// 创建交互式服务安装完成以后,启动UI的程序 BOOL LaunchApplication(LPCTSTR lpszExecute, LPCTSTR lpszCmdLine) { BOOL bRet = FALSE; HANDLE hUserTokenDup = NULL; LPVOID pEnv = NULL; do { DWORD dwSessionId = 0; if (0xFFFFFFFF == (dwSessionId = WTSGetActiveConsoleSessionId())) { PRINT(ERR, GetLastError(), TEXT("WTSGetActiveConsoleSessionId")); break; } #define DEFAULT_WINLOGON_APPLICATION (TEXT("winlogon.exe")) #define DEFAULT_DEFAULT_APPLICATION (TEXT("explorer.exe")) // 需要以explorer.exe进程的Token来创建Env环境块,否则以服务启动的App在打开文件路径的方面可能会遇到一些问题,比如最常见的是会访问C:\Windows\System32\config\systemprofile导致访问了错误的位置。 DWORD dwWinlogonPid = 0; if (0xFFFFFFFF == (dwWinlogonPid = GetProcessID(DEFAULT_WINLOGON_APPLICATION, dwSessionId))) { PRINT(ERR, TEXT("Get Process ID Failed!")); break; } if (NULL == (hUserTokenDup = GetProcessTokenDup(dwWinlogonPid))) { PRINT(ERR, TEXT("Get Process Duplicate Token Failed!")); break; } if (!AdjustProcessTokenDup(hUserTokenDup, dwSessionId)) { PRINT(ERR, TEXT("Adjust Process Token Failed!")); break; } HANDLE hDefaultTokenDup2 = NULL; DWORD dwDefaultPid = 0; if (0xFFFFFFFF == (dwDefaultPid = GetProcessID(DEFAULT_DEFAULT_APPLICATION, dwSessionId))) { PRINT(ERR, TEXT("Get Process ID Failed!")); break; } if (NULL == (hDefaultTokenDup2 = GetProcessTokenDup(dwDefaultPid))) { PRINT(ERR, TEXT("Get Process Duplicate Token Failed!")); break; } // Create Environment Block DWORD dwCreateFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE; if (CreateEnvironmentBlock(&pEnv, hDefaultTokenDup2, TRUE)) { dwCreateFlags |= CREATE_UNICODE_ENVIRONMENT; } // Launch Process In The Client's Logon Session TCHAR szExecute[MAX_PATH] = { 0 }; GetModuleFileName(NULL, szExecute, _countof(szExecute)); _tcsrchr(szExecute, TEXT('\\'))[1] = TEXT('\0'); StringCbCat(szExecute, _countof(szExecute) - _tcslen(szExecute), lpszExecute); TCHAR szCmdLine[MAX_PATH] = { 0 }; if (NULL != lpszCmdLine) { StringCchPrintf(szCmdLine, _countof(szCmdLine), TEXT("%s"), lpszCmdLine); } #define DEFAULT_DESKTOP_WINSTA0 (TEXT("winsta0\\default")) PROCESS_INFORMATION pi = { 0 }; STARTUPINFO si = { sizeof(STARTUPINFO) }; si.lpDesktop = DEFAULT_DESKTOP_WINSTA0; if (!CreateProcessAsUser(hUserTokenDup, szExecute, szCmdLine, NULL, NULL, FALSE, dwCreateFlags, pEnv, NULL, &si, &pi)) { PRINT(ERR, GetLastError(), TEXT("CreateProcessAsUser")); break; } CloseHandle(pi.hThread); CloseHandle(pi.hProcess); // Completed bRet = TRUE; } while (FALSE); if (NULL != pEnv) { DestroyEnvironmentBlock(pEnv); pEnv = NULL; } if (NULL != hUserTokenDup) { CloseHandle(hUserTokenDup); hUserTokenDup = NULL; } return bRet; } DWORD GetProcessID(LPCTSTR lpszProcessName, DWORD dwSessionId) { DWORD dwProcessId = 0xFFFFFFFF; HANDLE hSnapshot = INVALID_HANDLE_VALUE; do { _ASSERT(NULL != lpszProcessName); if (NULL == lpszProcessName) { break; } hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (INVALID_HANDLE_VALUE == hSnapshot) { PRINT(ERR, GetLastError(), TEXT("CreateToolhelp32Snapshot")); break; } PROCESSENTRY32 pe32 = { sizeof(PROCESSENTRY32) }; if (!Process32First(hSnapshot, &pe32)) { PRINT(ERR, GetLastError(), TEXT("Process32First")); break; } do { if (0 == _tcsicmp(pe32.szExeFile, lpszProcessName)) { DWORD dwProcessSessionId = 0; if (ProcessIdToSessionId(pe32.th32ProcessID, &dwProcessSessionId) && (dwSessionId == dwProcessSessionId)) { dwProcessId = pe32.th32ProcessID; break; } } } while (Process32Next(hSnapshot, &pe32)); // Completed } while (FALSE); if (INVALID_HANDLE_VALUE != hSnapshot) { CloseHandle(hSnapshot); hSnapshot = INVALID_HANDLE_VALUE; } return dwProcessId; } HANDLE GetProcessTokenDup(DWORD dwProcessId) { HANDLE hProcess = NULL; HANDLE hToken = NULL; HANDLE hTokenDup = NULL; do { if (NULL == (hProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, dwProcessId))) { PRINT(ERR, GetLastError(), TEXT("OpenProcess")); break; } if (!OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID | TOKEN_READ | TOKEN_WRITE, &hToken)) { PRINT(ERR, GetLastError(), TEXT("OpenProcessToken")); break; } if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hTokenDup)) { PRINT(ERR, GetLastError(), TEXT("DuplicateTokenEx")); break; } // Completed } while (FALSE); if (NULL != hToken) { CloseHandle(hToken); hToken = NULL; } if (NULL != hProcess) { CloseHandle(hProcess); hProcess = NULL; } return hTokenDup; } BOOL AdjustProcessTokenDup(HANDLE hTokenDup, DWORD dwSessionId) { BOOL bRet = FALSE; do { if (NULL == hTokenDup) { break; } // Adjust Token Privileges if(!SetTokenInformation(hTokenDup, TokenSessionId, (LPVOID)&dwSessionId, sizeof(dwSessionId))) { PRINT(ERR, GetLastError(), TEXT("SetTokenInformation")); break; } if (!AdjustTokenDupPrivileges(hTokenDup, SE_DEBUG_NAME)) { PRINT(ERR, TEXT("Enable SE_DEBUG_NAME Privilege Failed!")); } if (!AdjustTokenDupPrivileges(hTokenDup, SE_TCB_NAME)) { PRINT(ERR, TEXT("Enable SE_TCB_NAME Privilege Failed!")); } if (!AdjustTokenDupPrivileges(hTokenDup, SE_CHANGE_NOTIFY_NAME)) { PRINT(ERR, TEXT("Enable SE_CHANGE_NOTIFY_NAME Privilege Failed!")); } if (!AdjustTokenDupPrivileges(hTokenDup, SE_INCREASE_QUOTA_NAME)) { PRINT(ERR, TEXT("Enable SE_INCREASE_QUOTA_NAME Privilege Failed!")); } if (!AdjustTokenDupPrivileges(hTokenDup, SE_ASSIGNPRIMARYTOKEN_NAME)) { PRINT(ERR, TEXT("Enable SE_ASSIGNPRIMARYTOKEN_NAME Privilege Failed!")); } // Completed bRet = TRUE; } while (FALSE); return bRet; } BOOL AdjustTokenDupPrivileges(HANDLE hTokenDup, LPCTSTR lpszPrivileges) { BOOL bRet = FALSE; do { LUID luid = { 0 }; if (!LookupPrivilegeValue(NULL, lpszPrivileges, &luid)) { PRINT(ERR, GetLastError(), TEXT("LookupPrivilegeValue")); break; } TOKEN_PRIVILEGES tp = { 0 }; tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // Adjust token privileges if (!AdjustTokenPrivileges(hTokenDup, FALSE, &tp, sizeof(tp), NULL, NULL)) { PRINT(ERR, GetLastError(), TEXT("AdjustTokenPrivileges")); break; } // Completed bRet = TRUE; } while (FALSE); return bRet; } void PRINT(DWORD dwLevel, LPCTSTR lpszFormat, ...) { do { if (!m_bDbgValid) { break; } TCHAR szText[DEFAULT_PRINTF_BUFFER_LENGTH] = { 0 }; TCHAR szBuffer[DEFAULT_PRINTF_BUFFER_LENGTH] = { 0 }; // Parse Parameter va_list args; va_start(args, lpszFormat); StringCchVPrintf(szBuffer, _countof(szBuffer), lpszFormat, args); va_end(args); // Format FORMAT(szText, _countof(szText), szBuffer); // Dump DUMP(dwLevel, szText); } while (FALSE); } void PRINT(DWORD dwLevel, DWORD dwErrorId, LPCTSTR lpszDescription) { do { if (!m_bDbgValid) { break; } TCHAR szText[DEFAULT_PRINTF_BUFFER_LENGTH] = { 0 }; // Format FORMAT(szText, _countof(szText), dwErrorId, lpszDescription); // Dump DUMP(dwLevel, szText); } while (FALSE); } void CCommon::FORMAT(LPTSTR lpszText, size_t nLength, LPCTSTR lpszInfo) { _ASSERT(NULL != lpszText); _ASSERT(nLength > 0); _ASSERT(NULL != lpszInfo); SYSTEMTIME st = { 0 }; GetLocalTime(&st); StringCchPrintf(lpszText, nLength, TEXT("[%04d-%02d-%02d %02d:%02d:%02d.%03d] - %s\r\n"), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, lpszInfo); } void FORMAT(LPTSTR lpszText, size_t nLength, DWORD dwErrorId, LPCTSTR lpszDescription) { _ASSERT(NULL != lpszText); _ASSERT(nLength > 0); _ASSERT(NULL != lpszDescription); SYSTEMTIME st = { 0 }; GetLocalTime(&st); TCHAR szBuffer[DEFAULT_PRINTF_BUFFER_LENGTH] = { 0 }; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErrorId, LANG_NEUTRAL, (LPTSTR)szBuffer, _countof(szBuffer), NULL); StringCchPrintf(lpszText, nLength, TEXT("[%04d-%02d-%02d %02d:%02d:%02d.%03d] - Call %s() Failed with Error: %d - %s\r\n"), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, lpszDescription, dwErrorId, szBuffer); }
登录系统以后,在Windows服务进程中启动需管理员权限(带盾牌图标)的应用程序
猜你喜欢
转载自blog.csdn.net/visualeleven/article/details/80247383
今日推荐
周排行