diff options
Diffstat (limited to '')
-rw-r--r-- | src/dutil/procutil.cpp | 57 |
1 files changed, 36 insertions, 21 deletions
diff --git a/src/dutil/procutil.cpp b/src/dutil/procutil.cpp index 9833d0ec..6bfe5017 100644 --- a/src/dutil/procutil.cpp +++ b/src/dutil/procutil.cpp | |||
@@ -3,6 +3,21 @@ | |||
3 | #include "precomp.h" | 3 | #include "precomp.h" |
4 | 4 | ||
5 | 5 | ||
6 | // Exit macros | ||
7 | #define ProcExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_PROCUTIL, x, s, __VA_ARGS__) | ||
8 | #define ProcExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_PROCUTIL, x, s, __VA_ARGS__) | ||
9 | #define ProcExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_PROCUTIL, x, s, __VA_ARGS__) | ||
10 | #define ProcExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_PROCUTIL, x, s, __VA_ARGS__) | ||
11 | #define ProcExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_PROCUTIL, x, s, __VA_ARGS__) | ||
12 | #define ProcExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_PROCUTIL, x, s, __VA_ARGS__) | ||
13 | #define ProcExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_PROCUTIL, p, x, e, s, __VA_ARGS__) | ||
14 | #define ProcExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_PROCUTIL, p, x, s, __VA_ARGS__) | ||
15 | #define ProcExitOnNullDebugTrace(p, x, e, s, ...) ExitOnNullDebugTraceSource(DUTIL_SOURCE_PROCUTIL, p, x, e, s, __VA_ARGS__) | ||
16 | #define ProcExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_PROCUTIL, p, x, s, __VA_ARGS__) | ||
17 | #define ProcExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_PROCUTIL, e, x, s, __VA_ARGS__) | ||
18 | #define ProcExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_PROCUTIL, g, x, s, __VA_ARGS__) | ||
19 | |||
20 | |||
6 | // private functions | 21 | // private functions |
7 | static HRESULT CreatePipes( | 22 | static HRESULT CreatePipes( |
8 | __out HANDLE *phOutRead, | 23 | __out HANDLE *phOutRead, |
@@ -30,7 +45,7 @@ extern "C" HRESULT DAPI ProcElevated( | |||
30 | 45 | ||
31 | if (!::OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) | 46 | if (!::OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) |
32 | { | 47 | { |
33 | ExitWithLastError(hr, "Failed to open process token."); | 48 | ProcExitWithLastError(hr, "Failed to open process token."); |
34 | } | 49 | } |
35 | 50 | ||
36 | if (::GetTokenInformation(hToken, TokenElevation, &tokenElevated, sizeof(TOKEN_ELEVATION), &cbToken)) | 51 | if (::GetTokenInformation(hToken, TokenElevation, &tokenElevated, sizeof(TOKEN_ELEVATION), &cbToken)) |
@@ -50,7 +65,7 @@ extern "C" HRESULT DAPI ProcElevated( | |||
50 | } | 65 | } |
51 | else | 66 | else |
52 | { | 67 | { |
53 | ExitOnRootFailure(hr, "Failed to get elevation token from process."); | 68 | ProcExitOnRootFailure(hr, "Failed to get elevation token from process."); |
54 | } | 69 | } |
55 | } | 70 | } |
56 | 71 | ||
@@ -76,7 +91,7 @@ extern "C" HRESULT DAPI ProcWow64( | |||
76 | USHORT pProcessMachine = IMAGE_FILE_MACHINE_UNKNOWN; | 91 | USHORT pProcessMachine = IMAGE_FILE_MACHINE_UNKNOWN; |
77 | if (!pfnIsWow64Process2(hProcess, &pProcessMachine, nullptr)) | 92 | if (!pfnIsWow64Process2(hProcess, &pProcessMachine, nullptr)) |
78 | { | 93 | { |
79 | ExitWithLastError(hr, "Failed to check WOW64 process - IsWow64Process2."); | 94 | ProcExitWithLastError(hr, "Failed to check WOW64 process - IsWow64Process2."); |
80 | } | 95 | } |
81 | 96 | ||
82 | if (pProcessMachine != IMAGE_FILE_MACHINE_UNKNOWN) | 97 | if (pProcessMachine != IMAGE_FILE_MACHINE_UNKNOWN) |
@@ -93,7 +108,7 @@ extern "C" HRESULT DAPI ProcWow64( | |||
93 | { | 108 | { |
94 | if (!pfnIsWow64Process(hProcess, &fIsWow64)) | 109 | if (!pfnIsWow64Process(hProcess, &fIsWow64)) |
95 | { | 110 | { |
96 | ExitWithLastError(hr, "Failed to check WOW64 process - IsWow64Process."); | 111 | ProcExitWithLastError(hr, "Failed to check WOW64 process - IsWow64Process."); |
97 | } | 112 | } |
98 | } | 113 | } |
99 | } | 114 | } |
@@ -121,7 +136,7 @@ extern "C" HRESULT DAPI ProcDisableWowFileSystemRedirection( | |||
121 | 136 | ||
122 | if (!pfnWow64DisableWow64FsRedirection(&pfsr->pvRevertState)) | 137 | if (!pfnWow64DisableWow64FsRedirection(&pfsr->pvRevertState)) |
123 | { | 138 | { |
124 | ExitWithLastError(hr, "Failed to disable file system redirection."); | 139 | ProcExitWithLastError(hr, "Failed to disable file system redirection."); |
125 | } | 140 | } |
126 | 141 | ||
127 | pfsr->fDisabled = TRUE; | 142 | pfsr->fDisabled = TRUE; |
@@ -143,7 +158,7 @@ extern "C" HRESULT DAPI ProcRevertWowFileSystemRedirection( | |||
143 | 158 | ||
144 | if (!pfnWow64RevertWow64FsRedirection(pfsr->pvRevertState)) | 159 | if (!pfnWow64RevertWow64FsRedirection(pfsr->pvRevertState)) |
145 | { | 160 | { |
146 | ExitWithLastError(hr, "Failed to revert file system redirection."); | 161 | ProcExitWithLastError(hr, "Failed to revert file system redirection."); |
147 | } | 162 | } |
148 | 163 | ||
149 | pfsr->fDisabled = FALSE; | 164 | pfsr->fDisabled = FALSE; |
@@ -168,13 +183,13 @@ extern "C" HRESULT DAPI ProcExec( | |||
168 | PROCESS_INFORMATION pi = { }; | 183 | PROCESS_INFORMATION pi = { }; |
169 | 184 | ||
170 | hr = StrAllocFormatted(&sczFullCommandLine, L"\"%ls\" %ls", wzExecutablePath, wzCommandLine ? wzCommandLine : L""); | 185 | hr = StrAllocFormatted(&sczFullCommandLine, L"\"%ls\" %ls", wzExecutablePath, wzCommandLine ? wzCommandLine : L""); |
171 | ExitOnFailure(hr, "Failed to allocate full command-line."); | 186 | ProcExitOnFailure(hr, "Failed to allocate full command-line."); |
172 | 187 | ||
173 | si.cb = sizeof(si); | 188 | si.cb = sizeof(si); |
174 | si.wShowWindow = static_cast<WORD>(nCmdShow); | 189 | si.wShowWindow = static_cast<WORD>(nCmdShow); |
175 | if (!::CreateProcessW(wzExecutablePath, sczFullCommandLine, NULL, NULL, FALSE, 0, 0, NULL, &si, &pi)) | 190 | if (!::CreateProcessW(wzExecutablePath, sczFullCommandLine, NULL, NULL, FALSE, 0, 0, NULL, &si, &pi)) |
176 | { | 191 | { |
177 | ExitWithLastError(hr, "Failed to create process: %ls", sczFullCommandLine); | 192 | ProcExitWithLastError(hr, "Failed to create process: %ls", sczFullCommandLine); |
178 | } | 193 | } |
179 | 194 | ||
180 | *phProcess = pi.hProcess; | 195 | *phProcess = pi.hProcess; |
@@ -213,7 +228,7 @@ extern "C" HRESULT DAPI ProcExecute( | |||
213 | 228 | ||
214 | // Create redirect pipes. | 229 | // Create redirect pipes. |
215 | hr = CreatePipes(&hOutRead, &hOutWrite, &hErrWrite, &hInRead, &hInWrite); | 230 | hr = CreatePipes(&hOutRead, &hOutWrite, &hErrWrite, &hInRead, &hInWrite); |
216 | ExitOnFailure(hr, "failed to create output pipes"); | 231 | ProcExitOnFailure(hr, "failed to create output pipes"); |
217 | 232 | ||
218 | // Set up startup structure. | 233 | // Set up startup structure. |
219 | si.cb = sizeof(STARTUPINFOW); | 234 | si.cb = sizeof(STARTUPINFOW); |
@@ -249,7 +264,7 @@ extern "C" HRESULT DAPI ProcExecute( | |||
249 | } | 264 | } |
250 | else | 265 | else |
251 | { | 266 | { |
252 | ExitWithLastError(hr, "Process failed to execute."); | 267 | ProcExitWithLastError(hr, "Process failed to execute."); |
253 | } | 268 | } |
254 | 269 | ||
255 | *phProcess = pi.hProcess; | 270 | *phProcess = pi.hProcess; |
@@ -305,7 +320,7 @@ extern "C" HRESULT DAPI ProcWaitForCompletion( | |||
305 | er = ::WaitForSingleObject(hProcess, dwTimeout); | 320 | er = ::WaitForSingleObject(hProcess, dwTimeout); |
306 | if (WAIT_FAILED == er) | 321 | if (WAIT_FAILED == er) |
307 | { | 322 | { |
308 | ExitWithLastError(hr, "Failed to wait for process to complete."); | 323 | ProcExitWithLastError(hr, "Failed to wait for process to complete."); |
309 | } | 324 | } |
310 | else if (WAIT_TIMEOUT == er) | 325 | else if (WAIT_TIMEOUT == er) |
311 | { | 326 | { |
@@ -314,7 +329,7 @@ extern "C" HRESULT DAPI ProcWaitForCompletion( | |||
314 | 329 | ||
315 | if (!::GetExitCodeProcess(hProcess, &er)) | 330 | if (!::GetExitCodeProcess(hProcess, &er)) |
316 | { | 331 | { |
317 | ExitWithLastError(hr, "Failed to get process return code."); | 332 | ProcExitWithLastError(hr, "Failed to get process return code."); |
318 | } | 333 | } |
319 | 334 | ||
320 | *pReturnCode = er; | 335 | *pReturnCode = er; |
@@ -340,7 +355,7 @@ extern "C" HRESULT DAPI ProcWaitForIds( | |||
340 | DWORD cProcesses = 0; | 355 | DWORD cProcesses = 0; |
341 | 356 | ||
342 | rghProcesses = static_cast<HANDLE*>(MemAlloc(sizeof(DWORD) * cProcessIds, TRUE)); | 357 | rghProcesses = static_cast<HANDLE*>(MemAlloc(sizeof(DWORD) * cProcessIds, TRUE)); |
343 | ExitOnNull(rgdwProcessIds, hr, E_OUTOFMEMORY, "Failed to allocate array for process ID Handles."); | 358 | ProcExitOnNull(rgdwProcessIds, hr, E_OUTOFMEMORY, "Failed to allocate array for process ID Handles."); |
344 | 359 | ||
345 | for (DWORD i = 0; i < cProcessIds; ++i) | 360 | for (DWORD i = 0; i < cProcessIds; ++i) |
346 | { | 361 | { |
@@ -354,11 +369,11 @@ extern "C" HRESULT DAPI ProcWaitForIds( | |||
354 | er = ::WaitForMultipleObjects(cProcesses, rghProcesses, TRUE, dwMilliseconds); | 369 | er = ::WaitForMultipleObjects(cProcesses, rghProcesses, TRUE, dwMilliseconds); |
355 | if (WAIT_FAILED == er) | 370 | if (WAIT_FAILED == er) |
356 | { | 371 | { |
357 | ExitWithLastError(hr, "Failed to wait for process to complete."); | 372 | ProcExitWithLastError(hr, "Failed to wait for process to complete."); |
358 | } | 373 | } |
359 | else if (WAIT_TIMEOUT == er) | 374 | else if (WAIT_TIMEOUT == er) |
360 | { | 375 | { |
361 | ExitOnWin32Error(er, hr, "Timed out while waiting for process to complete."); | 376 | ProcExitOnWin32Error(er, hr, "Timed out while waiting for process to complete."); |
362 | } | 377 | } |
363 | 378 | ||
364 | LExit: | 379 | LExit: |
@@ -393,7 +408,7 @@ extern "C" HRESULT DAPI ProcCloseIds( | |||
393 | { | 408 | { |
394 | if (!::EnumWindows(&CloseWindowEnumCallback, pdwProcessIds[i])) | 409 | if (!::EnumWindows(&CloseWindowEnumCallback, pdwProcessIds[i])) |
395 | { | 410 | { |
396 | ExitWithLastError(hr, "Failed to enumerate windows."); | 411 | ProcExitWithLastError(hr, "Failed to enumerate windows."); |
397 | } | 412 | } |
398 | } | 413 | } |
399 | 414 | ||
@@ -430,30 +445,30 @@ static HRESULT CreatePipes( | |||
430 | // Create pipes | 445 | // Create pipes |
431 | if (!::CreatePipe(&hOutTemp, &hOutWrite, &sa, 0)) | 446 | if (!::CreatePipe(&hOutTemp, &hOutWrite, &sa, 0)) |
432 | { | 447 | { |
433 | ExitWithLastError(hr, "failed to create output pipe"); | 448 | ProcExitWithLastError(hr, "failed to create output pipe"); |
434 | } | 449 | } |
435 | 450 | ||
436 | if (!::CreatePipe(&hInRead, &hInTemp, &sa, 0)) | 451 | if (!::CreatePipe(&hInRead, &hInTemp, &sa, 0)) |
437 | { | 452 | { |
438 | ExitWithLastError(hr, "failed to create input pipe"); | 453 | ProcExitWithLastError(hr, "failed to create input pipe"); |
439 | } | 454 | } |
440 | 455 | ||
441 | // Duplicate output pipe so standard error and standard output write to the same pipe. | 456 | // Duplicate output pipe so standard error and standard output write to the same pipe. |
442 | if (!::DuplicateHandle(::GetCurrentProcess(), hOutWrite, ::GetCurrentProcess(), &hErrWrite, 0, TRUE, DUPLICATE_SAME_ACCESS)) | 457 | if (!::DuplicateHandle(::GetCurrentProcess(), hOutWrite, ::GetCurrentProcess(), &hErrWrite, 0, TRUE, DUPLICATE_SAME_ACCESS)) |
443 | { | 458 | { |
444 | ExitWithLastError(hr, "failed to duplicate write handle"); | 459 | ProcExitWithLastError(hr, "failed to duplicate write handle"); |
445 | } | 460 | } |
446 | 461 | ||
447 | // We need to create new "output read" and "input write" handles that are non inheritable. Otherwise CreateProcess will creates handles in | 462 | // We need to create new "output read" and "input write" handles that are non inheritable. Otherwise CreateProcess will creates handles in |
448 | // the child process that can't be closed. | 463 | // the child process that can't be closed. |
449 | if (!::DuplicateHandle(::GetCurrentProcess(), hOutTemp, ::GetCurrentProcess(), &hOutRead, 0, FALSE, DUPLICATE_SAME_ACCESS)) | 464 | if (!::DuplicateHandle(::GetCurrentProcess(), hOutTemp, ::GetCurrentProcess(), &hOutRead, 0, FALSE, DUPLICATE_SAME_ACCESS)) |
450 | { | 465 | { |
451 | ExitWithLastError(hr, "failed to duplicate output pipe"); | 466 | ProcExitWithLastError(hr, "failed to duplicate output pipe"); |
452 | } | 467 | } |
453 | 468 | ||
454 | if (!::DuplicateHandle(::GetCurrentProcess(), hInTemp, ::GetCurrentProcess(), &hInWrite, 0, FALSE, DUPLICATE_SAME_ACCESS)) | 469 | if (!::DuplicateHandle(::GetCurrentProcess(), hInTemp, ::GetCurrentProcess(), &hInWrite, 0, FALSE, DUPLICATE_SAME_ACCESS)) |
455 | { | 470 | { |
456 | ExitWithLastError(hr, "failed to duplicate input pipe"); | 471 | ProcExitWithLastError(hr, "failed to duplicate input pipe"); |
457 | } | 472 | } |
458 | 473 | ||
459 | // now that everything has succeeded, assign to the outputs | 474 | // now that everything has succeeded, assign to the outputs |