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

Binary file not shown.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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