diff options
| author | Sean Hall <r.sean.hall@gmail.com> | 2022-09-02 16:11:35 -0500 |
|---|---|---|
| committer | Sean Hall <r.sean.hall@gmail.com> | 2022-09-03 15:29:26 -0500 |
| commit | eea6121f388197435529922b3cb13d3631afb9a8 (patch) | |
| tree | 5740f0ff69f7e4aa9a7e8a92ff1f6fde0c1ae8d7 /src/burn/engine/uithread.cpp | |
| parent | e263e6bca03d783ece2f2dc86345dcdfc4b9776d (diff) | |
| download | wix-eea6121f388197435529922b3cb13d3631afb9a8.tar.gz wix-eea6121f388197435529922b3cb13d3631afb9a8.tar.bz2 wix-eea6121f388197435529922b3cb13d3631afb9a8.zip | |
Delay closing Burn's UI thread so that it can log the bundle's restart.
Diffstat (limited to 'src/burn/engine/uithread.cpp')
| -rw-r--r-- | src/burn/engine/uithread.cpp | 62 |
1 files changed, 48 insertions, 14 deletions
diff --git a/src/burn/engine/uithread.cpp b/src/burn/engine/uithread.cpp index 26a9b723..673111f8 100644 --- a/src/burn/engine/uithread.cpp +++ b/src/burn/engine/uithread.cpp | |||
| @@ -46,6 +46,11 @@ HRESULT UiCreateMessageWindow( | |||
| 46 | HANDLE rgWaitHandles[2] = { }; | 46 | HANDLE rgWaitHandles[2] = { }; |
| 47 | UITHREAD_CONTEXT context = { }; | 47 | UITHREAD_CONTEXT context = { }; |
| 48 | 48 | ||
| 49 | // Try to make this process the first one to receive WM_QUERYENDSESSION. | ||
| 50 | // When blocking shutdown during Apply, this prevents other applications from being closed even though the restart will be blocked. | ||
| 51 | // When initiating a restart, this makes it reasonable to assume WM_QUERYENDSESSION will be received quickly because otherwise other applications could delay indefinitely. | ||
| 52 | ::SetProcessShutdownParameters(0x3FF, 0); | ||
| 53 | |||
| 49 | // Create event to signal after the UI thread / window is initialized. | 54 | // Create event to signal after the UI thread / window is initialized. |
| 50 | rgWaitHandles[0] = ::CreateEventW(NULL, TRUE, FALSE, NULL); | 55 | rgWaitHandles[0] = ::CreateEventW(NULL, TRUE, FALSE, NULL); |
| 51 | ExitOnNullWithLastError(rgWaitHandles[0], hr, "Failed to create initialization event."); | 56 | ExitOnNullWithLastError(rgWaitHandles[0], hr, "Failed to create initialization event."); |
| @@ -79,10 +84,6 @@ void UiCloseMessageWindow( | |||
| 79 | if (::IsWindow(pEngineState->hMessageWindow)) | 84 | if (::IsWindow(pEngineState->hMessageWindow)) |
| 80 | { | 85 | { |
| 81 | ::PostMessageW(pEngineState->hMessageWindow, WM_CLOSE, 0, 0); | 86 | ::PostMessageW(pEngineState->hMessageWindow, WM_CLOSE, 0, 0); |
| 82 | |||
| 83 | // Give the window 15 seconds to close because if it stays open it can prevent | ||
| 84 | // the engine from starting a reboot (should a reboot actually be necessary). | ||
| 85 | ::WaitForSingleObject(pEngineState->hMessageWindowThread, 15 * 1000); | ||
| 86 | } | 87 | } |
| 87 | } | 88 | } |
| 88 | 89 | ||
| @@ -180,23 +181,56 @@ static LRESULT CALLBACK WndProc( | |||
| 180 | 181 | ||
| 181 | case WM_QUERYENDSESSION: | 182 | case WM_QUERYENDSESSION: |
| 182 | { | 183 | { |
| 183 | DWORD dwEndSession = static_cast<DWORD>(lParam); | 184 | BOOL fCritical = ENDSESSION_CRITICAL & lParam; |
| 184 | BOOL fCritical = ENDSESSION_CRITICAL & dwEndSession; | 185 | BOOL fAllowed = FALSE; |
| 185 | BOOL fCancel = FALSE; | ||
| 186 | BOOL fRet = FALSE; | ||
| 187 | 186 | ||
| 188 | // Always block shutdown during apply. | ||
| 189 | UITHREAD_INFO* pInfo = reinterpret_cast<UITHREAD_INFO*>(::GetWindowLongPtrW(hWnd, GWLP_USERDATA)); | 187 | UITHREAD_INFO* pInfo = reinterpret_cast<UITHREAD_INFO*>(::GetWindowLongPtrW(hWnd, GWLP_USERDATA)); |
| 190 | if (pInfo->pEngineState->plan.fApplying) | 188 | if (!pInfo->pEngineState->plan.fApplying && // always block shutdown during apply. |
| 189 | !fCritical) // always block critical shutdowns to receive the WM_ENDSESSION message. | ||
| 191 | { | 190 | { |
| 192 | fCancel = TRUE; | 191 | fAllowed = TRUE; |
| 193 | } | 192 | } |
| 194 | 193 | ||
| 194 | CoreUpdateRestartState(pInfo->pEngineState, BURN_RESTART_STATE_INITIATING); | ||
| 195 | pInfo->pEngineState->fCriticalShutdownInitiated |= fCritical; | 195 | pInfo->pEngineState->fCriticalShutdownInitiated |= fCritical; |
| 196 | 196 | ||
| 197 | fRet = !fCancel; | 197 | LogId(REPORT_STANDARD, MSG_SYSTEM_SHUTDOWN_REQUEST, LoggingBoolToString(fAllowed), LoggingBoolToString(pInfo->fElevatedEngine), LoggingBoolToString(fCritical), LoggingBoolToString(lParam & ENDSESSION_LOGOFF), LoggingBoolToString(lParam & ENDSESSION_CLOSEAPP)); |
| 198 | LogId(REPORT_STANDARD, MSG_SYSTEM_SHUTDOWN, LoggingBoolToString(fCritical), LoggingBoolToString(pInfo->fElevatedEngine), LoggingBoolToString(fRet)); | 198 | LogFlush(); |
| 199 | return fRet; | 199 | return fAllowed; |
| 200 | } | ||
| 201 | |||
| 202 | case WM_ENDSESSION: | ||
| 203 | { | ||
| 204 | UITHREAD_INFO* pInfo = reinterpret_cast<UITHREAD_INFO*>(::GetWindowLongPtrW(hWnd, GWLP_USERDATA)); | ||
| 205 | BOOL fAllowed = 0 != wParam; | ||
| 206 | |||
| 207 | LogId(REPORT_STANDARD, MSG_SYSTEM_SHUTDOWN_RESULT, LoggingBoolToString(fAllowed), LoggingBoolToString(pInfo->fElevatedEngine), LoggingBoolToString(lParam & ENDSESSION_CRITICAL), LoggingBoolToString(lParam & ENDSESSION_LOGOFF), LoggingBoolToString(lParam & ENDSESSION_CLOSEAPP)); | ||
| 208 | |||
| 209 | if (fAllowed) | ||
| 210 | { | ||
| 211 | // Windows will shutdown the process as soon as we return from this message. | ||
| 212 | // https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms700677(v=vs.85) | ||
| 213 | |||
| 214 | // Give Apply approximately 20 seconds to complete. | ||
| 215 | for (DWORD i = 0; i < 80; ++i) | ||
| 216 | { | ||
| 217 | if (!pInfo->pEngineState->plan.fApplying) | ||
| 218 | { | ||
| 219 | break; | ||
| 220 | } | ||
| 221 | |||
| 222 | ::Sleep(250); | ||
| 223 | } | ||
| 224 | |||
| 225 | LogStringWorkRaw("=======================================\r\n"); | ||
| 226 | |||
| 227 | // Close the log to try to make sure everything is flushed to disk. | ||
| 228 | LogClose(FALSE); | ||
| 229 | } | ||
| 230 | |||
| 231 | CoreUpdateRestartState(pInfo->pEngineState, fAllowed ? BURN_RESTART_STATE_INITIATED : BURN_RESTART_STATE_BLOCKED); | ||
| 232 | |||
| 233 | return 0; | ||
| 200 | } | 234 | } |
| 201 | 235 | ||
| 202 | case WM_DESTROY: | 236 | case WM_DESTROY: |
