Tech/Cording
[C++] Vista 이상에서 Service에서 활성화된 세션 ID로 특정 어플리케이션 실행하기
niu
2013. 11. 25. 03:26
BOOL CManager::Load_WTS_Process( UINT nId ) { DWORD dwSessionID; DWORD dwWinlogonPID; HANDLE hToken, hTokenDup, hWinlogon; TOKEN_PRIVILEGES token_priv; LUID luid; BOOL bSuc; dwSessionID = nId; hToken = NULL; hTokenDup = NULL; hWinlogon = NULL; try { dwWinlogonPID = IsProcess_running((const PTCHAR)Winlogon, _tcslen(Winlogon)); bSuc = WTSQueryUserToken( nId, &hToken ); if(!bSuc) { bSuc = WTSQueryUserToken( WTSGetActiveConsoleSessionId(), &hToken ); if(!bSuc) { WriteLog( _T("CManager::Load_WTS_Process -- WTSQueryUserToken Fail \n") ); throw ERROR_LOAD_WINSTA_DEF_PROC; } } hWinlogon = ::OpenProcess(MAXIMUM_ALLOWED, FALSE, dwWinlogonPID); if(!hWinlogon) { WriteLog( _T("CManager::Load_WTS_Process -- OpenProcess Fail \n") ); throw ERROR_OPENPROCESS; } bSuc = ::OpenProcessToken(hWinlogon, TOKEN_ALL_ACCESS, &hToken); if(!bSuc) { WriteLog( _T("CManager::Load_WTS_Process -- OpenProcessToken Fail \n") ); throw ERROR_OPENPROCESS_TOKEN; } bSuc = ::LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid); if(!bSuc) { WriteLog( _T("CManager::Load_WTS_Process -- LookupPrivilegeValue Fail \n") ); throw ERROR_LOOKUP_PRIV_VALUE; } bSuc = ::DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hTokenDup); if(!bSuc) { WriteLog( _T("CManager::Load_WTS_Process -- DuplicateTokenEx Fail \n") ); throw ERROR_DUP_TOKEN_EX; } bSuc = ::SetTokenInformation(hTokenDup, TokenSessionId, (LPVOID)&dwSessionID, sizeof(dwSessionID)); if(!bSuc) { WriteLog( _T("CManager::Load_WTS_Process -- SetTokenInformation Fail \n") ); throw ERROR_SET_TOKEN_INFO; } token_priv.PrivilegeCount = 1; token_priv.Privileges[0].Luid = luid; token_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; bSuc = ::AdjustTokenPrivileges(hTokenDup, FALSE, &token_priv, sizeof(token_priv), NULL, NULL); if(!bSuc) { WriteLog( _T("CManager::Load_WTS_Process -- AdjustTokenPrivileges Fail \n") ); throw ERROR_ADJ_TOKEN_PRIV; } } catch(...) { if(hToken) ::CloseHandle(hToken); if(hTokenDup) ::CloseHandle(hTokenDup); if(hWinlogon) ::CloseHandle(hWinlogon); return TRUE; } ULONG ulError =0; TCHAR szCmdLine[MAX_PATH] = _T(""); PROCESS_INFORMATION ProcessInfo = {0}; STARTUPINFO StartInfo = {0}; StartInfo.cb = sizeof(StartInfo); _tcscpy_s( szCmdLine, MAX_PATH, g_Manager.GetRetryImagePath() ); ULONG ulState = 0; ulState = ::InterlockedExchange((volatile LONG*)&m_ulRunningProcess, PROCESS_RUNNING); if(ulState) return FALSE; RtlZeroMemory(&m_TrayProcessInfo, sizeof(PROCESS_INFORMATION)); StartInfo.cb = sizeof(StartInfo); StartInfo.lpDesktop = (LPWSTR)Winsta0; bSuc = CreateProcessAsUser( hTokenDup, //hToken NULL, szCmdLine, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS | CREATE_NEW_PROCESS_GROUP, NULL, NULL, &StartInfo, &m_TrayProcessInfo ); if(!bSuc) { WriteLog( _T("CreateProcessAsUser Fail \n") ); g_Manager.m_bTrayThreadState = FALSE; } else { g_Manager.m_bTrayThreadState = TRUE; ::InterlockedExchange((volatile LONG*)&m_ulRunningProcess, PROCESS_RUNNING); } if(bSuc) { ::CloseHandle(m_TrayProcessInfo.hThread); ::CloseHandle(m_TrayProcessInfo.hProcess); } m_TrayProcessInfo.hThread = NULL; m_TrayProcessInfo.hProcess = NULL; if(hToken) ::CloseHandle(hToken); if(hTokenDup) ::CloseHandle(hTokenDup); if(hWinlogon) ::CloseHandle(hWinlogon); return bSuc; }