mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-26 19:33:31 +00:00
[SETUP:REACTOS] Improve Installation thread initialization and termination
- Improve install abort on errors; - Wait for the install thread to finish within the page that created it; - Display the hourglass cursor while waiting for the thread.
This commit is contained in:
+273
-107
@@ -36,6 +36,7 @@ PPARTENTRY SystemPartition = NULL;
|
||||
|
||||
/* UI elements */
|
||||
UI_CONTEXT UiContext;
|
||||
HCURSOR hWaitCursor;
|
||||
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
@@ -1713,7 +1714,7 @@ FileCopyCallback(PVOID Context,
|
||||
PCWSTR SrcFileName, DstFileName;
|
||||
|
||||
WaitForSingleObject(CopyContext->pSetupData->hHaltInstallEvent, INFINITE);
|
||||
if (CopyContext->pSetupData->bStopInstall)
|
||||
if (CopyContext->pSetupData->bAbortInstall)
|
||||
return FILEOP_ABORT; // Stop committing files
|
||||
|
||||
switch (Notification)
|
||||
@@ -1883,6 +1884,9 @@ PropSheet_SetCloseCancel(
|
||||
MF_BYCOMMAND | (Enable ? MF_ENABLED : MF_GRAYED));
|
||||
}
|
||||
|
||||
#define PM_INSTALL_START (WM_APP + 1)
|
||||
#define PM_INSTALL_DONE (WM_APP + 2)
|
||||
|
||||
static DWORD
|
||||
WINAPI
|
||||
PrepareAndDoCopyThread(
|
||||
@@ -1916,7 +1920,6 @@ PrepareAndDoCopyThread(
|
||||
/* Disable the Close/Cancel buttons during all partition operations */
|
||||
// TODO: Consider, alternatively, to just show an info-box saying
|
||||
// that the installation process cannot be canceled at this stage?
|
||||
// PropSheet_SetWizButtons(hWndParent, 0);
|
||||
PropSheet_SetCloseCancel(hWndParent, FALSE);
|
||||
|
||||
|
||||
@@ -1951,13 +1954,7 @@ PrepareAndDoCopyThread(
|
||||
|
||||
/* Re-enable the Close/Cancel buttons */
|
||||
PropSheet_SetCloseCancel(hWndParent, TRUE);
|
||||
|
||||
/*
|
||||
* We failed due to an unexpected error, keep on the copy page to view the current state,
|
||||
* but enable the "Next" button to allow the user to continue to the Abort page.
|
||||
*/
|
||||
PropSheet_SetWizButtons(hWndParent, PSWIZB_NEXT);
|
||||
return 1;
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
|
||||
@@ -1980,13 +1977,7 @@ PrepareAndDoCopyThread(
|
||||
|
||||
/* Re-enable the Close/Cancel buttons */
|
||||
PropSheet_SetCloseCancel(hWndParent, TRUE);
|
||||
|
||||
/*
|
||||
* We failed due to an unexpected error, keep on the copy page to view the current state,
|
||||
* but enable the "Next" button to allow the user to continue to the Abort page.
|
||||
*/
|
||||
PropSheet_SetWizButtons(hWndParent, PSWIZB_NEXT);
|
||||
return 1;
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
|
||||
@@ -1994,26 +1985,19 @@ PrepareAndDoCopyThread(
|
||||
PropSheet_SetCloseCancel(hWndParent, TRUE);
|
||||
|
||||
|
||||
|
||||
/* Re-calculate the final destination paths */
|
||||
ASSERT(InstallPartition);
|
||||
Status = InitDestinationPaths(&pSetupData->USetupData,
|
||||
NULL, // pSetupData->USetupData.InstallationDirectory,
|
||||
InstallVolume);
|
||||
if (!NT_SUCCESS(Status))
|
||||
Success = NT_SUCCESS(Status);
|
||||
if (!Success)
|
||||
{
|
||||
DisplayMessage(hWndParent, MB_ICONERROR, NULL, L"InitDestinationPaths() failed with status 0x%08lx\n", Status);
|
||||
|
||||
/*
|
||||
* We failed due to an unexpected error, keep on the copy page to view the current state,
|
||||
* but enable the "Next" button to allow the user to continue to the Abort page.
|
||||
*/
|
||||
PropSheet_SetWizButtons(hWndParent, PSWIZB_NEXT);
|
||||
return 1;
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Preparation of the list of files to be copied
|
||||
*/
|
||||
@@ -2039,17 +2023,9 @@ PrepareAndDoCopyThread(
|
||||
if (/*ErrorNumber != ERROR_SUCCESS*/ !Success)
|
||||
{
|
||||
/* Display an error only if an unexpected failure happened, and not because the user cancelled the installation */
|
||||
if (!pSetupData->bStopInstall)
|
||||
if (!pSetupData->bAbortInstall)
|
||||
MessageBoxW(hWndParent, L"Failed to prepare the list of files!", NULL, MB_ICONERROR);
|
||||
|
||||
/*
|
||||
* If we failed due to an unexpected error, keep on the copy page to view the current state,
|
||||
* but enable the "Next" button to allow the user to continue to the Abort page.
|
||||
* Otherwise we have been cancelled by the user, who has already switched to the Abort page.
|
||||
*/
|
||||
if (!pSetupData->bStopInstall)
|
||||
PropSheet_SetWizButtons(hWndParent, PSWIZB_NEXT);
|
||||
return 1;
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
|
||||
@@ -2069,20 +2045,13 @@ PrepareAndDoCopyThread(
|
||||
CopyContext.CompletedOperations = 0;
|
||||
|
||||
/* Do the file copying - The callback handles whether or not we should stop file copying */
|
||||
if (!DoFileCopy(&pSetupData->USetupData, FileCopyCallback, &CopyContext))
|
||||
Success = DoFileCopy(&pSetupData->USetupData, FileCopyCallback, &CopyContext);
|
||||
if (!Success)
|
||||
{
|
||||
/* Display an error only if an unexpected failure happened, and not because the user cancelled the installation */
|
||||
if (!pSetupData->bStopInstall)
|
||||
if (!pSetupData->bAbortInstall)
|
||||
MessageBoxW(hWndParent, L"Failed to copy the files!", NULL, MB_ICONERROR);
|
||||
|
||||
/*
|
||||
* If we failed due to an unexpected error, keep on the copy page to view the current state,
|
||||
* but enable the "Next" button to allow the user to continue to the Abort page.
|
||||
* Otherwise we have been cancelled by the user, who has already switched to the Abort page.
|
||||
*/
|
||||
if (!pSetupData->bStopInstall)
|
||||
PropSheet_SetWizButtons(hWndParent, PSWIZB_NEXT);
|
||||
return 1;
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
// /* Set status text */
|
||||
@@ -2095,6 +2064,11 @@ PrepareAndDoCopyThread(
|
||||
InstallSetupInfFile(&pSetupData->USetupData);
|
||||
|
||||
|
||||
/* Disable the Close/Cancel buttons for the remaining non-cancellable operations */
|
||||
// TODO: Consider, alternatively, to just show an info-box saying
|
||||
// that the installation process cannot be canceled at this stage?
|
||||
PropSheet_SetCloseCancel(hWndParent, FALSE);
|
||||
|
||||
/*
|
||||
* Create or update the registry hives
|
||||
*/
|
||||
@@ -2251,7 +2225,8 @@ PrepareAndDoCopyThread(
|
||||
IDS_ERROR_BOOTLDR_FAILED,
|
||||
Status);
|
||||
}
|
||||
break;
|
||||
Success = FALSE;
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
/* Skip installation */
|
||||
@@ -2260,12 +2235,14 @@ PrepareAndDoCopyThread(
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* We are done! Switch to the Finish page */
|
||||
PropSheet_SetCurSelByID(hWndParent, IDD_FINISHPAGE);
|
||||
return 0;
|
||||
Quit:
|
||||
/* Signal the wizard page that we have succeeded or failed */
|
||||
PostMessage(hwndDlg, PM_INSTALL_DONE, Success, 0); // Status
|
||||
return Success;
|
||||
}
|
||||
|
||||
// TODO: Determine later which method is the best.
|
||||
//#define TERMINATE_USE_PRESSBUTTON
|
||||
|
||||
static INT_PTR CALLBACK
|
||||
ProcessDlgProc(
|
||||
@@ -2294,6 +2271,16 @@ ProcessDlgProc(
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_SETCURSOR:
|
||||
{
|
||||
/* Set a page-wide cursor */
|
||||
if (!hWaitCursor)
|
||||
break;
|
||||
SetCursor(hWaitCursor);
|
||||
SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
LPNMHDR lpnm = (LPNMHDR)lParam;
|
||||
@@ -2304,83 +2291,256 @@ ProcessDlgProc(
|
||||
{
|
||||
HWND hWndParent = GetParent(hwndDlg);
|
||||
|
||||
/* Create the file-copy halt (manual-reset) event */
|
||||
pSetupData->hHaltInstallEvent = CreateEventW(NULL, TRUE, TRUE, NULL);
|
||||
if (!pSetupData->hHaltInstallEvent)
|
||||
break;
|
||||
pSetupData->bStopInstall = FALSE;
|
||||
/*
|
||||
* Disable all buttons during installation, and hide "Back" and "Next".
|
||||
* Don't use the PropSheet_SetWizButtons() macro, because its
|
||||
* posted message would be handled after hiding the buttons.
|
||||
* The message would then interfere with the hidden buttons
|
||||
* (when both "Back" and "Next" are hidden, "Next" gets forcefully shown).
|
||||
*/
|
||||
SendMessageW(hWndParent, PSM_SETWIZBUTTONS, 0, 0);
|
||||
// PropSheet_ShowWizButtons(hWndParent, 0, PSWIZB_BACK | PSWIZB_NEXT);
|
||||
ShowDlgItem(hWndParent, ID_WIZBACK, SW_HIDE);
|
||||
ShowDlgItem(hWndParent, ID_WIZNEXT, SW_HIDE);
|
||||
|
||||
/* Start the prepare-and-copy files thread */
|
||||
pSetupData->hInstallThread =
|
||||
CreateThread(NULL, 0,
|
||||
PrepareAndDoCopyThread,
|
||||
(PVOID)hwndDlg,
|
||||
CREATE_SUSPENDED,
|
||||
NULL);
|
||||
if (!pSetupData->hInstallThread)
|
||||
/* Start the installation procedure once the page is fully displayed */
|
||||
PostMessageW(hwndDlg, PM_INSTALL_START, 0, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
case PSN_KILLACTIVE:
|
||||
{
|
||||
/* Avoid reentrant calls caused by the message dispatching
|
||||
* done below: allow only the first page change, and ignore
|
||||
* all the others. */
|
||||
if (InterlockedFlagsTestAndSet8(&pSetupData->bStopInstall,
|
||||
SETUP_PAGE_SWITCHING))
|
||||
{
|
||||
CloseHandle(pSetupData->hHaltInstallEvent);
|
||||
pSetupData->hHaltInstallEvent = NULL;
|
||||
MessageBoxW(hWndParent, L"Cannot create the prepare-and-copy files thread!", NULL, MB_ICONERROR);
|
||||
break;
|
||||
SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Disable all buttons during installation, they will be
|
||||
* re-enabled by the installation thread; hide "Back" */
|
||||
PropSheet_SetWizButtons(hWndParent, 0);
|
||||
// PropSheet_ShowWizButtons(hWndParent, 0, PSWIZB_BACK);
|
||||
ShowDlgItem(hWndParent, ID_WIZBACK, SW_HIDE);
|
||||
/* If no installation is running, just change the page */
|
||||
if (!pSetupData->hInstallThread)
|
||||
break;
|
||||
|
||||
/* Resume the installation thread */
|
||||
ResumeThread(pSetupData->hInstallThread);
|
||||
/* Wait for the installation thread to terminate.
|
||||
* Since we dispatch messages in the meantime, we must
|
||||
* guard the property sheet notification handlers from
|
||||
* being invoked multiple times. */
|
||||
DWORD dwStatus = WaitForSingleObject(pSetupData->hInstallThread, 0);
|
||||
if (dwStatus == WAIT_TIMEOUT)
|
||||
{
|
||||
/* Show the hourglass cursor */
|
||||
HCURSOR hOldCursor;
|
||||
hWaitCursor = LoadCursor(NULL, IDC_WAIT);
|
||||
hOldCursor = SetCursor(hWaitCursor);
|
||||
ShowCursor(TRUE);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
MSG msg;
|
||||
dwStatus = MsgWaitForMultipleObjects(1, &pSetupData->hInstallThread,
|
||||
FALSE, INFINITE,
|
||||
QS_ALLINPUT | QS_ALLPOSTMESSAGE);
|
||||
if (dwStatus != (WAIT_OBJECT_0 + 1))
|
||||
break; // Stop if anything else (thread terminated, timeout or failure).
|
||||
|
||||
/* We still need to process main window messages to avoid freeze */
|
||||
while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageW(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore the old cursor */
|
||||
ShowCursor(FALSE);
|
||||
SetCursor(hOldCursor);
|
||||
hWaitCursor = NULL;
|
||||
}
|
||||
#if 0 && DBG
|
||||
if (dwStatus == WAIT_OBJECT_0)
|
||||
{
|
||||
DWORD dwExitCode = NO_ERROR;
|
||||
GetExitCodeThread(pSetupData->hInstallThread, &dwExitCode);
|
||||
DBG_UNREFERENCED_PARAMETER(dwExitCode);
|
||||
}
|
||||
#endif
|
||||
/* Cleanup; we can now change the page */
|
||||
CloseHandle(pSetupData->hInstallThread);
|
||||
pSetupData->hInstallThread = NULL;
|
||||
CloseHandle(pSetupData->hHaltInstallEvent);
|
||||
pSetupData->hHaltInstallEvent = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
case PSN_QUERYCANCEL:
|
||||
{
|
||||
/* Halt the on-going file copy */
|
||||
ResetEvent(pSetupData->hHaltInstallEvent);
|
||||
INT nRet;
|
||||
|
||||
if (DisplayMessage(GetParent(hwndDlg),
|
||||
MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2,
|
||||
MAKEINTRESOURCEW(IDS_ABORTSETUP2),
|
||||
MAKEINTRESOURCEW(IDS_ABORTSETUP)) == IDYES)
|
||||
if (pSetupData->bStopInstall)
|
||||
{
|
||||
/* Stop the file copy thread */
|
||||
pSetupData->bStopInstall = TRUE;
|
||||
SetEvent(pSetupData->hHaltInstallEvent);
|
||||
|
||||
#if 0
|
||||
/* Wait for any pending installation */
|
||||
WaitForSingleObject(pSetupData->hInstallThread, INFINITE);
|
||||
CloseHandle(pSetupData->hInstallThread);
|
||||
pSetupData->hInstallThread = NULL;
|
||||
CloseHandle(pSetupData->hHaltInstallEvent);
|
||||
pSetupData->hHaltInstallEvent = NULL;
|
||||
#endif
|
||||
|
||||
// TODO: Unwind installation?!
|
||||
|
||||
/* Go to the Abort page */
|
||||
PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_ABORTPAGE);
|
||||
/* The installation is terminating (either successfully,
|
||||
* or cancelled by the user or due to an error), ignore all
|
||||
* new requests since this is now too late to change bets. */
|
||||
nRet = IDYES;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We don't stop installation, resume file copy */
|
||||
/* Halt the on-going file copy */
|
||||
ResetEvent(pSetupData->hHaltInstallEvent);
|
||||
|
||||
nRet = DisplayMessage(GetParent(hwndDlg),
|
||||
MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2,
|
||||
MAKEINTRESOURCEW(IDS_ABORTSETUP2),
|
||||
MAKEINTRESOURCEW(IDS_ABORTSETUP));
|
||||
if (nRet == IDYES)
|
||||
{
|
||||
/* Signal the file copy thread to stop */
|
||||
InterlockedOr8((PCHAR)&pSetupData->bStopInstall, SETUP_ABORT_INSTALL);
|
||||
}
|
||||
/* else, we don't stop installation, resume file copy */
|
||||
SetEvent(pSetupData->hHaltInstallEvent);
|
||||
}
|
||||
|
||||
/* If we are not already in the process of cancelling
|
||||
* the installation or switching to a page, do it now. */
|
||||
if ((nRet == IDYES) && !pSetupData->bPageSwitching &&
|
||||
!InterlockedFlagsTestAndSet8(&pSetupData->bStopInstall,
|
||||
SETUP_IS_CANCELLING))
|
||||
{
|
||||
/* Go to the Abort page */
|
||||
#ifdef TERMINATE_USE_PRESSBUTTON
|
||||
PropSheet_SetCloseCancel(GetParent(hwndDlg), FALSE);
|
||||
PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_ABORTPAGE);
|
||||
#else
|
||||
PostMessageW(hwndDlg, PM_INSTALL_DONE, FALSE, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Do not close the wizard too soon */
|
||||
SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
case PSN_WIZBACK:
|
||||
/* Always disable going back */
|
||||
SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT, -1);
|
||||
return TRUE;
|
||||
|
||||
case PSN_WIZNEXT:
|
||||
{
|
||||
#ifdef TERMINATE_USE_PRESSBUTTON
|
||||
LONG_PTR nNextPage = (!pSetupData->bAbortInstall ? IDD_FINISHPAGE : IDD_ABORTPAGE);
|
||||
SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT, nNextPage);
|
||||
#else
|
||||
/* Always disable going next */
|
||||
SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT, -1);
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PM_INSTALL_START:
|
||||
{
|
||||
HWND hWndParent = GetParent(hwndDlg);
|
||||
|
||||
ASSERT(pSetupData->hInstallThread == NULL);
|
||||
|
||||
/* Force repainting first to make sure the wizard is visible */
|
||||
InvalidateRect(hWndParent, NULL, FALSE);
|
||||
UpdateWindow(hWndParent);
|
||||
|
||||
/* Create the file-copy halt (manual-reset) event */
|
||||
pSetupData->hHaltInstallEvent = CreateEventW(NULL, TRUE, TRUE, NULL);
|
||||
if (!pSetupData->hHaltInstallEvent)
|
||||
{
|
||||
DisplayMessage(hWndParent, MB_ICONERROR, NULL,
|
||||
L"Cannot create the install event, error %lu\n", GetLastError());
|
||||
goto Fail;
|
||||
}
|
||||
/* Start the installation thread */
|
||||
pSetupData->bStopInstall = FALSE;
|
||||
pSetupData->hInstallThread = CreateThread(NULL, 0,
|
||||
PrepareAndDoCopyThread,
|
||||
(PVOID)hwndDlg,
|
||||
0, NULL);
|
||||
if (!pSetupData->hInstallThread)
|
||||
{
|
||||
DisplayMessage(hWndParent, MB_ICONERROR, NULL,
|
||||
L"Cannot create the installation thread, error %lu\n", GetLastError());
|
||||
CloseHandle(pSetupData->hHaltInstallEvent);
|
||||
pSetupData->hHaltInstallEvent = NULL;
|
||||
Fail:
|
||||
/* Cancel the installation */
|
||||
InterlockedOr8((PCHAR)&pSetupData->bStopInstall, SETUP_ABORT_INSTALL);
|
||||
#ifdef TERMINATE_USE_PRESSBUTTON
|
||||
PropSheet_SetCloseCancel(hWndParent, FALSE);
|
||||
PropSheet_PressButton(hWndParent, PSBTN_CANCEL);
|
||||
#else
|
||||
SendMessageW(hwndDlg, PM_INSTALL_DONE, FALSE, 0);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PM_INSTALL_DONE:
|
||||
{
|
||||
HWND hWndParent = GetParent(hwndDlg);
|
||||
BOOL Success = !!wParam;
|
||||
BOOL AutoSwitchPage = TRUE;
|
||||
|
||||
/* If an unexpected error happened, stay on the copy page to allow
|
||||
* the user to view the current state, and keep the Close/Cancel
|
||||
* buttons to allow going to the Abort page.
|
||||
* Otherwise, we have been manually cancelled by the user and we
|
||||
* will directly switch to the Abort page. */
|
||||
if (!Success && !pSetupData->bStopInstall)
|
||||
{
|
||||
PropSheet_SetCloseCancel(hWndParent, TRUE);
|
||||
AutoSwitchPage = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable the Close/Cancel buttons, since the installation has
|
||||
* either successfully terminated, or was already cancelled by
|
||||
* the user. */
|
||||
PropSheet_SetCloseCancel(hWndParent, FALSE);
|
||||
}
|
||||
|
||||
if (!Success)
|
||||
{
|
||||
/* The installation was aborted */
|
||||
InterlockedOr8((PCHAR)&pSetupData->bStopInstall, SETUP_ABORT_INSTALL);
|
||||
}
|
||||
else if (pSetupData->bAbortInstall)
|
||||
{
|
||||
/* Override success in case the thread just terminated with some status
|
||||
* while at the same time, the user chose to cancel the installation */
|
||||
Success = FALSE;
|
||||
}
|
||||
|
||||
/* We are done! Switch to the Finish or the Abort page */
|
||||
if (!AutoSwitchPage)
|
||||
break;
|
||||
// TODO: if (!Success): Unwind installation.
|
||||
#ifdef TERMINATE_USE_PRESSBUTTON
|
||||
// NOTE: In this case, PSN_QUERYCANCEL **CANNOT** call PM_INSTALL_DONE
|
||||
PropSheet_PressButton(hWndParent, Success ? PSBTN_NEXT : PSBTN_CANCEL);
|
||||
#else
|
||||
if (!Success)
|
||||
InterlockedOr8((PCHAR)&pSetupData->bStopInstall, SETUP_IS_CANCELLING);
|
||||
PropSheet_SetCurSelByID(hWndParent, Success ? IDD_FINISHPAGE : IDD_ABORTPAGE);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -3298,6 +3458,19 @@ PrshtWndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_SETCURSOR:
|
||||
{
|
||||
/* Set a wizard-wide cursor */
|
||||
// NOTE: There is a problem, where when hovering over the wizard
|
||||
// navigation buttons, the cursor would blink with the arrow.
|
||||
// To mitigate this problem, only show the custom cursor when
|
||||
// we are on the main wizard window.
|
||||
if (!(hWaitCursor && (wParam == (WPARAM)hWnd)))
|
||||
break;
|
||||
SetCursor(hWaitCursor);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
case WM_DESTROY:
|
||||
{
|
||||
/* Restore the original dialog procedure */
|
||||
@@ -3538,13 +3711,6 @@ _tWinMain(HINSTANCE hInst,
|
||||
/* Display the wizard */
|
||||
PropertySheetW(&psh);
|
||||
|
||||
/* Wait for any pending installation */
|
||||
WaitForSingleObject(SetupData.hInstallThread, INFINITE);
|
||||
CloseHandle(SetupData.hInstallThread);
|
||||
SetupData.hInstallThread = NULL;
|
||||
CloseHandle(SetupData.hHaltInstallEvent);
|
||||
SetupData.hHaltInstallEvent = NULL;
|
||||
|
||||
if (SetupData.hBoldFont)
|
||||
DeleteFont(SetupData.hBoldFont);
|
||||
if (SetupData.hTitleFont)
|
||||
|
||||
@@ -115,6 +115,12 @@ typedef struct _KBLAYOUT
|
||||
} KBLAYOUT, *PKBLAYOUT;
|
||||
#endif
|
||||
|
||||
#define InterlockedFlagsTestAndSet8(Target, Flags) \
|
||||
!!(InterlockedOr8((PCHAR)(Target), (Flags)) & (Flags))
|
||||
|
||||
#define InterlockedFlagsTestAndReset8(Target, Flags) \
|
||||
!!(InterlockedAnd8((PCHAR)(Target), ~(Flags)) & (Flags))
|
||||
|
||||
typedef struct _SETUPDATA
|
||||
{
|
||||
/* General */
|
||||
@@ -127,7 +133,23 @@ typedef struct _SETUPDATA
|
||||
|
||||
HANDLE hInstallThread;
|
||||
HANDLE hHaltInstallEvent;
|
||||
BOOL bStopInstall;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
#define SETUP_ABORT_INSTALL 1
|
||||
UCHAR bAbortInstall :2; /**< TRUE if the installation is to be aborted;
|
||||
** FALSE if not (regular termination). */
|
||||
#define SETUP_IS_CANCELLING 4
|
||||
UCHAR bIsCancelling :2; /**< TRUE if the installation is being cancelled
|
||||
** (via PSN_QUERYCANCEL); FALSE if not. */
|
||||
#define SETUP_PAGE_SWITCHING 16
|
||||
UCHAR bPageSwitching :2; /**< TRUE if a page switch is occurring
|
||||
** (PSN_KILLACTIVE running); FALSE if not. */
|
||||
UCHAR bReserved :2;
|
||||
};
|
||||
BOOLEAN bStopInstall;
|
||||
};
|
||||
|
||||
NT_WIN32_PATH_MAPPING_LIST MappingList;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user