diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2022-09-02 16:12:26 -0500 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2022-09-03 15:29:26 -0500 |
commit | 7728e34e48a4fdb710ecc92dd8dca833bff3993f (patch) | |
tree | 83d9a6a5068985670dc47121d400fc7c491c23ec /src/burn | |
parent | eea6121f388197435529922b3cb13d3631afb9a8 (diff) | |
download | wix-7728e34e48a4fdb710ecc92dd8dca833bff3993f.tar.gz wix-7728e34e48a4fdb710ecc92dd8dca833bff3993f.tar.bz2 wix-7728e34e48a4fdb710ecc92dd8dca833bff3993f.zip |
Use elevated engine to make the restart request when it is available.
Fixes 6145
Diffstat (limited to 'src/burn')
-rw-r--r-- | src/burn/engine/core.cpp | 42 | ||||
-rw-r--r-- | src/burn/engine/core.h | 17 | ||||
-rw-r--r-- | src/burn/engine/engine.cpp | 152 | ||||
-rw-r--r-- | src/burn/engine/uithread.cpp | 10 |
4 files changed, 121 insertions, 100 deletions
diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp index 3c1ed117..c8dce17b 100644 --- a/src/burn/engine/core.cpp +++ b/src/burn/engine/core.cpp | |||
@@ -2028,6 +2028,48 @@ extern "C" HRESULT DAPI CoreWaitForProcCompletion( | |||
2028 | return vpfnProcWaitForCompletion(hProcess, dwTimeout, pdwReturnCode); | 2028 | return vpfnProcWaitForCompletion(hProcess, dwTimeout, pdwReturnCode); |
2029 | } | 2029 | } |
2030 | 2030 | ||
2031 | extern "C" HRESULT DAPI CoreCloseElevatedLoggingThread( | ||
2032 | __in BURN_ENGINE_STATE* pEngineState | ||
2033 | ) | ||
2034 | { | ||
2035 | HRESULT hr = S_OK; | ||
2036 | |||
2037 | if (INVALID_HANDLE_VALUE == pEngineState->elevatedLoggingContext.hThread) | ||
2038 | { | ||
2039 | ExitFunction(); | ||
2040 | } | ||
2041 | |||
2042 | if (!::SetEvent(pEngineState->elevatedLoggingContext.hFinishedEvent)) | ||
2043 | { | ||
2044 | ExitWithLastError(hr, "Failed to set log finished event."); | ||
2045 | } | ||
2046 | |||
2047 | hr = AppWaitForSingleObject(pEngineState->elevatedLoggingContext.hThread, 5 * 60 * 1000); // TODO: is 5 minutes good? | ||
2048 | ExitOnFailure(hr, "Failed to wait for elevated logging thread."); | ||
2049 | |||
2050 | LExit: | ||
2051 | return hr; | ||
2052 | } | ||
2053 | |||
2054 | extern "C" HRESULT DAPI CoreWaitForUnelevatedLoggingThread( | ||
2055 | __in HANDLE hUnelevatedLoggingThread | ||
2056 | ) | ||
2057 | { | ||
2058 | HRESULT hr = S_OK; | ||
2059 | |||
2060 | if (INVALID_HANDLE_VALUE == hUnelevatedLoggingThread) | ||
2061 | { | ||
2062 | ExitFunction(); | ||
2063 | } | ||
2064 | |||
2065 | // Give the thread 15 seconds to exit. | ||
2066 | hr = AppWaitForSingleObject(hUnelevatedLoggingThread, 15 * 1000); | ||
2067 | ExitOnFailure(hr, "Failed to wait for unelevated logging thread."); | ||
2068 | |||
2069 | LExit: | ||
2070 | return hr; | ||
2071 | } | ||
2072 | |||
2031 | // internal helper functions | 2073 | // internal helper functions |
2032 | 2074 | ||
2033 | static HRESULT AppendEscapedArgumentToCommandLine( | 2075 | static HRESULT AppendEscapedArgumentToCommandLine( |
diff --git a/src/burn/engine/core.h b/src/burn/engine/core.h index 28b5ba5d..812b40b1 100644 --- a/src/burn/engine/core.h +++ b/src/burn/engine/core.h | |||
@@ -123,6 +123,16 @@ typedef struct _BURN_ENGINE_COMMAND | |||
123 | LPWSTR sczLogFile; | 123 | LPWSTR sczLogFile; |
124 | } BURN_ENGINE_COMMAND; | 124 | } BURN_ENGINE_COMMAND; |
125 | 125 | ||
126 | typedef struct _BURN_REDIRECTED_LOGGING_CONTEXT | ||
127 | { | ||
128 | CRITICAL_SECTION csBuffer; | ||
129 | LPSTR sczBuffer; | ||
130 | HANDLE hPipe; | ||
131 | HANDLE hLogEvent; | ||
132 | HANDLE hFinishedEvent; | ||
133 | HANDLE hThread; | ||
134 | } BURN_REDIRECTED_LOGGING_CONTEXT; | ||
135 | |||
126 | typedef struct _BURN_ENGINE_STATE | 136 | typedef struct _BURN_ENGINE_STATE |
127 | { | 137 | { |
128 | // UX flow control | 138 | // UX flow control |
@@ -164,6 +174,7 @@ typedef struct _BURN_ENGINE_STATE | |||
164 | 174 | ||
165 | BURN_PLAN plan; | 175 | BURN_PLAN plan; |
166 | 176 | ||
177 | BURN_REDIRECTED_LOGGING_CONTEXT elevatedLoggingContext; | ||
167 | HANDLE hUnelevatedLoggingThread; | 178 | HANDLE hUnelevatedLoggingThread; |
168 | 179 | ||
169 | LPWSTR sczBundleEngineWorkingPath; | 180 | LPWSTR sczBundleEngineWorkingPath; |
@@ -336,6 +347,12 @@ HRESULT DAPI CoreWaitForProcCompletion( | |||
336 | __in DWORD dwTimeout, | 347 | __in DWORD dwTimeout, |
337 | __out_opt DWORD* pdwReturnCode | 348 | __out_opt DWORD* pdwReturnCode |
338 | ); | 349 | ); |
350 | HRESULT DAPI CoreCloseElevatedLoggingThread( | ||
351 | __in BURN_ENGINE_STATE* pEngineState | ||
352 | ); | ||
353 | HRESULT DAPI CoreWaitForUnelevatedLoggingThread( | ||
354 | __in HANDLE hUnelevatedLoggingThread | ||
355 | ); | ||
339 | 356 | ||
340 | #if defined(__cplusplus) | 357 | #if defined(__cplusplus) |
341 | } | 358 | } |
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 | ) |
diff --git a/src/burn/engine/uithread.cpp b/src/burn/engine/uithread.cpp index 673111f8..8ddd51bd 100644 --- a/src/burn/engine/uithread.cpp +++ b/src/burn/engine/uithread.cpp | |||
@@ -222,6 +222,16 @@ static LRESULT CALLBACK WndProc( | |||
222 | ::Sleep(250); | 222 | ::Sleep(250); |
223 | } | 223 | } |
224 | 224 | ||
225 | // If this is the per-machine process then close the logging pipe with the parent process. | ||
226 | if (pInfo->fElevatedEngine) | ||
227 | { | ||
228 | CoreCloseElevatedLoggingThread(pInfo->pEngineState); | ||
229 | } | ||
230 | else | ||
231 | { | ||
232 | CoreWaitForUnelevatedLoggingThread(pInfo->pEngineState->hUnelevatedLoggingThread); | ||
233 | } | ||
234 | |||
225 | LogStringWorkRaw("=======================================\r\n"); | 235 | LogStringWorkRaw("=======================================\r\n"); |
226 | 236 | ||
227 | // Close the log to try to make sure everything is flushed to disk. | 237 | // Close the log to try to make sure everything is flushed to disk. |