diff --git a/client/IOCPClient.cpp b/client/IOCPClient.cpp index d0ced76..c008dc1 100644 --- a/client/IOCPClient.cpp +++ b/client/IOCPClient.cpp @@ -593,35 +593,45 @@ BOOL IOCPClient::SendWithSplit(const char* src, ULONG srcSize, ULONG ulSplitLeng // 依次发送 for (i = ulLength; i >= (int)actualSplitLength; i -= actualSplitLength) { - int j = 0; - for (; j < ulSendRetry; ++j) { - iReturn = SendTo(Travel, actualSplitLength, 0); - if (iReturn > 0) { + int remaining = actualSplitLength; + while (remaining > 0) { + int j = 0; + for (; j < ulSendRetry; ++j) { + iReturn = SendTo(Travel, remaining, 0); + if (iReturn > 0) { + break; + } + } + if (j == ulSendRetry) { + isFail = true; break; } - } - if (j == ulSendRetry) { - isFail = true; - break; - } - ulSended += iReturn; - Travel += actualSplitLength; + ulSended += iReturn; + Travel += iReturn; + remaining -= iReturn; + } + if (isFail) break; } // 发送最后的部分 if (!isFail && i>0) { //1024 - int j = 0; - for (; j < ulSendRetry; j++) { - iReturn = SendTo((char*)Travel,i,0); - - if (iReturn > 0) { + int remaining = i; + while (remaining > 0) { + int j = 0; + for (; j < ulSendRetry; j++) { + iReturn = SendTo((char*)Travel, remaining, 0); + if (iReturn > 0) { + break; + } + } + if (j == ulSendRetry) { + isFail = true; break; } + ulSended += iReturn; + Travel += iReturn; + remaining -= iReturn; } - if (j == ulSendRetry) { - isFail = true; - } - ulSended += iReturn; } if (szBuffer != src) SAFE_DELETE_ARRAY(szBuffer); diff --git a/client/ScreenManager.cpp b/client/ScreenManager.cpp index e9cb1a5..a2857b9 100644 --- a/client/ScreenManager.cpp +++ b/client/ScreenManager.cpp @@ -418,13 +418,13 @@ void RunFileReceiver(CScreenManager *mgr, const std::string &folder, const std:: if (pClient->ConnectServer(mgr->m_ClientObject->ServerIP().c_str(), mgr->m_ClientObject->ServerPort())) { pClient->setManagerCallBack(mgr, CManager::DataProcess, CManager::ReconnectProcess); // 发送目录并准备接收文件 - int len = 1 + folder.length() + files.length() + 2; + int len = 1 + folder.length() + files.length() + 1; char* cmd = new char[len]; cmd[0] = COMMAND_GET_FILE; memcpy(cmd + 1, folder.c_str(), folder.length()); cmd[1 + folder.length()] = 0; memcpy(cmd + 1 + folder.length() + 1, files.data(), files.length()); - cmd[1 + folder.length() + files.length() + 1] = 0; + cmd[1 + folder.length() + files.length()] = 0; pClient->Send2Server(cmd, len); SAFE_DELETE_ARRAY(cmd); pClient->RunEventLoop(TRUE); diff --git a/common/file_upload.h b/common/file_upload.h index f15ead1..27f3040 100644 --- a/common/file_upload.h +++ b/common/file_upload.h @@ -35,3 +35,7 @@ int FileBatchTransferWorker(const std::vector& files, const std::st int RecvFileChunk(char* buf, size_t len, void* user, OnFinish f, const std::string& hash, const std::string& hmac); uint8_t* ScaleBitmap(uint8_t* dst, const uint8_t* src, int srcW, int srcH, int dstW, int dstH); + +std::vector PreprocessFilesSimple(const std::vector& inputFiles); + +std::vector BuildMultiStringPath(const std::vector& paths); diff --git a/common/logger.h b/common/logger.h index dc2851e..769df8b 100644 --- a/common/logger.h +++ b/common/logger.h @@ -103,9 +103,11 @@ public: writeToFile(logEntry); } } -#ifndef _WINDOWS #ifdef _DEBUG +#ifndef _WINDOWS printf("%s", logEntry.c_str()); +#else + OutputDebugStringA(logEntry.c_str()); #endif #endif cv.notify_one(); // 通知写线程 @@ -260,8 +262,6 @@ inline const char* getFileName(const char* path) #define Mprintf(format, ...) Logger::getInstance().log(getFileName(skCrypt(__FILE__)), __LINE__, skCrypt(format), __VA_ARGS__) #endif -#endif // _WIN32 - inline void Log(const char* message) { return Logger::getInstance().log(NULL, 0, "%s", message); @@ -276,3 +276,5 @@ inline void Logf(const char* file, int line, const char* format, ...) va_end(args); return Logger::getInstance().log(getFileName(file), line, "%s", message); } + +#endif // _WIN32 diff --git a/server/2015Remote/2015RemoteDlg.cpp b/server/2015Remote/2015RemoteDlg.cpp index 6fa0ea8..a402c10 100644 --- a/server/2015Remote/2015RemoteDlg.cpp +++ b/server/2015Remote/2015RemoteDlg.cpp @@ -2424,16 +2424,19 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject) // 发送文件 std::string dir = (char*)(szBuffer + 1); char* ptr = (char*)szBuffer + 1 + dir.length() + 1; - auto specified = *ptr ? ParseMultiStringPath(ptr, len - 2 - dir.length()) : std::vector{}; - int result = 0; - auto files = specified.empty() ? GetClipboardFiles(result): specified; + auto md5 = CalcMD5FromBytes((BYTE*)ptr, len - 2 - dir.length()); + if (!m_CmdList.PopCmd(md5)) { + Mprintf("【警告】文件传输指令非法或已过期: %s\n", md5.c_str()); + ContextObject->CancelIO(); + break; + } + auto files = *ptr ? ParseMultiStringPath(ptr, len - 2 - dir.length()) : std::vector{}; if (!files.empty()) { std::string hash = GetPwdHash(), hmac = GetHMAC(100); std::thread(FileBatchTransferWorker, files, dir, ContextObject, SendData, FinishSend, hash, hmac).detach(); } else { ContextObject->CancelIO(); - Mprintf("GetClipboardFiles failed: %d\n", result); } break; } @@ -4332,12 +4335,17 @@ LRESULT CALLBACK CMy2015RemoteDlg::LowLevelKeyboardProc(int nCode, WPARAM wParam auto files = GetClipboardFiles(result); if (!files.empty()) { // 获取远程目录 - BYTE szBuffer[100] = { COMMAND_GET_FOLDER }; + auto str = BuildMultiStringPath(files); + BYTE* szBuffer = new BYTE[81 + str.size()]; + szBuffer[0] = { COMMAND_GET_FOLDER }; std::string masterId = GetPwdHash(), hmac = GetHMAC(100); memcpy((char*)szBuffer + 1, masterId.c_str(), masterId.length()); memcpy((char*)szBuffer + 1 + masterId.length(), hmac.c_str(), hmac.length()); - dlg->m_ContextObject->Send2Client(szBuffer, sizeof(szBuffer)); - Mprintf("【Ctrl+V】 从本地拷贝文件到远程 \n"); + memcpy(szBuffer + 1 + 80, str.data(), str.size()); + auto md5 = CalcMD5FromBytes((BYTE*)str.data(), str.size()); + g_2015RemoteDlg->m_CmdList.PutCmd(md5); + dlg->m_ContextObject->Send2Client(szBuffer, 81 + str.size()); + Mprintf("【Ctrl+V】 从本地拷贝文件到远程: %s \n", md5.c_str()); } else { CString strText = GetClipboardText(); if (!strText.IsEmpty()) { diff --git a/server/2015Remote/2015RemoteDlg.h b/server/2015Remote/2015RemoteDlg.h index 117e6af..7a34373 100644 --- a/server/2015Remote/2015RemoteDlg.h +++ b/server/2015Remote/2015RemoteDlg.h @@ -6,6 +6,7 @@ #include "TrueColorToolBar.h" #include "IOCPServer.h" #include +#include ////////////////////////////////////////////////////////////////////////// // 以下为特殊需求使用 @@ -14,7 +15,7 @@ #define CLIENT_EXIT_WITH_SERVER 0 // 是否使用同步事件处理消息 -#define USING_EVENT 0 +#define USING_EVENT 1 typedef struct DllInfo { std::string Name; @@ -25,6 +26,23 @@ typedef struct DllInfo { } } DllInfo; +typedef struct FileTransformCmd { + CLock Lock; + std::map CmdTime; + void PutCmd(const std::string& str) { + Lock.Lock(); + CmdTime[str] = time(0); + Lock.Unlock(); + } + bool PopCmd(const std::string& str, int timeoutSec = 10) { + Lock.Lock(); + bool valid = CmdTime.find(str) != CmdTime.end() && time(0) - CmdTime[str] < timeoutSec; + CmdTime.erase(str); + Lock.Unlock(); + return valid; + } +} FileTransformCmd; + #define ID_DYNAMIC_MENU_BASE 36500 ////////////////////////////////////////////////////////////////////////// @@ -254,6 +272,7 @@ public: CBitmap m_bmOnline[20]; uint64_t m_superID; std::map m_RemoteWnds; + FileTransformCmd m_CmdList; CDialogBase* GetRemoteWindow(HWND hWnd); CDialogBase* GetRemoteWindow(CDialogBase* dlg); void RemoveRemoteWindow(HWND wnd); diff --git a/server/2015Remote/Buffer.h b/server/2015Remote/Buffer.h index 4ad0589..81c3ce4 100644 --- a/server/2015Remote/Buffer.h +++ b/server/2015Remote/Buffer.h @@ -73,6 +73,22 @@ public: { return md5; } + BYTE GetBYTE(int idx=0) const { + return idx >= len ? 0 : buf[idx]; + } + LPBYTE GetBuffer(int idx=0) const { + return idx >= len ? 0 : buf + idx; + } + int GetBufferLength() const { + return len; + } + BOOL CopyBuffer(PVOID pDst, ULONG nLen, ULONG ulPos=0) { + if (len - ulPos < nLen) { + return FALSE; + } + memcpy(pDst, buf + ulPos, nLen); + return TRUE; + } }; class CBuffer @@ -98,7 +114,7 @@ public: return WriteBuffer(buf.GetBuffer(), buf.GetBufferLen()); } LPBYTE GetBuffer(ULONG ulPos=0); - Buffer GetMyBuffer(ULONG ulPos); + Buffer GetMyBuffer(ULONG ulPos=0); BYTE GetBYTE(ULONG ulPos); BOOL CopyBuffer(PVOID pDst, ULONG nLen, ULONG ulPos); ULONG RemoveCompletedBuffer(ULONG ulLength); diff --git a/server/2015Remote/ScreenSpyDlg.cpp b/server/2015Remote/ScreenSpyDlg.cpp index ed8a40b..b7dc3bc 100644 --- a/server/2015Remote/ScreenSpyDlg.cpp +++ b/server/2015Remote/ScreenSpyDlg.cpp @@ -10,6 +10,7 @@ #include "CGridDialog.h" #include "2015RemoteDlg.h" #include +#include // CScreenSpyDlg 对话框 @@ -63,9 +64,10 @@ extern "C" char* __imp_strtok(char* str, const char* delim) return strtok(str, delim); } -CScreenSpyDlg::CScreenSpyDlg(CWnd* Parent, Server* IOCPServer, CONTEXT_OBJECT* ContextObject) +CScreenSpyDlg::CScreenSpyDlg(CMy2015RemoteDlg* Parent, Server* IOCPServer, CONTEXT_OBJECT* ContextObject) : DialogBase(CScreenSpyDlg::IDD, Parent, IOCPServer, ContextObject, 0) { + m_pParent = Parent; m_hFullDC = NULL; m_hFullMemDC = NULL; m_BitmapHandle = NULL; @@ -1134,7 +1136,6 @@ void CScreenSpyDlg::OnDropFiles(HDROP hDropInfo) } std::string GetPwdHash(); std::string GetHMAC(int offset); - std::vector PreprocessFilesSimple(const std::vector&inputFiles); auto files = PreprocessFilesSimple(list); auto str = BuildMultiStringPath(files); BYTE* szBuffer = new BYTE[1 + 80 + str.size()]; @@ -1143,8 +1144,10 @@ void CScreenSpyDlg::OnDropFiles(HDROP hDropInfo) memcpy((char*)szBuffer + 1, masterId.c_str(), masterId.length()); memcpy((char*)szBuffer + 1 + masterId.length(), hmac.c_str(), hmac.length()); memcpy(szBuffer + 1 + 80, str.data(), str.size()); + auto md5 = CalcMD5FromBytes((BYTE*)str.data(), str.size()); + m_pParent->m_CmdList.PutCmd(md5); m_ContextObject->Send2Client(szBuffer, 81 + str.size()); - Mprintf("【Ctrl+V】 从本地拖拽文件到远程 \n"); + Mprintf("【Ctrl+V】 从本地拖拽文件到远程: %s \n", md5.c_str()); SAFE_DELETE_ARRAY(szBuffer); } diff --git a/server/2015Remote/ScreenSpyDlg.h b/server/2015Remote/ScreenSpyDlg.h index e3c249e..1614319 100644 --- a/server/2015Remote/ScreenSpyDlg.h +++ b/server/2015Remote/ScreenSpyDlg.h @@ -3,6 +3,7 @@ #include "..\..\client\CursorInfo.h" #include "VideoDlg.h" #include "ToolbarDlg.h" +#include "2015RemoteDlg.h" extern "C" { @@ -44,9 +45,10 @@ class CScreenSpyDlg : public DialogBase { DECLARE_DYNAMIC(CScreenSpyDlg) CToolbarDlg* m_pToolbar = nullptr; + CMy2015RemoteDlg* m_pParent = nullptr; public: - CScreenSpyDlg(CWnd* Parent, Server* IOCPServer=NULL, CONTEXT_OBJECT *ContextObject=NULL); + CScreenSpyDlg(CMy2015RemoteDlg* Parent, Server* IOCPServer=NULL, CONTEXT_OBJECT *ContextObject=NULL); virtual ~CScreenSpyDlg(); virtual BOOL ShouldReconnect() { diff --git a/server/2015Remote/Server.h b/server/2015Remote/Server.h index 79d9f24..4460877 100644 --- a/server/2015Remote/Server.h +++ b/server/2015Remote/Server.h @@ -70,6 +70,7 @@ class HeaderParser protected: HeaderParser() { + m_bShouldUnmask = -1; m_Masker = nullptr; m_Encoder = nullptr; m_Encoder2 = nullptr; @@ -104,13 +105,17 @@ protected: // UnMask char* src = (char*)buf.GetBuffer(); ULONG srcSize = buf.GetBufferLength(); - PkgMaskType maskType = MaskTypeUnknown; - ULONG ret = TryUnMask(src, srcSize, maskType); + PkgMaskType maskType = m_bShouldUnmask ? MaskTypeUnknown : MaskTypeNone; + ULONG ret = m_bShouldUnmask ? TryUnMask(src, srcSize, maskType) : 0; std::string str = buf.Skip(ret); if (maskType == MaskTypeHTTP) { + m_bShouldUnmask = TRUE; std::string clientIP = getXForwardedFor(str); if (!clientIP.empty()) peer = clientIP; } + else { + m_bShouldUnmask = FALSE; + } if (nullptr == m_Masker) { m_Masker = maskType ? new HttpMask(peer) : new PkgMask(); } @@ -200,6 +205,7 @@ protected: } HeaderParser& Reset() { + m_bShouldUnmask = -1; if (m_Masker) { m_Masker->Destroy(); m_Masker = nullptr; @@ -250,6 +256,7 @@ private: Encoder* m_Encoder; // 编码器 Encoder* m_Encoder2; // 编码器2 PkgMask* m_Masker; + int m_bShouldUnmask; }; enum IOType {