//启动应用程序,path:程序的路径,带exe的,dir:程序的工作路径 BOOL LaunchApplication(LPTSTR path, LPTSTR dir) { char buf[128] = { 0 }; BOOL bRet = FALSE; HANDLE hUserTokenDup = NULL; LPVOID pEnv = NULL; do { DWORD dwSessionId = 0; if (0xFFFFFFFF == (dwSessionId = WTSGetActiveConsoleSessionId())) { Logger::getInstance()->info(__FILE__, __LINE__, "WTSGetActiveConsoleSessionId fail"); break; } #define DEFAULT_WINLOGON_APPLICATION (TEXT("winlogon.exe")) #define DEFAULT_DEFAULT_APPLICATION (TEXT("explorer.exe")) // 需要以explorer.exe进程的Token来创建Env环境块,否则以服务启动的App在打开文件路径的方面可能会遇到一些问题,比如最常见的是会访问C:WindowsSystem32configsystemprofile导致访问了错误的位置。 DWORD dwWinlogonPid = 0; if (0xFFFFFFFF == (dwWinlogonPid = GetProcessID(DEFAULT_WINLOGON_APPLICATION, dwSessionId))) { Logger::getInstance()->info(__FILE__, __LINE__, "Get Process ID Failed!"); break; } if (NULL == (hUserTokenDup = GetProcessTokenDup(dwWinlogonPid))) { Logger::getInstance()->info(__FILE__, __LINE__, "Get Process Duplicate Token Failed!"); break; } if (!AdjustProcessTokenDup(hUserTokenDup, dwSessionId)) { Logger::getInstance()->info(__FILE__, __LINE__, "Adjust Process Token Failed!"); break; } sprintf_s(buf, "dwSessionId=%d", dwSessionId); Logger::getInstance()->info(__FILE__, __LINE__, "Adjust Process Token Failed!"); //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(' '); StringCbCat(szExecute, _countof(szExecute) - _tcslen(szExecute), lpszExecute);*/ /*TCHAR szCmdLine[MAX_PATH] = { 0 }; if (NULL != lpszCmdLine) { StringCchPrintf(szCmdLine, _countof(szCmdLine), TEXT("%s"), lpszCmdLine); }*/ PROCESS_INFORMATION pi = { 0 }; SECURITY_ATTRIBUTES sa = {0}; sa.nLength = sizeof(SECURITY_ATTRIBUTES); STARTUPINFO si = { sizeof(STARTUPINFO) }; si.lpDesktop = TEXT("winsta0\default"); si.wShowWindow = SW_SHOW; si.dwFlags = STARTF_USESHOWWINDOW; si.cb = sizeof(STARTUPINFO); BOOL ret = CreateProcessAsUser(hUserTokenDup, path, NULL, &sa, &sa, FALSE, NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT, NULL, dir, &si, &pi); if (!ret) { sprintf_s(buf, "ret=%d,nError=%d", ret, GetLastError()); Logger::getInstance()->info(__FILE__, __LINE__, buf); break; } char buf[128] = { 0 }; sprintf_s(buf, "CreateProcessAsUser :ret=%d,nError=%d", ret, GetLastError()); Logger::getInstance()->info(__FILE__, __LINE__, buf); 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) { Logger::getInstance()->info(__FILE__, __LINE__, "CreateToolhelp32Snapshot error"); break; } PROCESSENTRY32 pe32 = { sizeof(PROCESSENTRY32) }; if (!Process32First(hSnapshot, &pe32)) { Logger::getInstance()->info(__FILE__, __LINE__, "Process32First error"); 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))) { Logger::getInstance()->info(__FILE__, __LINE__, "OpenProcess");//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)) { Logger::getInstance()->info(__FILE__, __LINE__, "OpenProcessToken"); break; } if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hTokenDup)) { Logger::getInstance()->info(__FILE__, __LINE__, "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))) { Logger::getInstance()->info(__FILE__, __LINE__, "SetTokenInformation"); break; } if (!AdjustTokenDupPrivileges(hTokenDup, SE_DEBUG_NAME)) { Logger::getInstance()->info(__FILE__, __LINE__, "Enable SE_DEBUG_NAME Privilege Failed!"); } if (!AdjustTokenDupPrivileges(hTokenDup, SE_TCB_NAME)) { Logger::getInstance()->info(__FILE__, __LINE__, "Enable SE_TCB_NAME Privilege Failed!");} if (!AdjustTokenDupPrivileges(hTokenDup, SE_CHANGE_NOTIFY_NAME)) { Logger::getInstance()->info(__FILE__, __LINE__, "Enable SE_CHANGE_NOTIFY_NAME Privilege Failed!");} if (!AdjustTokenDupPrivileges(hTokenDup, SE_INCREASE_QUOTA_NAME)) { Logger::getInstance()->info(__FILE__, __LINE__, "Enable SE_INCREASE_QUOTA_NAME Privilege Failed!"); } if (!AdjustTokenDupPrivileges(hTokenDup, SE_ASSIGNPRIMARYTOKEN_NAME)) { Logger::getInstance()->info(__FILE__, __LINE__, "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)) { Logger::getInstance()->info(__FILE__, __LINE__, "LookupPrivilegeValue");//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)) { Logger::getInstance()->info(__FILE__, __LINE__, "AdjustTokenPrivileges");//PRINT(ERR, GetLastError(), TEXT("AdjustTokenPrivileges")); break; } // Completed bRet = TRUE; } while (FALSE); return bRet; }