aboutsummaryrefslogtreecommitdiff
path: root/src/dutil/procutil.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/dutil/procutil.cpp57
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
7static HRESULT CreatePipes( 22static 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
364LExit: 379LExit:
@@ -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