diff options
Diffstat (limited to '')
-rw-r--r-- | src/dutil/rmutil.cpp | 63 |
1 files changed, 39 insertions, 24 deletions
diff --git a/src/dutil/rmutil.cpp b/src/dutil/rmutil.cpp index 75d3e277..95c8c8a4 100644 --- a/src/dutil/rmutil.cpp +++ b/src/dutil/rmutil.cpp | |||
@@ -3,6 +3,21 @@ | |||
3 | #include "precomp.h" | 3 | #include "precomp.h" |
4 | #include <restartmanager.h> | 4 | #include <restartmanager.h> |
5 | 5 | ||
6 | |||
7 | // Exit macros | ||
8 | #define RmExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_RMUTIL, x, s, __VA_ARGS__) | ||
9 | #define RmExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_RMUTIL, x, s, __VA_ARGS__) | ||
10 | #define RmExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_RMUTIL, x, s, __VA_ARGS__) | ||
11 | #define RmExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_RMUTIL, x, s, __VA_ARGS__) | ||
12 | #define RmExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_RMUTIL, x, s, __VA_ARGS__) | ||
13 | #define RmExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_RMUTIL, x, s, __VA_ARGS__) | ||
14 | #define RmExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_RMUTIL, p, x, e, s, __VA_ARGS__) | ||
15 | #define RmExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_RMUTIL, p, x, s, __VA_ARGS__) | ||
16 | #define RmExitOnNullDebugTrace(p, x, e, s, ...) ExitOnNullDebugTraceSource(DUTIL_SOURCE_RMUTIL, p, x, e, s, __VA_ARGS__) | ||
17 | #define RmExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_RMUTIL, p, x, s, __VA_ARGS__) | ||
18 | #define RmExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_RMUTIL, e, x, s, __VA_ARGS__) | ||
19 | #define RmExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_RMUTIL, g, x, s, __VA_ARGS__) | ||
20 | |||
6 | #define ARRAY_GROWTH_SIZE 5 | 21 | #define ARRAY_GROWTH_SIZE 5 |
7 | 22 | ||
8 | typedef DWORD (WINAPI *PFNRMJOINSESSION)( | 23 | typedef DWORD (WINAPI *PFNRMJOINSESSION)( |
@@ -80,13 +95,13 @@ extern "C" HRESULT DAPI RmuJoinSession( | |||
80 | *ppSession = NULL; | 95 | *ppSession = NULL; |
81 | 96 | ||
82 | pSession = static_cast<PRMU_SESSION>(MemAlloc(sizeof(RMU_SESSION), TRUE)); | 97 | pSession = static_cast<PRMU_SESSION>(MemAlloc(sizeof(RMU_SESSION), TRUE)); |
83 | ExitOnNull(pSession, hr, E_OUTOFMEMORY, "Failed to allocate the RMU_SESSION structure."); | 98 | RmExitOnNull(pSession, hr, E_OUTOFMEMORY, "Failed to allocate the RMU_SESSION structure."); |
84 | 99 | ||
85 | hr = RmuInitialize(); | 100 | hr = RmuInitialize(); |
86 | ExitOnFailure(hr, "Failed to initialize Restart Manager."); | 101 | RmExitOnFailure(hr, "Failed to initialize Restart Manager."); |
87 | 102 | ||
88 | er = vpfnRmJoinSession(&pSession->dwSessionHandle, wzSessionKey); | 103 | er = vpfnRmJoinSession(&pSession->dwSessionHandle, wzSessionKey); |
89 | ExitOnWin32Error(er, hr, "Failed to join Restart Manager session %ls.", wzSessionKey); | 104 | RmExitOnWin32Error(er, hr, "Failed to join Restart Manager session %ls.", wzSessionKey); |
90 | 105 | ||
91 | ::InitializeCriticalSection(&pSession->cs); | 106 | ::InitializeCriticalSection(&pSession->cs); |
92 | pSession->fInitialized = TRUE; | 107 | pSession->fInitialized = TRUE; |
@@ -120,7 +135,7 @@ extern "C" HRESULT DAPI RmuAddFile( | |||
120 | 135 | ||
121 | // Create or grow the jagged array. | 136 | // Create or grow the jagged array. |
122 | hr = StrArrayAllocString(&pSession->rgsczFilenames, &pSession->cFilenames, wzPath, 0); | 137 | hr = StrArrayAllocString(&pSession->rgsczFilenames, &pSession->cFilenames, wzPath, 0); |
123 | ExitOnFailure(hr, "Failed to add the filename to the array."); | 138 | RmExitOnFailure(hr, "Failed to add the filename to the array."); |
124 | 139 | ||
125 | LExit: | 140 | LExit: |
126 | ::LeaveCriticalSection(&pSession->cs); | 141 | ::LeaveCriticalSection(&pSession->cs); |
@@ -161,29 +176,29 @@ extern "C" HRESULT DAPI RmuAddProcessById( | |||
161 | // Adding SeDebugPrivilege in the event that the process targeted by ::OpenProcess() is in a another user context. | 176 | // Adding SeDebugPrivilege in the event that the process targeted by ::OpenProcess() is in a another user context. |
162 | if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken)) | 177 | if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken)) |
163 | { | 178 | { |
164 | ExitWithLastError(hr, "Failed to get process token."); | 179 | RmExitWithLastError(hr, "Failed to get process token."); |
165 | } | 180 | } |
166 | 181 | ||
167 | priv.PrivilegeCount = 1; | 182 | priv.PrivilegeCount = 1; |
168 | priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; | 183 | priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; |
169 | if (!::LookupPrivilegeValueW(NULL, L"SeDebugPrivilege", &priv.Privileges[0].Luid)) | 184 | if (!::LookupPrivilegeValueW(NULL, L"SeDebugPrivilege", &priv.Privileges[0].Luid)) |
170 | { | 185 | { |
171 | ExitWithLastError(hr, "Failed to get debug privilege LUID."); | 186 | RmExitWithLastError(hr, "Failed to get debug privilege LUID."); |
172 | } | 187 | } |
173 | 188 | ||
174 | cbPrevPriv = sizeof(TOKEN_PRIVILEGES); | 189 | cbPrevPriv = sizeof(TOKEN_PRIVILEGES); |
175 | pPrevPriv = static_cast<TOKEN_PRIVILEGES*>(MemAlloc(cbPrevPriv, TRUE)); | 190 | pPrevPriv = static_cast<TOKEN_PRIVILEGES*>(MemAlloc(cbPrevPriv, TRUE)); |
176 | ExitOnNull(pPrevPriv, hr, E_OUTOFMEMORY, "Failed to allocate memory for empty previous privileges."); | 191 | RmExitOnNull(pPrevPriv, hr, E_OUTOFMEMORY, "Failed to allocate memory for empty previous privileges."); |
177 | 192 | ||
178 | if (!::AdjustTokenPrivileges(hToken, FALSE, &priv, cbPrevPriv, pPrevPriv, &cbPrevPriv)) | 193 | if (!::AdjustTokenPrivileges(hToken, FALSE, &priv, cbPrevPriv, pPrevPriv, &cbPrevPriv)) |
179 | { | 194 | { |
180 | LPVOID pv = MemReAlloc(pPrevPriv, cbPrevPriv, TRUE); | 195 | LPVOID pv = MemReAlloc(pPrevPriv, cbPrevPriv, TRUE); |
181 | ExitOnNull(pv, hr, E_OUTOFMEMORY, "Failed to allocate memory for previous privileges."); | 196 | RmExitOnNull(pv, hr, E_OUTOFMEMORY, "Failed to allocate memory for previous privileges."); |
182 | pPrevPriv = static_cast<TOKEN_PRIVILEGES*>(pv); | 197 | pPrevPriv = static_cast<TOKEN_PRIVILEGES*>(pv); |
183 | 198 | ||
184 | if (!::AdjustTokenPrivileges(hToken, FALSE, &priv, cbPrevPriv, pPrevPriv, &cbPrevPriv)) | 199 | if (!::AdjustTokenPrivileges(hToken, FALSE, &priv, cbPrevPriv, pPrevPriv, &cbPrevPriv)) |
185 | { | 200 | { |
186 | ExitWithLastError(hr, "Failed to get debug privilege LUID."); | 201 | RmExitWithLastError(hr, "Failed to get debug privilege LUID."); |
187 | } | 202 | } |
188 | } | 203 | } |
189 | 204 | ||
@@ -195,13 +210,13 @@ extern "C" HRESULT DAPI RmuAddProcessById( | |||
195 | { | 210 | { |
196 | if (!::GetProcessTimes(hProcess, &CreationTime, &ExitTime, &KernelTime, &UserTime)) | 211 | if (!::GetProcessTimes(hProcess, &CreationTime, &ExitTime, &KernelTime, &UserTime)) |
197 | { | 212 | { |
198 | ExitWithLastError(hr, "Failed to get the process times for process ID %d.", dwProcessId); | 213 | RmExitWithLastError(hr, "Failed to get the process times for process ID %d.", dwProcessId); |
199 | } | 214 | } |
200 | 215 | ||
201 | ::EnterCriticalSection(&pSession->cs); | 216 | ::EnterCriticalSection(&pSession->cs); |
202 | fLocked = TRUE; | 217 | fLocked = TRUE; |
203 | hr = RmuApplicationArrayAlloc(&pSession->rgApplications, &pSession->cApplications, dwProcessId, CreationTime); | 218 | hr = RmuApplicationArrayAlloc(&pSession->rgApplications, &pSession->cApplications, dwProcessId, CreationTime); |
204 | ExitOnFailure(hr, "Failed to add the application to the array."); | 219 | RmExitOnFailure(hr, "Failed to add the application to the array."); |
205 | } | 220 | } |
206 | else | 221 | else |
207 | { | 222 | { |
@@ -213,7 +228,7 @@ extern "C" HRESULT DAPI RmuAddProcessById( | |||
213 | } | 228 | } |
214 | else | 229 | else |
215 | { | 230 | { |
216 | ExitOnWin32Error(er, hr, "Failed to open the process ID %d.", dwProcessId); | 231 | RmExitOnWin32Error(er, hr, "Failed to open the process ID %d.", dwProcessId); |
217 | } | 232 | } |
218 | } | 233 | } |
219 | 234 | ||
@@ -258,7 +273,7 @@ extern "C" HRESULT DAPI RmuAddProcessesByName( | |||
258 | BOOL fNotFound = FALSE; | 273 | BOOL fNotFound = FALSE; |
259 | 274 | ||
260 | hr = ProcFindAllIdsFromExeName(wzProcessName, &pdwProcessIds, &cProcessIds); | 275 | hr = ProcFindAllIdsFromExeName(wzProcessName, &pdwProcessIds, &cProcessIds); |
261 | ExitOnFailure(hr, "Failed to enumerate all the processes by name %ls.", wzProcessName); | 276 | RmExitOnFailure(hr, "Failed to enumerate all the processes by name %ls.", wzProcessName); |
262 | 277 | ||
263 | for (DWORD i = 0; i < cProcessIds; ++i) | 278 | for (DWORD i = 0; i < cProcessIds; ++i) |
264 | { | 279 | { |
@@ -270,7 +285,7 @@ extern "C" HRESULT DAPI RmuAddProcessesByName( | |||
270 | } | 285 | } |
271 | else | 286 | else |
272 | { | 287 | { |
273 | ExitOnFailure(hr, "Failed to add process %ls (%d) to the Restart Manager session.", wzProcessName, pdwProcessIds[i]); | 288 | RmExitOnFailure(hr, "Failed to add process %ls (%d) to the Restart Manager session.", wzProcessName, pdwProcessIds[i]); |
274 | } | 289 | } |
275 | } | 290 | } |
276 | 291 | ||
@@ -303,7 +318,7 @@ extern "C" HRESULT DAPI RmuAddService( | |||
303 | ::EnterCriticalSection(&pSession->cs); | 318 | ::EnterCriticalSection(&pSession->cs); |
304 | 319 | ||
305 | hr = StrArrayAllocString(&pSession->rgsczServiceNames, &pSession->cServiceNames, wzServiceName, 0); | 320 | hr = StrArrayAllocString(&pSession->rgsczServiceNames, &pSession->cServiceNames, wzServiceName, 0); |
306 | ExitOnFailure(hr, "Failed to add the service name to the array."); | 321 | RmExitOnFailure(hr, "Failed to add the service name to the array."); |
307 | 322 | ||
308 | LExit: | 323 | LExit: |
309 | ::LeaveCriticalSection(&pSession->cs); | 324 | ::LeaveCriticalSection(&pSession->cs); |
@@ -341,7 +356,7 @@ extern "C" HRESULT DAPI RmuRegisterResources( | |||
341 | pSession->cServiceNames, | 356 | pSession->cServiceNames, |
342 | pSession->rgsczServiceNames | 357 | pSession->rgsczServiceNames |
343 | ); | 358 | ); |
344 | ExitOnWin32Error(er, hr, "Failed to register the resources with the Restart Manager session."); | 359 | RmExitOnWin32Error(er, hr, "Failed to register the resources with the Restart Manager session."); |
345 | 360 | ||
346 | // Empty the arrays if registered in case additional resources are added later. | 361 | // Empty the arrays if registered in case additional resources are added later. |
347 | ReleaseNullStrArray(pSession->rgsczFilenames, pSession->cFilenames); | 362 | ReleaseNullStrArray(pSession->rgsczFilenames, pSession->cFilenames); |
@@ -373,11 +388,11 @@ extern "C" HRESULT DAPI RmuEndSession( | |||
373 | if (!pSession->fStartedSessionHandle) | 388 | if (!pSession->fStartedSessionHandle) |
374 | { | 389 | { |
375 | hr = RmuRegisterResources(pSession); | 390 | hr = RmuRegisterResources(pSession); |
376 | ExitOnFailure(hr, "Failed to register remaining resources."); | 391 | RmExitOnFailure(hr, "Failed to register remaining resources."); |
377 | } | 392 | } |
378 | 393 | ||
379 | er = vpfnRmEndSession(pSession->dwSessionHandle); | 394 | er = vpfnRmEndSession(pSession->dwSessionHandle); |
380 | ExitOnWin32Error(er, hr, "Failed to end the Restart Manager session."); | 395 | RmExitOnWin32Error(er, hr, "Failed to end the Restart Manager session."); |
381 | 396 | ||
382 | LExit: | 397 | LExit: |
383 | if (pSession->fInitialized) | 398 | if (pSession->fInitialized) |
@@ -404,16 +419,16 @@ static HRESULT RmuInitialize() | |||
404 | if (1 == iRef && !vhModule) | 419 | if (1 == iRef && !vhModule) |
405 | { | 420 | { |
406 | hr = LoadSystemLibrary(L"rstrtmgr.dll", &hModule); | 421 | hr = LoadSystemLibrary(L"rstrtmgr.dll", &hModule); |
407 | ExitOnFailure(hr, "Failed to load the rstrtmgr.dll module."); | 422 | RmExitOnFailure(hr, "Failed to load the rstrtmgr.dll module."); |
408 | 423 | ||
409 | vpfnRmJoinSession = reinterpret_cast<PFNRMJOINSESSION>(::GetProcAddress(hModule, "RmJoinSession")); | 424 | vpfnRmJoinSession = reinterpret_cast<PFNRMJOINSESSION>(::GetProcAddress(hModule, "RmJoinSession")); |
410 | ExitOnNullWithLastError(vpfnRmJoinSession, hr, "Failed to get the RmJoinSession procedure from rstrtmgr.dll."); | 425 | RmExitOnNullWithLastError(vpfnRmJoinSession, hr, "Failed to get the RmJoinSession procedure from rstrtmgr.dll."); |
411 | 426 | ||
412 | vpfnRmRegisterResources = reinterpret_cast<PFNRMREGISTERRESOURCES>(::GetProcAddress(hModule, "RmRegisterResources")); | 427 | vpfnRmRegisterResources = reinterpret_cast<PFNRMREGISTERRESOURCES>(::GetProcAddress(hModule, "RmRegisterResources")); |
413 | ExitOnNullWithLastError(vpfnRmRegisterResources, hr, "Failed to get the RmRegisterResources procedure from rstrtmgr.dll."); | 428 | RmExitOnNullWithLastError(vpfnRmRegisterResources, hr, "Failed to get the RmRegisterResources procedure from rstrtmgr.dll."); |
414 | 429 | ||
415 | vpfnRmEndSession = reinterpret_cast<PFNRMENDSESSION>(::GetProcAddress(hModule, "RmEndSession")); | 430 | vpfnRmEndSession = reinterpret_cast<PFNRMENDSESSION>(::GetProcAddress(hModule, "RmEndSession")); |
416 | ExitOnNullWithLastError(vpfnRmEndSession, hr, "Failed to get the RmEndSession procedure from rstrtmgr.dll."); | 431 | RmExitOnNullWithLastError(vpfnRmEndSession, hr, "Failed to get the RmEndSession procedure from rstrtmgr.dll."); |
417 | 432 | ||
418 | vhModule = hModule; | 433 | vhModule = hModule; |
419 | } | 434 | } |
@@ -447,7 +462,7 @@ static HRESULT RmuApplicationArrayAlloc( | |||
447 | RM_UNIQUE_PROCESS *pApplication = NULL; | 462 | RM_UNIQUE_PROCESS *pApplication = NULL; |
448 | 463 | ||
449 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(prgApplications), *pcApplications + 1, sizeof(RM_UNIQUE_PROCESS), ARRAY_GROWTH_SIZE); | 464 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(prgApplications), *pcApplications + 1, sizeof(RM_UNIQUE_PROCESS), ARRAY_GROWTH_SIZE); |
450 | ExitOnFailure(hr, "Failed to allocate memory for the application array."); | 465 | RmExitOnFailure(hr, "Failed to allocate memory for the application array."); |
451 | 466 | ||
452 | pApplication = static_cast<RM_UNIQUE_PROCESS*>(&(*prgApplications)[*pcApplications]); | 467 | pApplication = static_cast<RM_UNIQUE_PROCESS*>(&(*prgApplications)[*pcApplications]); |
453 | pApplication->dwProcessId = dwProcessId; | 468 | pApplication->dwProcessId = dwProcessId; |
@@ -466,7 +481,7 @@ static HRESULT RmuApplicationArrayFree( | |||
466 | HRESULT hr = S_OK; | 481 | HRESULT hr = S_OK; |
467 | 482 | ||
468 | hr = MemFree(rgApplications); | 483 | hr = MemFree(rgApplications); |
469 | ExitOnFailure(hr, "Failed to free memory for the application array."); | 484 | RmExitOnFailure(hr, "Failed to free memory for the application array."); |
470 | 485 | ||
471 | LExit: | 486 | LExit: |
472 | return hr; | 487 | return hr; |