mirror of
https://github.com/yuanyuanxiang/SimpleRemoter.git
synced 2026-01-22 07:14:15 +08:00
Fix (Windows Service): Remove the shit dropped by AI
This commit is contained in:
@@ -124,39 +124,6 @@ CMy2015RemoteApp::CMy2015RemoteApp()
|
||||
|
||||
CMy2015RemoteApp theApp;
|
||||
|
||||
|
||||
// 从服务路径中提取可执行文件路径(去除引号和参数)
|
||||
static void ExtractExePathFromServicePath(const char* servicePath, char* exePath, size_t exePathSize)
|
||||
{
|
||||
if (!servicePath || !exePath || exePathSize == 0) {
|
||||
if (exePath && exePathSize > 0) exePath[0] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
const char* src = servicePath;
|
||||
char* dst = exePath;
|
||||
size_t remaining = exePathSize - 1;
|
||||
|
||||
// 跳过前导空格
|
||||
while (*src == ' ') src++;
|
||||
|
||||
if (*src == '"') {
|
||||
// 带引号的路径:提取引号内的内容
|
||||
src++; // 跳过开始引号
|
||||
while (*src && *src != '"' && remaining > 0) {
|
||||
*dst++ = *src++;
|
||||
remaining--;
|
||||
}
|
||||
} else {
|
||||
// 不带引号的路径:提取到空格或结束
|
||||
while (*src && *src != ' ' && remaining > 0) {
|
||||
*dst++ = *src++;
|
||||
remaining--;
|
||||
}
|
||||
}
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
// 处理服务相关的命令行参数
|
||||
// 返回值: TRUE 表示已处理服务命令(程序应退出),FALSE 表示继续正常启动
|
||||
static BOOL HandleServiceCommandLine()
|
||||
@@ -203,18 +170,18 @@ static BOOL HandleServiceCommandLine()
|
||||
char curPath[MAX_PATH];
|
||||
GetModuleFileNameA(NULL, curPath, MAX_PATH);
|
||||
|
||||
// 从服务路径中提取纯可执行文件路径(去除引号和参数)
|
||||
char serviceExePath[MAX_PATH] = { 0 };
|
||||
ExtractExePathFromServicePath(servicePath, serviceExePath, MAX_PATH);
|
||||
|
||||
if (registered && _stricmp(curPath, serviceExePath) != 0) {
|
||||
Mprintf("[HandleServiceCommandLine] ServerService Uninstall: %s\n", servicePath);
|
||||
ServerService_Uninstall();
|
||||
_strlwr(servicePath);
|
||||
_strlwr(curPath);
|
||||
BOOL same = (strstr(servicePath, curPath) != 0);
|
||||
if (registered && !same) {
|
||||
BOOL r = ServerService_Uninstall();
|
||||
Mprintf("[HandleServiceCommandLine] ServerService Uninstall %s: %s\n", r ? "succeed" : "failed", servicePath);
|
||||
registered = FALSE;
|
||||
}
|
||||
if (!registered) {
|
||||
Mprintf("[HandleServiceCommandLine] ServerService Install: %s\n", curPath);
|
||||
return ServerService_Install();
|
||||
BOOL r = ServerService_Install();
|
||||
Mprintf("[HandleServiceCommandLine] ServerService Install: %s\n", r ? "succeed" : "failed", curPath);
|
||||
return r;
|
||||
} else if (!running) {
|
||||
int r = ServerService_Run();
|
||||
Mprintf("[HandleServiceCommandLine] ServerService Run '%s' %s\n", curPath, r == ERROR_SUCCESS ? "succeed" : "failed");
|
||||
|
||||
@@ -13,45 +13,6 @@ static HANDLE g_StopEvent = INVALID_HANDLE_VALUE;
|
||||
// 前向声明
|
||||
static void WINAPI ServiceMain(DWORD argc, LPTSTR* argv);
|
||||
static void WINAPI ServiceCtrlHandler(DWORD ctrlCode);
|
||||
static void ServiceWriteLog(const char* message);
|
||||
|
||||
// 获取日志文件路径(程序所在目录)
|
||||
static void GetServiceLogPath(char* logPath, size_t size)
|
||||
{
|
||||
char exePath[MAX_PATH];
|
||||
if (GetModuleFileNameA(NULL, exePath, MAX_PATH)) {
|
||||
char* lastSlash = strrchr(exePath, '\\');
|
||||
if (lastSlash) {
|
||||
*lastSlash = '\0';
|
||||
sprintf_s(logPath, size, "%s\\YamaService.log", exePath);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 备用路径:Windows临时目录
|
||||
char tempPath[MAX_PATH];
|
||||
if (GetTempPathA(MAX_PATH, tempPath)) {
|
||||
sprintf_s(logPath, size, "%sYamaService.log", tempPath);
|
||||
} else {
|
||||
strncpy_s(logPath, size, "YamaService.log", _TRUNCATE);
|
||||
}
|
||||
}
|
||||
|
||||
// 日志函数
|
||||
static void ServiceWriteLog(const char* message)
|
||||
{
|
||||
char logPath[MAX_PATH];
|
||||
GetServiceLogPath(logPath, sizeof(logPath));
|
||||
FILE* f = fopen(logPath, "a");
|
||||
if (f) {
|
||||
SYSTEMTIME st;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL ServerService_CheckStatus(BOOL* registered, BOOL* running,
|
||||
char* exePath, size_t exePathSize)
|
||||
@@ -148,14 +109,14 @@ int ServerService_Run(void)
|
||||
ServiceTable[1].lpServiceName = NULL;
|
||||
ServiceTable[1].lpServiceProc = NULL;
|
||||
|
||||
ServiceWriteLog("========================================");
|
||||
ServiceWriteLog("ServerService_Run() called");
|
||||
Mprintf("========================================");
|
||||
Mprintf("ServerService_Run() called");
|
||||
|
||||
if (StartServiceCtrlDispatcher(ServiceTable) == FALSE) {
|
||||
DWORD err = GetLastError();
|
||||
char buffer[256];
|
||||
sprintf_s(buffer, sizeof(buffer), "StartServiceCtrlDispatcher failed: %d", (int)err);
|
||||
ServiceWriteLog(buffer);
|
||||
Mprintf(buffer);
|
||||
return (int)err;
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
@@ -226,7 +187,7 @@ static void WINAPI ServiceMain(DWORD argc, LPTSTR* argv)
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
ServiceWriteLog("ServiceMain() called");
|
||||
Mprintf("ServiceMain() called");
|
||||
|
||||
g_StatusHandle = RegisterServiceCtrlHandler(
|
||||
SERVER_SERVICE_NAME,
|
||||
@@ -234,7 +195,7 @@ static void WINAPI ServiceMain(DWORD argc, LPTSTR* argv)
|
||||
);
|
||||
|
||||
if (g_StatusHandle == NULL) {
|
||||
ServiceWriteLog("RegisterServiceCtrlHandler failed");
|
||||
Mprintf("RegisterServiceCtrlHandler failed");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -251,7 +212,7 @@ static void WINAPI ServiceMain(DWORD argc, LPTSTR* argv)
|
||||
|
||||
g_StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (g_StopEvent == NULL) {
|
||||
ServiceWriteLog("CreateEvent failed");
|
||||
Mprintf("CreateEvent failed");
|
||||
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
|
||||
g_ServiceStatus.dwWin32ExitCode = GetLastError();
|
||||
SetServiceStatus(g_StatusHandle, &g_ServiceStatus);
|
||||
@@ -264,7 +225,7 @@ static void WINAPI ServiceMain(DWORD argc, LPTSTR* argv)
|
||||
g_ServiceStatus.dwCheckPoint = 0;
|
||||
|
||||
SetServiceStatus(g_StatusHandle, &g_ServiceStatus);
|
||||
ServiceWriteLog("Service is now running");
|
||||
Mprintf("Service is now running");
|
||||
|
||||
HANDLE hThread = CreateThread(NULL, 0, ServerService_WorkerThread, NULL, 0, NULL);
|
||||
if (hThread) {
|
||||
@@ -280,14 +241,14 @@ static void WINAPI ServiceMain(DWORD argc, LPTSTR* argv)
|
||||
g_ServiceStatus.dwCheckPoint = 3;
|
||||
|
||||
SetServiceStatus(g_StatusHandle, &g_ServiceStatus);
|
||||
ServiceWriteLog("Service stopped");
|
||||
Mprintf("Service stopped");
|
||||
}
|
||||
|
||||
static void WINAPI ServiceCtrlHandler(DWORD ctrlCode)
|
||||
{
|
||||
switch (ctrlCode) {
|
||||
case SERVICE_CONTROL_STOP:
|
||||
ServiceWriteLog("SERVICE_CONTROL_STOP received");
|
||||
Mprintf("SERVICE_CONTROL_STOP received");
|
||||
|
||||
if (g_ServiceStatus.dwCurrentState != SERVICE_RUNNING)
|
||||
break;
|
||||
@@ -318,39 +279,39 @@ DWORD WINAPI ServerService_WorkerThread(LPVOID lpParam)
|
||||
int heartbeatCount = 0;
|
||||
char buf[128];
|
||||
|
||||
ServiceWriteLog("========================================");
|
||||
ServiceWriteLog("Worker thread started");
|
||||
ServiceWriteLog("Service will launch Yama GUI in user sessions");
|
||||
Mprintf("========================================");
|
||||
Mprintf("Worker thread started");
|
||||
Mprintf("Service will launch Yama GUI in user sessions");
|
||||
|
||||
// 初始化会话监控器
|
||||
ServerSessionMonitor monitor;
|
||||
ServerSessionMonitor_Init(&monitor);
|
||||
|
||||
if (!ServerSessionMonitor_Start(&monitor)) {
|
||||
ServiceWriteLog("ERROR: Failed to start session monitor");
|
||||
Mprintf("ERROR: Failed to start session monitor");
|
||||
ServerSessionMonitor_Cleanup(&monitor);
|
||||
return ERROR_SERVICE_SPECIFIC_ERROR;
|
||||
}
|
||||
|
||||
ServiceWriteLog("Session monitor started successfully");
|
||||
ServiceWriteLog("Yama GUI will be launched automatically in user sessions");
|
||||
Mprintf("Session monitor started successfully");
|
||||
Mprintf("Yama GUI will be launched automatically in user sessions");
|
||||
|
||||
// 主循环,只等待停止信号
|
||||
while (WaitForSingleObject(g_StopEvent, 10000) != WAIT_OBJECT_0) {
|
||||
heartbeatCount++;
|
||||
if (heartbeatCount % 6 == 0) { // 每60秒记录一次(10秒 * 6 = 60秒)
|
||||
sprintf_s(buf, sizeof(buf), "Service heartbeat - uptime: %d minutes", heartbeatCount / 6);
|
||||
ServiceWriteLog(buf);
|
||||
Mprintf(buf);
|
||||
}
|
||||
}
|
||||
|
||||
ServiceWriteLog("Stop signal received");
|
||||
ServiceWriteLog("Stopping session monitor...");
|
||||
Mprintf("Stop signal received");
|
||||
Mprintf("Stopping session monitor...");
|
||||
ServerSessionMonitor_Stop(&monitor);
|
||||
ServerSessionMonitor_Cleanup(&monitor);
|
||||
|
||||
ServiceWriteLog("Worker thread exiting");
|
||||
ServiceWriteLog("========================================");
|
||||
Mprintf("Worker thread exiting");
|
||||
Mprintf("========================================");
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ static BOOL LaunchGuiInSession(ServerSessionMonitor* self, DWORD sessionId);
|
||||
static BOOL IsGuiRunningInSession(ServerSessionMonitor* self, DWORD sessionId);
|
||||
static void TerminateAllGui(ServerSessionMonitor* self);
|
||||
static void CleanupDeadProcesses(ServerSessionMonitor* self);
|
||||
static void ServerMonitor_WriteLog(const char* message);
|
||||
|
||||
// 动态数组辅助函数
|
||||
static void AgentArray_Init(ServerAgentProcessArray* arr);
|
||||
@@ -77,46 +76,6 @@ static void AgentArray_RemoveAt(ServerAgentProcessArray* arr, size_t index)
|
||||
arr->count--;
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 日志函数
|
||||
// ============================================
|
||||
|
||||
// 获取日志文件路径(程序所在目录)
|
||||
static void GetMonitorLogPath(char* logPath, size_t size)
|
||||
{
|
||||
char exePath[MAX_PATH];
|
||||
if (GetModuleFileNameA(NULL, exePath, MAX_PATH)) {
|
||||
char* lastSlash = strrchr(exePath, '\\');
|
||||
if (lastSlash) {
|
||||
*lastSlash = '\0';
|
||||
sprintf_s(logPath, size, "%s\\YamaSessionMonitor.log", exePath);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 备用路径:Windows临时目录
|
||||
char tempPath[MAX_PATH];
|
||||
if (GetTempPathA(MAX_PATH, tempPath)) {
|
||||
sprintf_s(logPath, size, "%sYamaSessionMonitor.log", tempPath);
|
||||
} else {
|
||||
strncpy_s(logPath, size, "YamaSessionMonitor.log", _TRUNCATE);
|
||||
}
|
||||
}
|
||||
|
||||
static void ServerMonitor_WriteLog(const char* message)
|
||||
{
|
||||
char logPath[MAX_PATH];
|
||||
GetMonitorLogPath(logPath, sizeof(logPath));
|
||||
FILE* f = fopen(logPath, "a");
|
||||
if (f) {
|
||||
SYSTEMTIME st;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 公共接口实现
|
||||
// ============================================
|
||||
@@ -139,23 +98,23 @@ void ServerSessionMonitor_Cleanup(ServerSessionMonitor* self)
|
||||
BOOL ServerSessionMonitor_Start(ServerSessionMonitor* self)
|
||||
{
|
||||
if (self->running) {
|
||||
ServerMonitor_WriteLog("Monitor already running");
|
||||
Mprintf("Monitor already running");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
ServerMonitor_WriteLog("========================================");
|
||||
ServerMonitor_WriteLog("Starting server session monitor...");
|
||||
Mprintf("========================================");
|
||||
Mprintf("Starting server session monitor...");
|
||||
|
||||
self->running = TRUE;
|
||||
self->monitorThread = CreateThread(NULL, 0, MonitorThreadProc, self, 0, NULL);
|
||||
|
||||
if (!self->monitorThread) {
|
||||
ServerMonitor_WriteLog("ERROR: Failed to create monitor thread");
|
||||
Mprintf("ERROR: Failed to create monitor thread");
|
||||
self->running = FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ServerMonitor_WriteLog("Server session monitor thread created");
|
||||
Mprintf("Server session monitor thread created");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -165,14 +124,14 @@ void ServerSessionMonitor_Stop(ServerSessionMonitor* self)
|
||||
return;
|
||||
}
|
||||
|
||||
ServerMonitor_WriteLog("Stopping server session monitor...");
|
||||
Mprintf("Stopping server session monitor...");
|
||||
self->running = FALSE;
|
||||
|
||||
if (self->monitorThread) {
|
||||
DWORD waitResult = WaitForSingleObject(self->monitorThread, 10000);
|
||||
if (waitResult == WAIT_TIMEOUT) {
|
||||
// 线程未在规定时间内退出,强制终止
|
||||
ServerMonitor_WriteLog("WARNING: Monitor thread did not exit in time, terminating...");
|
||||
Mprintf("WARNING: Monitor thread did not exit in time, terminating...");
|
||||
TerminateThread(self->monitorThread, 1);
|
||||
}
|
||||
CloseHandle(self->monitorThread);
|
||||
@@ -180,11 +139,11 @@ void ServerSessionMonitor_Stop(ServerSessionMonitor* self)
|
||||
}
|
||||
|
||||
// 终止所有GUI进程
|
||||
ServerMonitor_WriteLog("Terminating all GUI processes...");
|
||||
Mprintf("Terminating all GUI processes...");
|
||||
// TerminateAllGui(self);
|
||||
|
||||
ServerMonitor_WriteLog("Server session monitor stopped");
|
||||
ServerMonitor_WriteLog("========================================");
|
||||
Mprintf("Server session monitor stopped");
|
||||
Mprintf("========================================");
|
||||
}
|
||||
|
||||
// ============================================
|
||||
@@ -203,7 +162,7 @@ static void MonitorLoop(ServerSessionMonitor* self)
|
||||
int loopCount = 0;
|
||||
char buf[256];
|
||||
|
||||
ServerMonitor_WriteLog("Monitor loop started");
|
||||
Mprintf("Monitor loop started");
|
||||
|
||||
while (self->running) {
|
||||
loopCount++;
|
||||
@@ -230,20 +189,20 @@ static void MonitorLoop(ServerSessionMonitor* self)
|
||||
sprintf_s(buf, sizeof(buf), "Active session found: ID=%d, Name=%s",
|
||||
(int)sessionId,
|
||||
pSessionInfo[i].pWinStationName);
|
||||
ServerMonitor_WriteLog(buf);
|
||||
Mprintf(buf);
|
||||
}
|
||||
|
||||
// 检查GUI是否在该会话中运行
|
||||
if (!IsGuiRunningInSession(self, sessionId)) {
|
||||
sprintf_s(buf, sizeof(buf), "GUI not running in session %d, launching...", (int)sessionId);
|
||||
ServerMonitor_WriteLog(buf);
|
||||
Mprintf(buf);
|
||||
|
||||
if (LaunchGuiInSession(self, sessionId)) {
|
||||
ServerMonitor_WriteLog("GUI launched successfully");
|
||||
Mprintf("GUI launched successfully");
|
||||
// 给程序一些时间启动
|
||||
Sleep(2000);
|
||||
} else {
|
||||
ServerMonitor_WriteLog("Failed to launch GUI");
|
||||
Mprintf("Failed to launch GUI");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,13 +212,13 @@ static void MonitorLoop(ServerSessionMonitor* self)
|
||||
}
|
||||
|
||||
if (!foundActiveSession && loopCount % 5 == 1) {
|
||||
ServerMonitor_WriteLog("No active sessions found");
|
||||
Mprintf("No active sessions found");
|
||||
}
|
||||
|
||||
WTSFreeMemory(pSessionInfo);
|
||||
} else {
|
||||
if (loopCount % 5 == 1) {
|
||||
ServerMonitor_WriteLog("WTSEnumerateSessions failed");
|
||||
Mprintf("WTSEnumerateSessions failed");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,7 +228,7 @@ static void MonitorLoop(ServerSessionMonitor* self)
|
||||
}
|
||||
}
|
||||
|
||||
ServerMonitor_WriteLog("Monitor loop exited");
|
||||
Mprintf("Monitor loop exited");
|
||||
}
|
||||
|
||||
static BOOL IsGuiRunningInSession(ServerSessionMonitor* self, DWORD sessionId)
|
||||
@@ -296,7 +255,7 @@ static BOOL IsGuiRunningInSession(ServerSessionMonitor* self, DWORD sessionId)
|
||||
// 创建进程快照
|
||||
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
if (hSnapshot == INVALID_HANDLE_VALUE) {
|
||||
ServerMonitor_WriteLog("CreateToolhelp32Snapshot failed");
|
||||
Mprintf("CreateToolhelp32Snapshot failed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -338,14 +297,14 @@ static void TerminateAllGui(ServerSessionMonitor* self)
|
||||
EnterCriticalSection(&self->csProcessList);
|
||||
|
||||
sprintf_s(buf, sizeof(buf), "Terminating %d GUI process(es)", (int)self->agentProcesses.count);
|
||||
ServerMonitor_WriteLog(buf);
|
||||
Mprintf(buf);
|
||||
|
||||
for (size_t i = 0; i < self->agentProcesses.count; i++) {
|
||||
ServerAgentProcessInfo* info = &self->agentProcesses.items[i];
|
||||
|
||||
sprintf_s(buf, sizeof(buf), "Terminating GUI PID=%d (Session %d)",
|
||||
(int)info->processId, (int)info->sessionId);
|
||||
ServerMonitor_WriteLog(buf);
|
||||
Mprintf(buf);
|
||||
|
||||
// 检查进程是否还活着
|
||||
DWORD exitCode;
|
||||
@@ -355,16 +314,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());
|
||||
ServerMonitor_WriteLog(buf);
|
||||
Mprintf(buf);
|
||||
} else {
|
||||
ServerMonitor_WriteLog("GUI terminated successfully");
|
||||
Mprintf("GUI terminated successfully");
|
||||
// 等待进程完全退出
|
||||
WaitForSingleObject(info->hProcess, 5000);
|
||||
}
|
||||
} else {
|
||||
sprintf_s(buf, sizeof(buf), "GUI PID=%d already exited with code %d",
|
||||
(int)info->processId, (int)exitCode);
|
||||
ServerMonitor_WriteLog(buf);
|
||||
Mprintf(buf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,7 +333,7 @@ static void TerminateAllGui(ServerSessionMonitor* self)
|
||||
self->agentProcesses.count = 0; // 清空列表
|
||||
|
||||
LeaveCriticalSection(&self->csProcessList);
|
||||
ServerMonitor_WriteLog("All GUI processes terminated");
|
||||
Mprintf("All GUI processes terminated");
|
||||
}
|
||||
|
||||
// 清理已经终止的进程
|
||||
@@ -394,7 +353,7 @@ static void CleanupDeadProcesses(ServerSessionMonitor* self)
|
||||
// 进程已退出
|
||||
sprintf_s(buf, sizeof(buf), "GUI PID=%d exited with code %d, cleaning up",
|
||||
(int)info->processId, (int)exitCode);
|
||||
ServerMonitor_WriteLog(buf);
|
||||
Mprintf(buf);
|
||||
|
||||
CloseHandle(info->hProcess);
|
||||
AgentArray_RemoveAt(&self->agentProcesses, i);
|
||||
@@ -404,7 +363,7 @@ static void CleanupDeadProcesses(ServerSessionMonitor* self)
|
||||
// 无法获取退出代码,可能进程已不存在
|
||||
sprintf_s(buf, sizeof(buf), "Cannot query GUI PID=%d, removing from list",
|
||||
(int)info->processId);
|
||||
ServerMonitor_WriteLog(buf);
|
||||
Mprintf(buf);
|
||||
|
||||
CloseHandle(info->hProcess);
|
||||
AgentArray_RemoveAt(&self->agentProcesses, i);
|
||||
@@ -422,7 +381,7 @@ static BOOL LaunchGuiInSession(ServerSessionMonitor* self, DWORD sessionId)
|
||||
char buf[512];
|
||||
|
||||
sprintf_s(buf, sizeof(buf), "Attempting to launch GUI in session %d", (int)sessionId);
|
||||
ServerMonitor_WriteLog(buf);
|
||||
Mprintf(buf);
|
||||
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
@@ -436,7 +395,7 @@ static BOOL LaunchGuiInSession(ServerSessionMonitor* self, DWORD sessionId)
|
||||
HANDLE hToken = NULL;
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &hToken)) {
|
||||
sprintf_s(buf, sizeof(buf), "OpenProcessToken failed: %d", (int)GetLastError());
|
||||
ServerMonitor_WriteLog(buf);
|
||||
Mprintf(buf);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -445,7 +404,7 @@ static BOOL LaunchGuiInSession(ServerSessionMonitor* self, DWORD sessionId)
|
||||
if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL,
|
||||
SecurityImpersonation, TokenPrimary, &hDupToken)) {
|
||||
sprintf_s(buf, sizeof(buf), "DuplicateTokenEx failed: %d", (int)GetLastError());
|
||||
ServerMonitor_WriteLog(buf);
|
||||
Mprintf(buf);
|
||||
CloseHandle(hToken);
|
||||
return FALSE;
|
||||
}
|
||||
@@ -453,31 +412,31 @@ static BOOL LaunchGuiInSession(ServerSessionMonitor* self, DWORD sessionId)
|
||||
// 修改令牌的会话 ID 为目标用户会话
|
||||
if (!SetTokenInformation(hDupToken, TokenSessionId, &sessionId, sizeof(sessionId))) {
|
||||
sprintf_s(buf, sizeof(buf), "SetTokenInformation failed: %d", (int)GetLastError());
|
||||
ServerMonitor_WriteLog(buf);
|
||||
Mprintf(buf);
|
||||
CloseHandle(hDupToken);
|
||||
CloseHandle(hToken);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ServerMonitor_WriteLog("Token duplicated");
|
||||
Mprintf("Token duplicated");
|
||||
|
||||
// 获取当前程序路径(就是自己)
|
||||
char exePath[MAX_PATH];
|
||||
if (!GetModuleFileNameA(NULL, exePath, MAX_PATH)) {
|
||||
ServerMonitor_WriteLog("GetModuleFileName failed");
|
||||
Mprintf("GetModuleFileName failed");
|
||||
CloseHandle(hDupToken);
|
||||
CloseHandle(hToken);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
sprintf_s(buf, sizeof(buf), "Service path: %s", exePath);
|
||||
ServerMonitor_WriteLog(buf);
|
||||
Mprintf(buf);
|
||||
|
||||
// 检查文件是否存在
|
||||
DWORD fileAttr = GetFileAttributesA(exePath);
|
||||
if (fileAttr == INVALID_FILE_ATTRIBUTES) {
|
||||
sprintf_s(buf, sizeof(buf), "ERROR: Executable not found at: %s", exePath);
|
||||
ServerMonitor_WriteLog(buf);
|
||||
Mprintf(buf);
|
||||
CloseHandle(hDupToken);
|
||||
CloseHandle(hToken);
|
||||
return FALSE;
|
||||
@@ -488,20 +447,20 @@ static BOOL LaunchGuiInSession(ServerSessionMonitor* self, DWORD sessionId)
|
||||
sprintf_s(cmdLine, sizeof(cmdLine), "\"%s\" -agent", exePath);
|
||||
|
||||
sprintf_s(buf, sizeof(buf), "Command line: %s", cmdLine);
|
||||
ServerMonitor_WriteLog(buf);
|
||||
Mprintf(buf);
|
||||
|
||||
// 获取用户令牌(用于获取环境块)
|
||||
LPVOID lpEnvironment = NULL;
|
||||
HANDLE hUserToken = NULL;
|
||||
if (!WTSQueryUserToken(sessionId, &hUserToken)) {
|
||||
sprintf_s(buf, sizeof(buf), "WTSQueryUserToken failed: %d", (int)GetLastError());
|
||||
ServerMonitor_WriteLog(buf);
|
||||
Mprintf(buf);
|
||||
}
|
||||
|
||||
// 使用用户令牌创建环境块
|
||||
if (hUserToken) {
|
||||
if (!CreateEnvironmentBlock(&lpEnvironment, hUserToken, FALSE)) {
|
||||
ServerMonitor_WriteLog("CreateEnvironmentBlock failed");
|
||||
Mprintf("CreateEnvironmentBlock failed");
|
||||
}
|
||||
CloseHandle(hUserToken);
|
||||
}
|
||||
@@ -527,7 +486,7 @@ static BOOL LaunchGuiInSession(ServerSessionMonitor* self, DWORD sessionId)
|
||||
|
||||
if (result) {
|
||||
sprintf_s(buf, sizeof(buf), "SUCCESS: GUI process created (PID=%d)", (int)pi.dwProcessId);
|
||||
ServerMonitor_WriteLog(buf);
|
||||
Mprintf(buf);
|
||||
|
||||
// 保存进程信息,以便停止时可以终止它
|
||||
EnterCriticalSection(&self->csProcessList);
|
||||
@@ -542,15 +501,15 @@ static BOOL LaunchGuiInSession(ServerSessionMonitor* self, DWORD sessionId)
|
||||
} else {
|
||||
DWORD err = GetLastError();
|
||||
sprintf_s(buf, sizeof(buf), "CreateProcessAsUser failed: %d", (int)err);
|
||||
ServerMonitor_WriteLog(buf);
|
||||
Mprintf(buf);
|
||||
|
||||
// 提供更详细的错误信息
|
||||
if (err == ERROR_FILE_NOT_FOUND) {
|
||||
ServerMonitor_WriteLog("ERROR: Executable not found");
|
||||
Mprintf("ERROR: Executable not found");
|
||||
} else if (err == ERROR_ACCESS_DENIED) {
|
||||
ServerMonitor_WriteLog("ERROR: Access denied - service may not have sufficient privileges");
|
||||
Mprintf("ERROR: Access denied - service may not have sufficient privileges");
|
||||
} else if (err == 1314) {
|
||||
ServerMonitor_WriteLog("ERROR: Service does not have SE_INCREASE_QUOTA privilege");
|
||||
Mprintf("ERROR: Service does not have SE_INCREASE_QUOTA privilege");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user