diff options
Diffstat (limited to 'src/burn/engine/engine.cpp')
| -rw-r--r-- | src/burn/engine/engine.cpp | 152 |
1 files changed, 52 insertions, 100 deletions
diff --git a/src/burn/engine/engine.cpp b/src/burn/engine/engine.cpp index 9c8b6c1d..89082a88 100644 --- a/src/burn/engine/engine.cpp +++ b/src/burn/engine/engine.cpp | |||
| @@ -3,15 +3,6 @@ | |||
| 3 | #include "precomp.h" | 3 | #include "precomp.h" |
| 4 | 4 | ||
| 5 | 5 | ||
| 6 | typedef struct _REDIRECTED_LOGGING_CONTEXT | ||
| 7 | { | ||
| 8 | CRITICAL_SECTION csBuffer; | ||
| 9 | LPSTR sczBuffer; | ||
| 10 | HANDLE hPipe; | ||
| 11 | HANDLE hLogEvent; | ||
| 12 | HANDLE hFinishedEvent; | ||
| 13 | } REDIRECTED_LOGGING_CONTEXT; | ||
| 14 | |||
| 15 | // constants | 6 | // constants |
| 16 | 7 | ||
| 17 | const DWORD RESTART_RETRIES = 10; | 8 | const DWORD RESTART_RETRIES = 10; |
| @@ -65,13 +56,6 @@ static HRESULT LogStringOverPipe( | |||
| 65 | static DWORD WINAPI ElevatedLoggingThreadProc( | 56 | static DWORD WINAPI ElevatedLoggingThreadProc( |
| 66 | __in LPVOID lpThreadParameter | 57 | __in LPVOID lpThreadParameter |
| 67 | ); | 58 | ); |
| 68 | static HRESULT WaitForElevatedLoggingThread( | ||
| 69 | __in REDIRECTED_LOGGING_CONTEXT* pContext, | ||
| 70 | __in HANDLE hLoggingThread | ||
| 71 | ); | ||
| 72 | static HRESULT WaitForUnelevatedLoggingThread( | ||
| 73 | __in HANDLE hUnelevatedLoggingThread | ||
| 74 | ); | ||
| 75 | static HRESULT Restart( | 59 | static HRESULT Restart( |
| 76 | __in BURN_ENGINE_STATE* pEngineState | 60 | __in BURN_ENGINE_STATE* pEngineState |
| 77 | ); | 61 | ); |
| @@ -308,10 +292,6 @@ LExit: | |||
| 308 | { | 292 | { |
| 309 | LogId(REPORT_STANDARD, MSG_EXITING_RUN_ONCE, FAILED(hr) ? (int)hr : *pdwExitCode); | 293 | LogId(REPORT_STANDARD, MSG_EXITING_RUN_ONCE, FAILED(hr) ? (int)hr : *pdwExitCode); |
| 310 | } | 294 | } |
| 311 | else if (fRunElevated) | ||
| 312 | { | ||
| 313 | LogId(REPORT_STANDARD, MSG_EXITING_ELEVATED, FAILED(hr) ? (int)hr : *pdwExitCode); | ||
| 314 | } | ||
| 315 | 295 | ||
| 316 | if (fLogInitialized) | 296 | if (fLogInitialized) |
| 317 | { | 297 | { |
| @@ -320,7 +300,12 @@ LExit: | |||
| 320 | LogFlush(); | 300 | LogFlush(); |
| 321 | } | 301 | } |
| 322 | 302 | ||
| 323 | if (engineState.fRestart) | 303 | // end per-machine process if running |
| 304 | if (!fRunElevated && INVALID_HANDLE_VALUE != engineState.companionConnection.hPipe) | ||
| 305 | { | ||
| 306 | PipeTerminateChildProcess(&engineState.companionConnection, *pdwExitCode, engineState.fRestart); | ||
| 307 | } | ||
| 308 | else if (engineState.fRestart) | ||
| 324 | { | 309 | { |
| 325 | LogId(REPORT_STANDARD, MSG_RESTARTING); | 310 | LogId(REPORT_STANDARD, MSG_RESTARTING); |
| 326 | 311 | ||
| @@ -334,6 +319,30 @@ LExit: | |||
| 334 | // If the message window is still around, close it. | 319 | // If the message window is still around, close it. |
| 335 | UiCloseMessageWindow(&engineState); | 320 | UiCloseMessageWindow(&engineState); |
| 336 | 321 | ||
| 322 | // If the logging thread is still around, close it. | ||
| 323 | if (!fRunElevated) | ||
| 324 | { | ||
| 325 | CoreWaitForUnelevatedLoggingThread(engineState.hUnelevatedLoggingThread); | ||
| 326 | } | ||
| 327 | else if (fRunElevated) | ||
| 328 | { | ||
| 329 | CoreCloseElevatedLoggingThread(&engineState); | ||
| 330 | |||
| 331 | // We're done talking to the child so always reset logging now. | ||
| 332 | LogRedirect(NULL, NULL); | ||
| 333 | |||
| 334 | // If there was a log message left, try to log it locally. | ||
| 335 | if (engineState.elevatedLoggingContext.sczBuffer) | ||
| 336 | { | ||
| 337 | LogStringWorkRaw(engineState.elevatedLoggingContext.sczBuffer); | ||
| 338 | |||
| 339 | ReleaseStr(engineState.elevatedLoggingContext.sczBuffer); | ||
| 340 | } | ||
| 341 | |||
| 342 | // Log the exit code here to make sure it gets in the elevated log. | ||
| 343 | LogId(REPORT_STANDARD, MSG_EXITING_ELEVATED, FAILED(hr) ? (int)hr : *pdwExitCode); | ||
| 344 | } | ||
| 345 | |||
| 337 | UninitializeEngineState(&engineState); | 346 | UninitializeEngineState(&engineState); |
| 338 | 347 | ||
| 339 | if (fXmlInitialized) | 348 | if (fXmlInitialized) |
| @@ -387,7 +396,12 @@ static HRESULT InitializeEngineState( | |||
| 387 | HANDLE hSectionFile = hEngineFile; | 396 | HANDLE hSectionFile = hEngineFile; |
| 388 | HANDLE hSourceEngineFile = INVALID_HANDLE_VALUE; | 397 | HANDLE hSourceEngineFile = INVALID_HANDLE_VALUE; |
| 389 | 398 | ||
| 399 | pEngineState->hUnelevatedLoggingThread = INVALID_HANDLE_VALUE; | ||
| 400 | pEngineState->elevatedLoggingContext.hPipe = INVALID_HANDLE_VALUE; | ||
| 401 | pEngineState->elevatedLoggingContext.hThread = INVALID_HANDLE_VALUE; | ||
| 402 | |||
| 390 | ::InitializeCriticalSection(&pEngineState->csRestartState); | 403 | ::InitializeCriticalSection(&pEngineState->csRestartState); |
| 404 | ::InitializeCriticalSection(&pEngineState->elevatedLoggingContext.csBuffer); | ||
| 391 | 405 | ||
| 392 | pEngineState->internalCommand.automaticUpdates = BURN_AU_PAUSE_ACTION_IFELEVATED; | 406 | pEngineState->internalCommand.automaticUpdates = BURN_AU_PAUSE_ACTION_IFELEVATED; |
| 393 | ::InitializeCriticalSection(&pEngineState->userExperience.csEngineActive); | 407 | ::InitializeCriticalSection(&pEngineState->userExperience.csEngineActive); |
| @@ -423,6 +437,12 @@ static void UninitializeEngineState( | |||
| 423 | ReleaseMem(pEngineState->internalCommand.rgSecretArgs); | 437 | ReleaseMem(pEngineState->internalCommand.rgSecretArgs); |
| 424 | ReleaseMem(pEngineState->internalCommand.rgUnknownArgs); | 438 | ReleaseMem(pEngineState->internalCommand.rgUnknownArgs); |
| 425 | 439 | ||
| 440 | ReleaseFileHandle(pEngineState->hUnelevatedLoggingThread); | ||
| 441 | ReleaseFileHandle(pEngineState->elevatedLoggingContext.hThread); | ||
| 442 | ::DeleteCriticalSection(&pEngineState->elevatedLoggingContext.csBuffer); | ||
| 443 | ReleaseHandle(pEngineState->elevatedLoggingContext.hLogEvent); | ||
| 444 | ReleaseHandle(pEngineState->elevatedLoggingContext.hFinishedEvent); | ||
| 445 | |||
| 426 | PipeConnectionUninitialize(&pEngineState->embeddedConnection); | 446 | PipeConnectionUninitialize(&pEngineState->embeddedConnection); |
| 427 | PipeConnectionUninitialize(&pEngineState->companionConnection); | 447 | PipeConnectionUninitialize(&pEngineState->companionConnection); |
| 428 | ReleaseStr(pEngineState->sczBundleEngineWorkingPath) | 448 | ReleaseStr(pEngineState->sczBundleEngineWorkingPath) |
| @@ -643,14 +663,6 @@ LExit: | |||
| 643 | 663 | ||
| 644 | VariablesDump(&pEngineState->variables); | 664 | VariablesDump(&pEngineState->variables); |
| 645 | 665 | ||
| 646 | // end per-machine process if running | ||
| 647 | if (INVALID_HANDLE_VALUE != pEngineState->companionConnection.hPipe) | ||
| 648 | { | ||
| 649 | PipeTerminateChildProcess(&pEngineState->companionConnection, pEngineState->userExperience.dwExitCode, FALSE); | ||
| 650 | |||
| 651 | WaitForUnelevatedLoggingThread(pEngineState->hUnelevatedLoggingThread); | ||
| 652 | } | ||
| 653 | |||
| 654 | // If the splash screen is still around, close it. | 666 | // If the splash screen is still around, close it. |
| 655 | if (::IsWindow(pEngineState->command.hwndSplashScreen)) | 667 | if (::IsWindow(pEngineState->command.hwndSplashScreen)) |
| 656 | { | 668 | { |
| @@ -671,9 +683,7 @@ static HRESULT RunElevated( | |||
| 671 | { | 683 | { |
| 672 | HRESULT hr = S_OK; | 684 | HRESULT hr = S_OK; |
| 673 | HANDLE hLock = NULL; | 685 | HANDLE hLock = NULL; |
| 674 | HANDLE hLoggingThread = NULL; | 686 | BURN_REDIRECTED_LOGGING_CONTEXT* pLoggingContext = &pEngineState->elevatedLoggingContext; |
| 675 | REDIRECTED_LOGGING_CONTEXT loggingContext = { }; | ||
| 676 | BOOL fDeleteLoggingCs = FALSE; | ||
| 677 | 687 | ||
| 678 | // Initialize logging. | 688 | // Initialize logging. |
| 679 | hr = LoggingOpen(&pEngineState->log, &pEngineState->internalCommand, &pEngineState->command, &pEngineState->variables, pEngineState->registration.sczDisplayName); | 689 | hr = LoggingOpen(&pEngineState->log, &pEngineState->internalCommand, &pEngineState->command, &pEngineState->variables, pEngineState->registration.sczDisplayName); |
| @@ -685,21 +695,18 @@ static HRESULT RunElevated( | |||
| 685 | 695 | ||
| 686 | // Set up the context for the logging thread then | 696 | // Set up the context for the logging thread then |
| 687 | // override logging to write over the pipe. | 697 | // override logging to write over the pipe. |
| 688 | ::InitializeCriticalSection(&loggingContext.csBuffer); | 698 | pLoggingContext->hLogEvent = ::CreateEventW(NULL, TRUE, FALSE, NULL); |
| 689 | fDeleteLoggingCs = TRUE; | 699 | ExitOnNullWithLastError(pLoggingContext->hLogEvent, hr, "Failed to create log event for logging thread."); |
| 690 | |||
| 691 | loggingContext.hLogEvent = ::CreateEventW(NULL, TRUE, FALSE, NULL); | ||
| 692 | ExitOnNullWithLastError(loggingContext.hLogEvent, hr, "Failed to create log event for logging thread."); | ||
| 693 | 700 | ||
| 694 | loggingContext.hFinishedEvent = ::CreateEventW(NULL, TRUE, FALSE, NULL); | 701 | pLoggingContext->hFinishedEvent = ::CreateEventW(NULL, TRUE, FALSE, NULL); |
| 695 | ExitOnNullWithLastError(loggingContext.hFinishedEvent, hr, "Failed to create finished event for logging thread."); | 702 | ExitOnNullWithLastError(pLoggingContext->hFinishedEvent, hr, "Failed to create finished event for logging thread."); |
| 696 | 703 | ||
| 697 | loggingContext.hPipe = pEngineState->companionConnection.hLoggingPipe; | 704 | pLoggingContext->hPipe = pEngineState->companionConnection.hLoggingPipe; |
| 698 | 705 | ||
| 699 | hLoggingThread = ::CreateThread(NULL, 0, ElevatedLoggingThreadProc, &loggingContext, 0, NULL); | 706 | pLoggingContext->hThread = ::CreateThread(NULL, 0, ElevatedLoggingThreadProc, pLoggingContext, 0, NULL); |
| 700 | ExitOnNullWithLastError(hLoggingThread, hr, "Failed to create elevated logging thread."); | 707 | ExitOnNullWithLastError(pLoggingContext->hThread, hr, "Failed to create elevated logging thread."); |
| 701 | 708 | ||
| 702 | LogRedirect(RedirectLoggingOverPipe, &loggingContext); | 709 | LogRedirect(RedirectLoggingOverPipe, pLoggingContext); |
| 703 | 710 | ||
| 704 | if (!pEngineState->internalCommand.fInitiallyElevated) | 711 | if (!pEngineState->internalCommand.fInitiallyElevated) |
| 705 | { | 712 | { |
| @@ -716,29 +723,7 @@ static HRESULT RunElevated( | |||
| 716 | hr = ElevationChildPumpMessages(pEngineState->companionConnection.hPipe, pEngineState->companionConnection.hCachePipe, &pEngineState->approvedExes, &pEngineState->cache, &pEngineState->containers, &pEngineState->packages, &pEngineState->payloads, &pEngineState->variables, &pEngineState->registration, &pEngineState->userExperience, &hLock, &pEngineState->userExperience.dwExitCode, &pEngineState->fRestart, &pEngineState->plan.fApplying); | 723 | hr = ElevationChildPumpMessages(pEngineState->companionConnection.hPipe, pEngineState->companionConnection.hCachePipe, &pEngineState->approvedExes, &pEngineState->cache, &pEngineState->containers, &pEngineState->packages, &pEngineState->payloads, &pEngineState->variables, &pEngineState->registration, &pEngineState->userExperience, &hLock, &pEngineState->userExperience.dwExitCode, &pEngineState->fRestart, &pEngineState->plan.fApplying); |
| 717 | ExitOnFailure(hr, "Failed to pump messages from parent process."); | 724 | ExitOnFailure(hr, "Failed to pump messages from parent process."); |
| 718 | 725 | ||
| 719 | WaitForElevatedLoggingThread(&loggingContext, hLoggingThread); | ||
| 720 | |||
| 721 | LExit: | 726 | LExit: |
| 722 | ReleaseHandle(hLoggingThread); | ||
| 723 | |||
| 724 | LogRedirect(NULL, NULL); // we're done talking to the child so always reset logging now. | ||
| 725 | |||
| 726 | if (fDeleteLoggingCs) | ||
| 727 | { | ||
| 728 | ::DeleteCriticalSection(&loggingContext.csBuffer); | ||
| 729 | } | ||
| 730 | |||
| 731 | ReleaseHandle(loggingContext.hLogEvent); | ||
| 732 | ReleaseHandle(loggingContext.hFinishedEvent); | ||
| 733 | |||
| 734 | // If there was a log message left, try to log it locally. | ||
| 735 | if (loggingContext.sczBuffer) | ||
| 736 | { | ||
| 737 | LogStringWorkRaw(loggingContext.sczBuffer); | ||
| 738 | |||
| 739 | ReleaseStr(loggingContext.sczBuffer); | ||
| 740 | } | ||
| 741 | |||
| 742 | if (hLock) | 727 | if (hLock) |
| 743 | { | 728 | { |
| 744 | ::ReleaseMutex(hLock); | 729 | ::ReleaseMutex(hLock); |
| @@ -936,7 +921,7 @@ static HRESULT DAPI RedirectLoggingOverPipe( | |||
| 936 | ) | 921 | ) |
| 937 | { | 922 | { |
| 938 | HRESULT hr = S_OK; | 923 | HRESULT hr = S_OK; |
| 939 | REDIRECTED_LOGGING_CONTEXT* pContext = static_cast<REDIRECTED_LOGGING_CONTEXT*>(pvContext); | 924 | BURN_REDIRECTED_LOGGING_CONTEXT* pContext = static_cast<BURN_REDIRECTED_LOGGING_CONTEXT*>(pvContext); |
| 940 | 925 | ||
| 941 | ::EnterCriticalSection(&pContext->csBuffer); | 926 | ::EnterCriticalSection(&pContext->csBuffer); |
| 942 | 927 | ||
| @@ -986,7 +971,7 @@ static DWORD WINAPI ElevatedLoggingThreadProc( | |||
| 986 | { | 971 | { |
| 987 | HRESULT hr = S_OK; | 972 | HRESULT hr = S_OK; |
| 988 | DWORD dwLastError = ERROR_SUCCESS; | 973 | DWORD dwLastError = ERROR_SUCCESS; |
| 989 | REDIRECTED_LOGGING_CONTEXT* pContext = static_cast<REDIRECTED_LOGGING_CONTEXT*>(lpThreadParameter); | 974 | BURN_REDIRECTED_LOGGING_CONTEXT* pContext = static_cast<BURN_REDIRECTED_LOGGING_CONTEXT*>(lpThreadParameter); |
| 990 | DWORD dwSignaledIndex = 0; | 975 | DWORD dwSignaledIndex = 0; |
| 991 | LPSTR sczBuffer = NULL; | 976 | LPSTR sczBuffer = NULL; |
| 992 | BURN_PIPE_RESULT result = { }; | 977 | BURN_PIPE_RESULT result = { }; |
| @@ -1079,39 +1064,6 @@ LExit: | |||
| 1079 | return (DWORD)hr; | 1064 | return (DWORD)hr; |
| 1080 | } | 1065 | } |
| 1081 | 1066 | ||
| 1082 | static HRESULT WaitForElevatedLoggingThread( | ||
| 1083 | __in REDIRECTED_LOGGING_CONTEXT* pContext, | ||
| 1084 | __in HANDLE hLoggingThread | ||
| 1085 | ) | ||
| 1086 | { | ||
| 1087 | HRESULT hr = S_OK; | ||
| 1088 | |||
| 1089 | if (!::SetEvent(pContext->hFinishedEvent)) | ||
| 1090 | { | ||
| 1091 | ExitWithLastError(hr, "Failed to set log finished event."); | ||
| 1092 | } | ||
| 1093 | |||
| 1094 | hr = AppWaitForSingleObject(hLoggingThread, 5 * 60 * 1000); // TODO: is 5 minutes good? | ||
| 1095 | ExitOnFailure(hr, "Failed to wait for elevated logging thread."); | ||
| 1096 | |||
| 1097 | LExit: | ||
| 1098 | return hr; | ||
| 1099 | } | ||
| 1100 | |||
| 1101 | static HRESULT WaitForUnelevatedLoggingThread( | ||
| 1102 | __in HANDLE hUnelevatedLoggingThread | ||
| 1103 | ) | ||
| 1104 | { | ||
| 1105 | HRESULT hr = S_OK; | ||
| 1106 | |||
| 1107 | // Give the thread 15 seconds to exit. | ||
| 1108 | hr = AppWaitForSingleObject(hUnelevatedLoggingThread, 15 * 1000); | ||
| 1109 | ExitOnFailure(hr, "Failed to wait for unelevated logging thread."); | ||
| 1110 | |||
| 1111 | LExit: | ||
| 1112 | return hr; | ||
| 1113 | } | ||
| 1114 | |||
| 1115 | static HRESULT Restart( | 1067 | static HRESULT Restart( |
| 1116 | __in BURN_ENGINE_STATE* pEngineState | 1068 | __in BURN_ENGINE_STATE* pEngineState |
| 1117 | ) | 1069 | ) |
