static HRESULT InitializeEngineState( __in BURN_ENGINE_STATE* pEngineState ) { HRESULT hr = S_OK; BOOL fElevated = FALSE; pEngineState->automaticUpdates = BURN_AU_PAUSE_ACTION_IFELEVATED; pEngineState->dwElevatedLoggingTlsId = TLS_OUT_OF_INDEXES; ::InitializeCriticalSection(&pEngineState->csActive); ::InitializeCriticalSection(&pEngineState->userExperience.csEngineActive); PipeConnectionInitialize(&pEngineState->companionConnection); PipeConnectionInitialize(&pEngineState->embeddedConnection); ProcElevated(::GetCurrentProcess(), &fElevated); pEngineState->elevationState = fElevated ? BURN_ELEVATION_STATE_ELEVATED : BURN_ELEVATION_STATE_UNELEVATED; hr = SectionInitialize(&pEngineState->section); ExitOnFailure(hr, "Failed to initialize engine section."); LExit: return hr; }
/******************************************************************** RmuAddProcessById - Adds the process ID to the Restart Manager sesion. You should call this multiple times as necessary before calling RmuRegisterResources. ********************************************************************/ extern "C" HRESULT DAPI RmuAddProcessById( __in PRMU_SESSION pSession, __in DWORD dwProcessId ) { HRESULT hr = S_OK; HANDLE hProcess = NULL; FILETIME CreationTime = {}; FILETIME ExitTime = {}; FILETIME KernelTime = {}; FILETIME UserTime = {}; BOOL fLocked = FALSE; HANDLE hToken = NULL; TOKEN_PRIVILEGES priv = { 0 }; TOKEN_PRIVILEGES* pPrevPriv = NULL; DWORD cbPrevPriv = 0; DWORD er = ERROR_SUCCESS; BOOL fAdjustedPrivileges = FALSE; BOOL fElevated = FALSE; ProcElevated(::GetCurrentProcess(), &fElevated); // Must be elevated to adjust process privileges if (fElevated) { // Adding SeDebugPrivilege in the event that the process targeted by ::OpenProcess() is in a another user context. if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken)) { ExitWithLastError(hr, "Failed to get process token."); } priv.PrivilegeCount = 1; priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (!::LookupPrivilegeValueW(NULL, L"SeDebugPrivilege", &priv.Privileges[0].Luid)) { ExitWithLastError(hr, "Failed to get debug privilege LUID."); } cbPrevPriv = sizeof(TOKEN_PRIVILEGES); pPrevPriv = static_cast<TOKEN_PRIVILEGES*>(MemAlloc(cbPrevPriv, TRUE)); ExitOnNull(pPrevPriv, hr, E_OUTOFMEMORY, "Failed to allocate memory for empty previous privileges."); if (!::AdjustTokenPrivileges(hToken, FALSE, &priv, cbPrevPriv, pPrevPriv, &cbPrevPriv)) { LPVOID pv = MemReAlloc(pPrevPriv, cbPrevPriv, TRUE); ExitOnNull(pv, hr, E_OUTOFMEMORY, "Failed to allocate memory for previous privileges."); pPrevPriv = static_cast<TOKEN_PRIVILEGES*>(pv); if (!::AdjustTokenPrivileges(hToken, FALSE, &priv, cbPrevPriv, pPrevPriv, &cbPrevPriv)) { ExitWithLastError(hr, "Failed to get debug privilege LUID."); } } fAdjustedPrivileges = TRUE; } hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessId); if (hProcess) { if (!::GetProcessTimes(hProcess, &CreationTime, &ExitTime, &KernelTime, &UserTime)) { ExitWithLastError(hr, "Failed to get the process times for process ID %d.", dwProcessId); } ::EnterCriticalSection(&pSession->cs); fLocked = TRUE; hr = RmuApplicationArrayAlloc(&pSession->rgApplications, &pSession->cApplications, dwProcessId, CreationTime); ExitOnFailure(hr, "Failed to add the application to the array."); } else { er = ::GetLastError(); if (ERROR_ACCESS_DENIED == er) { // OpenProcess will fail when not elevated and the target process is in another user context. Let the caller log and continue. hr = E_NOTFOUND; } else { ExitOnWin32Error(er, hr, "Failed to open the process ID %d.", dwProcessId); } } LExit: if (hProcess) { ::CloseHandle(hProcess); } if (fAdjustedPrivileges) { ::AdjustTokenPrivileges(hToken, FALSE, pPrevPriv, 0, NULL, NULL); } ReleaseMem(pPrevPriv); ReleaseHandle(hToken); if (fLocked) { ::LeaveCriticalSection(&pSession->cs); } return hr; }