diff options
| -rw-r--r-- | src/burn/engine/core.cpp | 14 | ||||
| -rw-r--r-- | src/burn/engine/core.h | 3 | ||||
| -rw-r--r-- | src/burn/engine/elevation.cpp | 42 | ||||
| -rw-r--r-- | src/burn/engine/engine.cpp | 30 | ||||
| -rw-r--r-- | src/burn/engine/pipe.cpp | 102 | ||||
| -rw-r--r-- | src/burn/engine/pipe.h | 13 | ||||
| -rw-r--r-- | src/burn/test/BurnUnitTest/ElevationTest.cpp | 27 |
7 files changed, 61 insertions, 170 deletions
diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp index 94aaf204..3e45cdfc 100644 --- a/src/burn/engine/core.cpp +++ b/src/burn/engine/core.cpp | |||
| @@ -1086,14 +1086,6 @@ extern "C" HRESULT CoreCreateCleanRoomCommandLine( | |||
| 1086 | ExitOnFailure(hr, "Failed to append /disablesystemrestore."); | 1086 | ExitOnFailure(hr, "Failed to append /disablesystemrestore."); |
| 1087 | } | 1087 | } |
| 1088 | 1088 | ||
| 1089 | #ifdef ENABLE_UNELEVATE | ||
| 1090 | if (pInternalCommand->fDisableUnelevate) | ||
| 1091 | { | ||
| 1092 | hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls", BURN_COMMANDLINE_SWITCH_DISABLE_UNELEVATE); | ||
| 1093 | ExitOnFailure(hr, "Failed to append switch: %ls.", BURN_COMMANDLINE_SWITCH_DISABLE_UNELEVATE); | ||
| 1094 | } | ||
| 1095 | #endif | ||
| 1096 | |||
| 1097 | if (pInternalCommand->sczOriginalSource) | 1089 | if (pInternalCommand->sczOriginalSource) |
| 1098 | { | 1090 | { |
| 1099 | hr = StrAllocConcat(psczCommandLine, L" /originalsource", 0); | 1091 | hr = StrAllocConcat(psczCommandLine, L" /originalsource", 0); |
| @@ -1646,12 +1638,6 @@ extern "C" HRESULT CoreParseCommandLine( | |||
| 1646 | { | 1638 | { |
| 1647 | pCommand->fPassthrough = TRUE; | 1639 | pCommand->fPassthrough = TRUE; |
| 1648 | } | 1640 | } |
| 1649 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_DISABLE_UNELEVATE, -1)) | ||
| 1650 | { | ||
| 1651 | #ifdef ENABLE_UNELEVATE | ||
| 1652 | pInternalCommand->fDisableUnelevate = TRUE; | ||
| 1653 | #endif | ||
| 1654 | } | ||
| 1655 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_RUNONCE, -1)) | 1641 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_RUNONCE, -1)) |
| 1656 | { | 1642 | { |
| 1657 | if (BURN_MODE_UNKNOWN != pInternalCommand->mode) | 1643 | if (BURN_MODE_UNKNOWN != pInternalCommand->mode) |
diff --git a/src/burn/engine/core.h b/src/burn/engine/core.h index ccc33ba4..f3328738 100644 --- a/src/burn/engine/core.h +++ b/src/burn/engine/core.h | |||
| @@ -91,9 +91,6 @@ typedef struct _BURN_ENGINE_COMMAND | |||
| 91 | BURN_MODE mode; | 91 | BURN_MODE mode; |
| 92 | BURN_AU_PAUSE_ACTION automaticUpdates; | 92 | BURN_AU_PAUSE_ACTION automaticUpdates; |
| 93 | BOOL fDisableSystemRestore; | 93 | BOOL fDisableSystemRestore; |
| 94 | #ifdef ENABLE_UNELEVATE | ||
| 95 | BOOL fDisableUnelevate; | ||
| 96 | #endif | ||
| 97 | BOOL fInitiallyElevated; | 94 | BOOL fInitiallyElevated; |
| 98 | 95 | ||
| 99 | LPWSTR sczActiveParent; | 96 | LPWSTR sczActiveParent; |
diff --git a/src/burn/engine/elevation.cpp b/src/burn/engine/elevation.cpp index 03674f0b..c229fa58 100644 --- a/src/burn/engine/elevation.cpp +++ b/src/burn/engine/elevation.cpp | |||
| @@ -100,6 +100,16 @@ typedef struct _BURN_ELEVATION_CHILD_MESSAGE_CONTEXT | |||
| 100 | 100 | ||
| 101 | // internal function declarations | 101 | // internal function declarations |
| 102 | 102 | ||
| 103 | /******************************************************************* | ||
| 104 | LaunchElevatedProcess - Called from the per-user process to create | ||
| 105 | the per-machine process and set up the | ||
| 106 | communication pipe. | ||
| 107 | |||
| 108 | *******************************************************************/ | ||
| 109 | static HRESULT LaunchElevatedProcess( | ||
| 110 | __in BURN_ENGINE_STATE* pEngineState, | ||
| 111 | __in_opt HWND hwndParent | ||
| 112 | ); | ||
| 103 | static DWORD WINAPI ElevatedChildCacheThreadProc( | 113 | static DWORD WINAPI ElevatedChildCacheThreadProc( |
| 104 | __in LPVOID lpThreadParameter | 114 | __in LPVOID lpThreadParameter |
| 105 | ); | 115 | ); |
| @@ -367,7 +377,7 @@ extern "C" HRESULT ElevationElevate( | |||
| 367 | nResult = IDOK; | 377 | nResult = IDOK; |
| 368 | 378 | ||
| 369 | // Create the elevated process and if successful, wait for it to connect. | 379 | // Create the elevated process and if successful, wait for it to connect. |
| 370 | hr = PipeLaunchChildProcess(pEngineState->sczBundleEngineWorkingPath, &pEngineState->companionConnection, TRUE, hwndParent); | 380 | hr = LaunchElevatedProcess(pEngineState, hwndParent); |
| 371 | if (SUCCEEDED(hr)) | 381 | if (SUCCEEDED(hr)) |
| 372 | { | 382 | { |
| 373 | LogId(REPORT_STANDARD, MSG_LAUNCH_ELEVATED_ENGINE_SUCCESS); | 383 | LogId(REPORT_STANDARD, MSG_LAUNCH_ELEVATED_ENGINE_SUCCESS); |
| @@ -1371,6 +1381,36 @@ LExit: | |||
| 1371 | 1381 | ||
| 1372 | // internal function definitions | 1382 | // internal function definitions |
| 1373 | 1383 | ||
| 1384 | static HRESULT LaunchElevatedProcess( | ||
| 1385 | __in BURN_ENGINE_STATE* pEngineState, | ||
| 1386 | __in_opt HWND hwndParent | ||
| 1387 | ) | ||
| 1388 | { | ||
| 1389 | HRESULT hr = S_OK; | ||
| 1390 | DWORD dwCurrentProcessId = ::GetCurrentProcessId(); | ||
| 1391 | LPWSTR sczParameters = NULL; | ||
| 1392 | HANDLE hProcess = NULL; | ||
| 1393 | BURN_PIPE_CONNECTION* pConnection = &pEngineState->companionConnection; | ||
| 1394 | |||
| 1395 | hr = StrAllocFormatted(&sczParameters, L"-q -%ls %ls %ls %u", BURN_COMMANDLINE_SWITCH_ELEVATED, pConnection->sczName, pConnection->sczSecret, dwCurrentProcessId); | ||
| 1396 | ExitOnFailure(hr, "Failed to allocate parameters for elevated process."); | ||
| 1397 | |||
| 1398 | // Since ShellExecuteEx doesn't support passing inherited handles, don't bother with CoreAppendFileHandleSelfToCommandLine. | ||
| 1399 | // We could fallback to using ::DuplicateHandle to inject the file handle later if necessary. | ||
| 1400 | hr = ShelExec(pEngineState->sczBundleEngineWorkingPath, sczParameters, L"runas", NULL, SW_SHOWNA, hwndParent, &hProcess); | ||
| 1401 | ExitOnFailure(hr, "Failed to launch elevated child process: %ls", pEngineState->sczBundleEngineWorkingPath); | ||
| 1402 | |||
| 1403 | pConnection->dwProcessId = ::GetProcessId(hProcess); | ||
| 1404 | pConnection->hProcess = hProcess; | ||
| 1405 | hProcess = NULL; | ||
| 1406 | |||
| 1407 | LExit: | ||
| 1408 | ReleaseHandle(hProcess); | ||
| 1409 | ReleaseStr(sczParameters); | ||
| 1410 | |||
| 1411 | return hr; | ||
| 1412 | } | ||
| 1413 | |||
| 1374 | static DWORD WINAPI ElevatedChildCacheThreadProc( | 1414 | static DWORD WINAPI ElevatedChildCacheThreadProc( |
| 1375 | __in LPVOID lpThreadParameter | 1415 | __in LPVOID lpThreadParameter |
| 1376 | ) | 1416 | ) |
diff --git a/src/burn/engine/engine.cpp b/src/burn/engine/engine.cpp index 8b4a296b..0ce2de6d 100644 --- a/src/burn/engine/engine.cpp +++ b/src/burn/engine/engine.cpp | |||
| @@ -462,31 +462,19 @@ static HRESULT RunUntrusted( | |||
| 462 | hr = CoreCreateCleanRoomCommandLine(&sczParameters, pEngineState, wzCleanRoomBundlePath, sczCurrentProcessPath, &hFileAttached, &hFileSelf); | 462 | hr = CoreCreateCleanRoomCommandLine(&sczParameters, pEngineState, wzCleanRoomBundlePath, sczCurrentProcessPath, &hFileAttached, &hFileSelf); |
| 463 | ExitOnFailure(hr, "Failed to create clean room command-line."); | 463 | ExitOnFailure(hr, "Failed to create clean room command-line."); |
| 464 | 464 | ||
| 465 | #ifdef ENABLE_UNELEVATE | 465 | hr = StrAllocFormattedSecure(&sczFullCommandLine, L"\"%ls\" %ls", wzCleanRoomBundlePath, sczParameters); |
| 466 | // TODO: Pass file handle to unelevated process if this ever gets reenabled. | 466 | ExitOnFailure(hr, "Failed to allocate full command-line."); |
| 467 | if (!pEngineState->internalCommand.fDisableUnelevate) | ||
| 468 | { | ||
| 469 | // Try to launch unelevated and if that fails for any reason, we'll launch our process normally (even though that may make it elevated). | ||
| 470 | hr = ProcExecuteAsInteractiveUser(wzCleanRoomBundlePath, sczParameters, &hProcess); | ||
| 471 | } | ||
| 472 | #endif | ||
| 473 | 467 | ||
| 474 | if (!hProcess) | 468 | si.cb = sizeof(si); |
| 469 | si.wShowWindow = static_cast<WORD>(pEngineState->command.nCmdShow); | ||
| 470 | if (!::CreateProcessW(wzCleanRoomBundlePath, sczFullCommandLine, NULL, NULL, TRUE, 0, 0, NULL, &si, &pi)) | ||
| 475 | { | 471 | { |
| 476 | hr = StrAllocFormattedSecure(&sczFullCommandLine, L"\"%ls\" %ls", wzCleanRoomBundlePath, sczParameters); | 472 | ExitWithLastError(hr, "Failed to launch clean room process: %ls", sczFullCommandLine); |
| 477 | ExitOnFailure(hr, "Failed to allocate full command-line."); | ||
| 478 | |||
| 479 | si.cb = sizeof(si); | ||
| 480 | si.wShowWindow = static_cast<WORD>(pEngineState->command.nCmdShow); | ||
| 481 | if (!::CreateProcessW(wzCleanRoomBundlePath, sczFullCommandLine, NULL, NULL, TRUE, 0, 0, NULL, &si, &pi)) | ||
| 482 | { | ||
| 483 | ExitWithLastError(hr, "Failed to launch clean room process: %ls", sczFullCommandLine); | ||
| 484 | } | ||
| 485 | |||
| 486 | hProcess = pi.hProcess; | ||
| 487 | pi.hProcess = NULL; | ||
| 488 | } | 473 | } |
| 489 | 474 | ||
| 475 | hProcess = pi.hProcess; | ||
| 476 | pi.hProcess = NULL; | ||
| 477 | |||
| 490 | hr = ProcWaitForCompletion(hProcess, INFINITE, &pEngineState->userExperience.dwExitCode); | 478 | hr = ProcWaitForCompletion(hProcess, INFINITE, &pEngineState->userExperience.dwExitCode); |
| 491 | ExitOnFailure(hr, "Failed to wait for clean room process: %ls", wzCleanRoomBundlePath); | 479 | ExitOnFailure(hr, "Failed to wait for clean room process: %ls", wzCleanRoomBundlePath); |
| 492 | 480 | ||
diff --git a/src/burn/engine/pipe.cpp b/src/burn/engine/pipe.cpp index a9fd24e8..48be8785 100644 --- a/src/burn/engine/pipe.cpp +++ b/src/burn/engine/pipe.cpp | |||
| @@ -314,108 +314,6 @@ LExit: | |||
| 314 | } | 314 | } |
| 315 | 315 | ||
| 316 | /******************************************************************* | 316 | /******************************************************************* |
| 317 | PipeLaunchParentProcess - Called from the per-machine process to create | ||
| 318 | a per-user process and set up the | ||
| 319 | communication pipe. | ||
| 320 | |||
| 321 | *******************************************************************/ | ||
| 322 | const LPCWSTR BURN_COMMANDLINE_SWITCH_UNELEVATED = L"burn.unelevated"; | ||
| 323 | HRESULT PipeLaunchParentProcess( | ||
| 324 | __in_z LPCWSTR wzCommandLine, | ||
| 325 | __in int nCmdShow, | ||
| 326 | __in_z LPWSTR sczConnectionName, | ||
| 327 | __in_z LPWSTR sczSecret, | ||
| 328 | __in BOOL /*fDisableUnelevate*/ | ||
| 329 | ) | ||
| 330 | { | ||
| 331 | HRESULT hr = S_OK; | ||
| 332 | DWORD dwProcessId = 0; | ||
| 333 | LPWSTR sczBurnPath = NULL; | ||
| 334 | LPWSTR sczParameters = NULL; | ||
| 335 | HANDLE hProcess = NULL; | ||
| 336 | |||
| 337 | dwProcessId = ::GetCurrentProcessId(); | ||
| 338 | |||
| 339 | hr = PathForCurrentProcess(&sczBurnPath, NULL); | ||
| 340 | ExitOnFailure(hr, "Failed to get current process path."); | ||
| 341 | |||
| 342 | hr = StrAllocFormatted(&sczParameters, L"-%ls %ls %ls %u %ls", BURN_COMMANDLINE_SWITCH_UNELEVATED, sczConnectionName, sczSecret, dwProcessId, wzCommandLine); | ||
| 343 | ExitOnFailure(hr, "Failed to allocate parameters for unelevated process."); | ||
| 344 | |||
| 345 | #ifdef ENABLE_UNELEVATE | ||
| 346 | if (fDisableUnelevate) | ||
| 347 | { | ||
| 348 | hr = ProcExec(sczBurnPath, sczParameters, nCmdShow, &hProcess); | ||
| 349 | ExitOnFailure(hr, "Failed to launch parent process with unelevate disabled: %ls", sczBurnPath); | ||
| 350 | } | ||
| 351 | else | ||
| 352 | { | ||
| 353 | // Try to launch unelevated and if that fails for any reason, try launch our process normally (even though that may make it elevated). | ||
| 354 | hr = ProcExecuteAsInteractiveUser(sczBurnPath, sczParameters, &hProcess); | ||
| 355 | if (FAILED(hr)) | ||
| 356 | { | ||
| 357 | hr = ShelExecUnelevated(sczBurnPath, sczParameters, L"open", NULL, nCmdShow); | ||
| 358 | if (FAILED(hr)) | ||
| 359 | { | ||
| 360 | hr = ShelExec(sczBurnPath, sczParameters, L"open", NULL, nCmdShow, NULL, NULL); | ||
| 361 | ExitOnFailure(hr, "Failed to launch parent process: %ls", sczBurnPath); | ||
| 362 | } | ||
| 363 | } | ||
| 364 | } | ||
| 365 | #else | ||
| 366 | hr = ProcExec(sczBurnPath, sczParameters, nCmdShow, &hProcess); | ||
| 367 | ExitOnFailure(hr, "Failed to launch parent process with unelevate disabled: %ls", sczBurnPath); | ||
| 368 | #endif | ||
| 369 | |||
| 370 | LExit: | ||
| 371 | ReleaseHandle(hProcess); | ||
| 372 | ReleaseStr(sczParameters); | ||
| 373 | ReleaseStr(sczBurnPath); | ||
| 374 | |||
| 375 | return hr; | ||
| 376 | } | ||
| 377 | |||
| 378 | /******************************************************************* | ||
| 379 | PipeLaunchChildProcess - Called from the per-user process to create | ||
| 380 | the per-machine process and set up the | ||
| 381 | communication pipe. | ||
| 382 | |||
| 383 | *******************************************************************/ | ||
| 384 | extern "C" HRESULT PipeLaunchChildProcess( | ||
| 385 | __in_z LPCWSTR wzExecutablePath, | ||
| 386 | __in BURN_PIPE_CONNECTION* pConnection, | ||
| 387 | __in BOOL fElevate, | ||
| 388 | __in_opt HWND hwndParent | ||
| 389 | ) | ||
| 390 | { | ||
| 391 | HRESULT hr = S_OK; | ||
| 392 | DWORD dwCurrentProcessId = ::GetCurrentProcessId(); | ||
| 393 | LPWSTR sczParameters = NULL; | ||
| 394 | LPCWSTR wzVerb = NULL; | ||
| 395 | HANDLE hProcess = NULL; | ||
| 396 | |||
| 397 | hr = StrAllocFormatted(&sczParameters, L"-q -%ls %ls %ls %u", BURN_COMMANDLINE_SWITCH_ELEVATED, pConnection->sczName, pConnection->sczSecret, dwCurrentProcessId); | ||
| 398 | ExitOnFailure(hr, "Failed to allocate parameters for elevated process."); | ||
| 399 | |||
| 400 | wzVerb = !fElevate ? L"open" : L"runas"; | ||
| 401 | |||
| 402 | // Since ShellExecuteEx doesn't support passing inherited handles, don't bother with CoreAppendFileHandleSelfToCommandLine. | ||
| 403 | // We could fallback to using ::DuplicateHandle to inject the file handle later if necessary. | ||
| 404 | hr = ShelExec(wzExecutablePath, sczParameters, wzVerb, NULL, SW_SHOWNA, hwndParent, &hProcess); | ||
| 405 | ExitOnFailure(hr, "Failed to launch elevated child process: %ls", wzExecutablePath); | ||
| 406 | |||
| 407 | pConnection->dwProcessId = ::GetProcessId(hProcess); | ||
| 408 | pConnection->hProcess = hProcess; | ||
| 409 | hProcess = NULL; | ||
| 410 | |||
| 411 | LExit: | ||
| 412 | ReleaseHandle(hProcess); | ||
| 413 | ReleaseStr(sczParameters); | ||
| 414 | |||
| 415 | return hr; | ||
| 416 | } | ||
| 417 | |||
| 418 | /******************************************************************* | ||
| 419 | PipeWaitForChildConnect - | 317 | PipeWaitForChildConnect - |
| 420 | 318 | ||
| 421 | *******************************************************************/ | 319 | *******************************************************************/ |
diff --git a/src/burn/engine/pipe.h b/src/burn/engine/pipe.h index 429cd824..4ec6bfa2 100644 --- a/src/burn/engine/pipe.h +++ b/src/burn/engine/pipe.h | |||
| @@ -80,19 +80,6 @@ HRESULT PipeCreatePipes( | |||
| 80 | __in BOOL fCreateCachePipe, | 80 | __in BOOL fCreateCachePipe, |
| 81 | __out HANDLE* phEvent | 81 | __out HANDLE* phEvent |
| 82 | ); | 82 | ); |
| 83 | HRESULT PipeLaunchParentProcess( | ||
| 84 | __in LPCWSTR wzCommandLine, | ||
| 85 | __in int nCmdShow, | ||
| 86 | __in_z LPWSTR sczConnectionName, | ||
| 87 | __in_z LPWSTR sczSecret, | ||
| 88 | __in BOOL fDisableUnelevate | ||
| 89 | ); | ||
| 90 | HRESULT PipeLaunchChildProcess( | ||
| 91 | __in_z LPCWSTR wzExecutablePath, | ||
| 92 | __in BURN_PIPE_CONNECTION* pConnection, | ||
| 93 | __in BOOL fElevate, | ||
| 94 | __in_opt HWND hwndParent | ||
| 95 | ); | ||
| 96 | HRESULT PipeWaitForChildConnect( | 83 | HRESULT PipeWaitForChildConnect( |
| 97 | __in BURN_PIPE_CONNECTION* pConnection | 84 | __in BURN_PIPE_CONNECTION* pConnection |
| 98 | ); | 85 | ); |
diff --git a/src/burn/test/BurnUnitTest/ElevationTest.cpp b/src/burn/test/BurnUnitTest/ElevationTest.cpp index 3d144128..97d76b7d 100644 --- a/src/burn/test/BurnUnitTest/ElevationTest.cpp +++ b/src/burn/test/BurnUnitTest/ElevationTest.cpp | |||
| @@ -52,38 +52,33 @@ namespace Bootstrapper | |||
| 52 | void ElevateTest() | 52 | void ElevateTest() |
| 53 | { | 53 | { |
| 54 | HRESULT hr = S_OK; | 54 | HRESULT hr = S_OK; |
| 55 | BURN_PIPE_CONNECTION connection = { }; | 55 | BURN_ENGINE_STATE engineState = { }; |
| 56 | BURN_PIPE_CONNECTION* pConnection = &engineState.companionConnection; | ||
| 56 | HANDLE hEvent = NULL; | 57 | HANDLE hEvent = NULL; |
| 57 | DWORD dwResult = S_OK; | 58 | DWORD dwResult = S_OK; |
| 59 | |||
| 60 | engineState.sczBundleEngineWorkingPath = L"tests\\ignore\\this\\path\\to\\burn.exe"; | ||
| 61 | |||
| 58 | try | 62 | try |
| 59 | { | 63 | { |
| 60 | ShelFunctionOverride(ElevateTest_ShellExecuteExW); | 64 | ShelFunctionOverride(ElevateTest_ShellExecuteExW); |
| 61 | 65 | ||
| 62 | PipeConnectionInitialize(&connection); | 66 | PipeConnectionInitialize(pConnection); |
| 63 | 67 | ||
| 64 | // | 68 | // |
| 65 | // per-user side setup | 69 | // per-user side setup |
| 66 | // | 70 | // |
| 67 | hr = PipeCreateNameAndSecret(&connection.sczName, &connection.sczSecret); | 71 | hr = ElevationElevate(&engineState, NULL); |
| 68 | TestThrowOnFailure(hr, L"Failed to create connection name and secret."); | 72 | TestThrowOnFailure(hr, L"Failed to elevate."); |
| 69 | |||
| 70 | hr = PipeCreatePipes(&connection, TRUE, &hEvent); | ||
| 71 | TestThrowOnFailure(hr, L"Failed to create pipes."); | ||
| 72 | |||
| 73 | hr = PipeLaunchChildProcess(L"tests\\ignore\\this\\path\\to\\burn.exe", &connection, TRUE, NULL); | ||
| 74 | TestThrowOnFailure(hr, L"Failed to create elevated process."); | ||
| 75 | |||
| 76 | hr = PipeWaitForChildConnect(&connection); | ||
| 77 | TestThrowOnFailure(hr, L"Failed to wait for child process to connect."); | ||
| 78 | 73 | ||
| 79 | // post execute message | 74 | // post execute message |
| 80 | hr = PipeSendMessage(connection.hPipe, TEST_PARENT_SENT_MESSAGE_ID, NULL, 0, ProcessParentMessages, NULL, &dwResult); | 75 | hr = PipeSendMessage(pConnection->hPipe, TEST_PARENT_SENT_MESSAGE_ID, NULL, 0, ProcessParentMessages, NULL, &dwResult); |
| 81 | TestThrowOnFailure(hr, "Failed to post execute message to per-machine process."); | 76 | TestThrowOnFailure(hr, "Failed to post execute message to per-machine process."); |
| 82 | 77 | ||
| 83 | // | 78 | // |
| 84 | // initiate termination | 79 | // initiate termination |
| 85 | // | 80 | // |
| 86 | hr = PipeTerminateChildProcess(&connection, 666, FALSE); | 81 | hr = PipeTerminateChildProcess(pConnection, 666, FALSE); |
| 87 | TestThrowOnFailure(hr, L"Failed to terminate elevated process."); | 82 | TestThrowOnFailure(hr, L"Failed to terminate elevated process."); |
| 88 | 83 | ||
| 89 | // check flags | 84 | // check flags |
| @@ -91,7 +86,7 @@ namespace Bootstrapper | |||
| 91 | } | 86 | } |
| 92 | finally | 87 | finally |
| 93 | { | 88 | { |
| 94 | PipeConnectionUninitialize(&connection); | 89 | PipeConnectionUninitialize(pConnection); |
| 95 | ReleaseHandle(hEvent); | 90 | ReleaseHandle(hEvent); |
| 96 | } | 91 | } |
| 97 | } | 92 | } |
