|
|
#include "precomp.h"
#pragma hdrstop
#define SETNEXTPAGE(x) *((LONG*)lParam) = x
extern HWND BackgroundWnd; extern HWND BackgroundWnd2;
static HANDLE g_Thread = NULL; static HANDLE g_Event = NULL;
//
// Prototypes
//
INT_PTR DynSetup_ManualDialog( IN HWND hdlg, IN UINT msg, IN WPARAM wParam, IN LPARAM lParam );
HANDLE pInitializeOnlineSeconds ( VOID );
DWORD pGetOnlineRemainingSeconds ( IN HANDLE Handle, IN DWORD DownloadedBytes, IN DWORD TotalBytesToDownload, OUT PDWORD KbPerSec OPTIONAL );
VOID pCheckRadioButtons ( IN HWND Hdlg, IN UINT ButtonToSelect, ... ) { va_list args; UINT u;
va_start (args, ButtonToSelect); while (u = va_arg (args, UINT)) { CheckDlgButton (Hdlg, u, u == ButtonToSelect ? BST_CHECKED : BST_UNCHECKED); } va_end (args); }
BOOL DynSetupWizPage( IN HWND hdlg, IN UINT msg, IN WPARAM wParam, IN LPARAM lParam ) /*++
Routine Description:
Dynamic Setup page 1 (choose to use dynamic updates) or just skip it if this happens after a restart
Arguments:
Standard window proc arguments.
Returns:
Message-dependent value.
--*/ { PPAGE_RUNTIME_DATA WizPage = (PPAGE_RUNTIME_DATA)GetWindowLongPtr(hdlg,DWLP_USER); BOOL fRetVal = FALSE;
switch(msg) {
case WM_INITDIALOG: pCheckRadioButtons (hdlg, g_DynUpdtStatus->DUStatus == DUS_INITIAL ? IDOK : IDCANCEL, IDOK, IDCANCEL); SetFocus(GetDlgItem(hdlg,IDOK)); break;
case WM_COMMAND: if(HIWORD(wParam) == BN_CLICKED) { if (LOWORD(wParam) == IDOK) { g_DynUpdtStatus->DUStatus = DUS_INITIAL; } else if (LOWORD(wParam) == IDCANCEL) { g_DynUpdtStatus->DUStatus = DUS_SKIP; } } fRetVal = TRUE; break;
case WMX_ACTIVATEPAGE: fRetVal = TRUE; if (wParam) { //
// don't activate the page in restart mode
//
if (Winnt32Restarted ()) { if (Winnt32RestartedWithAF ()) { GetPrivateProfileString( WINNT_UNATTENDED, WINNT_U_DYNAMICUPDATESHARE, TEXT(""), g_DynUpdtStatus->DynamicUpdatesSource, ARRAYSIZE(g_DynUpdtStatus->DynamicUpdatesSource), g_DynUpdtStatus->RestartAnswerFile ); } return FALSE; }
//
// skip this step if already successfully performed
//
if (g_DynUpdtStatus->DUStatus == DUS_SUCCESSFUL) { return FALSE; }
if (!g_DynUpdtStatus->Disabled && g_DynUpdtStatus->UserSpecifiedUpdates) { //
// go to the next page to start processing files
//
PropSheet_PressButton (GetParent (hdlg), PSBTN_NEXT); } else { if (g_DynUpdtStatus->Disabled || //
// skip if support is not available
//
!DynamicUpdateIsSupported (hdlg) ) { //
// skip page(s)
//
g_DynUpdtStatus->DUStatus = DUS_SKIP; pCheckRadioButtons (hdlg, IDCANCEL, IDOK, IDCANCEL); // Don't do press button next, This would cause the page to paint.
return( FALSE ); }
//
// in CheckUpgradeOnly mode, ask user if they want to connect to WU
//
if (UpgradeAdvisorMode || !CheckUpgradeOnly || UnattendSwitchSpecified) { if ((UpgradeAdvisorMode || UnattendedOperation) && !CancelPending) { PropSheet_PressButton (GetParent (hdlg), PSBTN_NEXT); break; } } if (CheckUpgradeOnly) { //
// disable the Back button in this case
//
PropSheet_SetWizButtons (GetParent(hdlg), WizPage->CommonData.Buttons & ~PSWIZB_BACK); } } }
Animate_Open(GetDlgItem(hdlg, IDC_ANIMATE), wParam ? MAKEINTRESOURCE(IDA_COMPGLOB) : NULL); break;
default:
break; }
return fRetVal; }
VOID pUpdateInfoText ( IN UINT InfoId ) { #define MAX_TEXT 256
TCHAR text[MAX_TEXT];
if (!LoadString (hInst, InfoId, text, ARRAYSIZE(text))) { text[0] = 0; } BB_SetInfoText (text); }
VOID pUpdateProgressText ( IN HWND Hdlg, IN UINT ProgressId, IN PCTSTR AppendText, OPTIONAL IN BOOL InsertNewLine ) { #define MAX_TEXT 256
TCHAR text[MAX_TEXT] = TEXT("");
if (Hdlg) { if (!GetDlgItemText (Hdlg, ProgressId, text, ARRAYSIZE(text))) { text[0] = 0; } } else { if (!LoadString (hInst, ProgressId, text, ARRAYSIZE(text))) { text[0] = 0; } } if (AppendText) { DWORD len = lstrlen (AppendText) + 1; if (len < ARRAYSIZE(text)) { if (InsertNewLine) { if (len + LENGTHOF("\r\n") < ARRAYSIZE(text)) { len += LENGTHOF("\r\n"); _tcsncat (text, TEXT("\r\n"), ARRAYSIZE(text) - len); } } _tcsncat (text, AppendText, ARRAYSIZE(text) - len); } } BB_SetProgressText (text); UpdateWindow (GetBBMainHwnd ()); }
VOID SetDlgItemTextBold ( IN HWND Hdlg, IN INT DlgItemID, IN BOOL Bold ) { HFONT font; LOGFONT logFont; LONG weight; DWORD id = 0;
font = (HFONT) SendDlgItemMessage (Hdlg, DlgItemID, WM_GETFONT, 0, 0); if (font && GetObject (font, sizeof(LOGFONT), &logFont)) { weight = Bold ? FW_BOLD : FW_NORMAL; if (weight != logFont.lfWeight) { logFont.lfWeight = weight; font = CreateFontIndirect (&logFont); if (font) { SendDlgItemMessage (Hdlg, DlgItemID, WM_SETFONT, (WPARAM)font, MAKELPARAM(TRUE,0)); } } } }
BOOL DynSetup2WizPage( IN HWND hdlg, IN UINT msg, IN WPARAM wParam, IN LPARAM lParam ) /*++
Routine Description:
Dynamic Setup page 2
Arguments:
Standard window proc arguments.
Returns:
Message-dependent value.
--*/ { PPAGE_RUNTIME_DATA WizPage = (PPAGE_RUNTIME_DATA)GetWindowLongPtr(hdlg,DWLP_USER); BOOL fRetVal = FALSE; PTSTR message; DWORD onlineRemainingSeconds; DWORD onlineRemainingMinutes; DWORD kbps; TCHAR buf[200]; DWORD estTime, estSize; HCURSOR hc; BOOL b; HANDLE hBitmap, hOld; DWORD tid; #ifdef DOWNLOAD_DETAILS
TCHAR buf2[200]; #endif
static BOOL DownloadPageActive = FALSE; static PTSTR msgToFormat = NULL; static HANDLE hComp = NULL; static BOOL CancelDownloadPending = FALSE; static BOOL ResumeWorkerThread = FALSE; static DWORD PrevOnlineRemainingMinutes; static UINT_PTR timer = 0;
#define DOWNLOAD_TIMEOUT_TIMER 5
#define DOWNLOAD_NOTIFY_TIMEOUT 60000
switch(msg) {
case WM_INITDIALOG:
if (GetDlgItemText (hdlg, IDT_DYNSETUP_TIME, buf, ARRAYSIZE(buf))) { msgToFormat = DupString (buf); } SetDlgItemText (hdlg, IDT_DYNSETUP_TIME, TEXT(""));
break;
case WMX_ACTIVATEPAGE: fRetVal = TRUE;
if (wParam) { if (g_DynUpdtStatus->DUStatus == DUS_SKIP || g_DynUpdtStatus->DUStatus == DUS_SUCCESSFUL ) { if (g_Thread) { MYASSERT (g_Event); g_Thread = NULL; CloseHandle (g_Event); g_Event = NULL; } if (g_DynUpdtStatus->DUStatus == DUS_SKIP) { if (!g_DynUpdtStatus->Disabled) { DynUpdtDebugLog ( Winnt32LogInformation, TEXT("DynamicUpdate is skipped"), 0 ); } } return FALSE; } //
// prepare the UI
//
if (Winnt32Restarted () || g_DynUpdtStatus->UserSpecifiedUpdates) { hBitmap = LoadImage (hInst, MAKEINTRESOURCE(IDB_CHECK), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS); hOld = (HANDLE) SendDlgItemMessage (hdlg, IDC_COPY_BMP, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap); hOld = (HANDLE) SendDlgItemMessage (hdlg, IDC_COPY_BMP2, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap); hBitmap = LoadImage (hInst, MAKEINTRESOURCE(IDB_ARROW), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS); hOld = (HANDLE) SendDlgItemMessage (hdlg, IDC_COPY_BMP3, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap); } else { pUpdateInfoText (IDS_ESC_TOCANCEL_DOWNLOAD); hBitmap = LoadImage (hInst, MAKEINTRESOURCE(IDB_ARROW), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS); hOld = (HANDLE) SendDlgItemMessage (hdlg, IDC_COPY_BMP, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap); hOld = (HANDLE) SendDlgItemMessage (hdlg, IDC_COPY_BMP2, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap); hOld = (HANDLE) SendDlgItemMessage (hdlg, IDC_COPY_BMP3, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap); } if (!g_Event) { g_Event = CreateEvent (NULL, FALSE, FALSE, S_DU_SYNC_EVENT_NAME); if (!g_Event) { DynUpdtDebugLog ( Winnt32LogError, TEXT("CreateEvent(%1) failed"), 0, S_DU_SYNC_EVENT_NAME ); g_DynUpdtStatus->DUStatus = DUS_ERROR; return FALSE; } } if (!g_Thread) { g_Thread = CreateThread (NULL, 0, DoDynamicUpdate, (LPVOID)hdlg, 0, &tid); if (!g_Thread) { DynUpdtDebugLog ( Winnt32LogError, TEXT("CreateThread(DoDynamicUpdate) failed"), 0 ); g_DynUpdtStatus->DUStatus = DUS_ERROR; CloseHandle (g_Event); g_Event = NULL; return FALSE; } //
// the handle is no longer needed
//
CloseHandle (g_Thread); } else { b = FALSE; if (g_DynUpdtStatus->DUStatus == DUS_PREPARING_CONNECTIONUNAVAILABLE || g_DynUpdtStatus->DUStatus == DUS_PREPARING_INVALIDURL) { g_DynUpdtStatus->DUStatus = DUS_PREPARING; b = TRUE; } if (g_DynUpdtStatus->DUStatus == DUS_DOWNLOADING_ERROR) { g_DynUpdtStatus->DUStatus = DUS_DOWNLOADING; b = TRUE; } if (b) { //
// page was actually reentered after some previous failure
// resume the working thread
//
MYASSERT (g_Event); SetEvent (g_Event); } }
DownloadPageActive = TRUE; //
// hide the wizard page
//
SendMessage(GetParent (hdlg), WMX_BBTEXT, (WPARAM)TRUE, 0); } else { if (timer) { KillTimer (hdlg, timer); timer = 0; }
DownloadPageActive = FALSE; } Animate_Open(GetDlgItem(hdlg, IDC_ANIMATE), wParam ? MAKEINTRESOURCE(IDA_COMPGLOB) : NULL); break;
case WMX_SETUPUPDATE_PROGRESS_NOTIFY: //
// reset the timer
//
timer = SetTimer (hdlg, DOWNLOAD_TIMEOUT_TIMER, DOWNLOAD_NOTIFY_TIMEOUT, NULL); //
// update UI
//
if (!hComp) { hComp = pInitializeOnlineSeconds (); PrevOnlineRemainingMinutes = -1; } onlineRemainingSeconds = pGetOnlineRemainingSeconds (hComp, (DWORD)lParam, (DWORD)wParam, &kbps); if (onlineRemainingSeconds) { onlineRemainingMinutes = onlineRemainingSeconds / 60 + 1; if (msgToFormat && onlineRemainingMinutes < PrevOnlineRemainingMinutes) { PrevOnlineRemainingMinutes = onlineRemainingMinutes; if (_sntprintf (buf, ARRAYSIZE(buf), msgToFormat, onlineRemainingMinutes) < 0) { buf[ARRAYSIZE(buf) - 1] = 0; }
#ifdef DOWNLOAD_DETAILS
//
// also display kbps and remaining time in seconds
//
_sntprintf (buf2, TEXT(" (%u sec. at %u kbps)"), onlineRemainingSeconds, kbps); StringCchCat (buf, ARRAYSIZE(buf), buf2); #endif
SetDlgItemText (hdlg, IDT_DYNSETUP_TIME, buf); pUpdateProgressText (hdlg, IDT_DYNSETUP_DOWNLOADING, buf, TRUE); } } break;
case WMX_SETUPUPDATE_RESULT: if (timer) { KillTimer (hdlg, timer); timer = 0; } if (g_DynUpdtStatus->DUStatus == DUS_DOWNLOADING) { Animate_Stop (GetDlgItem (hdlg, IDC_ANIMATE)); if (g_DynUpdtStatus->Cancelled) { g_DynUpdtStatus->DUStatus = DUS_CANCELLED; } else { if (wParam == DU_STATUS_SUCCESS) { g_DynUpdtStatus->DUStatus = DUS_PROCESSING; } else if (wParam == DU_STATUS_FAILED) { g_DynUpdtStatus->DUStatus = DUS_DOWNLOADING_ERROR; } else { g_DynUpdtStatus->DUStatus = DUS_ERROR; MYASSERT (FALSE); } } if (!CancelDownloadPending) { //
// let the worker thread continue
//
if (g_DynUpdtStatus->DUStatus != DUS_DOWNLOADING_ERROR) { MYASSERT (g_Event); SetEvent (g_Event); } else { //
// go to the error page
//
if (DownloadPageActive) { PropSheet_SetWizButtons (GetParent(hdlg), WizPage->CommonData.Buttons | PSWIZB_NEXT); PropSheet_PressButton (GetParent (hdlg), PSBTN_NEXT); DownloadPageActive = FALSE; } } } else { ResumeWorkerThread = TRUE; } } else { MYASSERT (FALSE); g_DynUpdtStatus->DUStatus = DUS_ERROR; if (g_Event) { SetEvent (g_Event); } } break;
case WMX_SETUPUPDATE_PREPARING: SetDlgItemTextBold (hdlg, IDT_DYNSETUP_DIALING, TRUE); pUpdateProgressText (hdlg, IDT_DYNSETUP_DIALING, NULL, FALSE); Animate_Play (GetDlgItem (hdlg, IDC_ANIMATE), 0, -1, -1); break;
case WMX_SETUPUPDATE_DOWNLOADING: //
// wParam holds the estimated download time
// lParam holds the estimated download size
//
SetDlgItemTextBold (hdlg, IDT_DYNSETUP_DIALING, FALSE); hBitmap = LoadImage (hInst, MAKEINTRESOURCE(IDB_CHECK), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS); hOld = (HANDLE) SendDlgItemMessage (hdlg, IDC_COPY_BMP, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap);
SetDlgItemTextBold (hdlg, IDT_DYNSETUP_DOWNLOADING, TRUE); pUpdateProgressText (hdlg, IDT_DYNSETUP_DOWNLOADING, NULL, FALSE); ShowWindow (GetDlgItem (hdlg, IDT_DYNSETUP_TIME), SW_SHOW);
//
// set a timeout interval, just in case the control "forgets" to send messages
//
timer = SetTimer (hdlg, DOWNLOAD_TIMEOUT_TIMER, DOWNLOAD_NOTIFY_TIMEOUT, NULL); if (!timer) { DynUpdtDebugLog ( Winnt32LogWarning, TEXT("SetTimer failed - unable to automatically abort if the control doesn't respond timely"), 0 ); } break;
case WMX_SETUPUPDATE_PROCESSING: g_DynUpdtStatus->DUStatus = DUS_PROCESSING; SetDlgItemTextBold (hdlg, IDT_DYNSETUP_DOWNLOADING, FALSE); ShowWindow (GetDlgItem (hdlg, IDT_DYNSETUP_TIME), SW_HIDE); hBitmap = LoadImage (hInst, MAKEINTRESOURCE(IDB_CHECK), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS); hOld = (HANDLE) SendDlgItemMessage (hdlg, IDC_COPY_BMP2, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap);
SetDlgItemTextBold (hdlg, IDT_DYNSETUP_PROCESSING, TRUE); pUpdateProgressText (hdlg, IDT_DYNSETUP_PROCESSING, NULL, FALSE); pUpdateInfoText (IDS_ESC_TOCANCEL); break;
case WMX_SETUPUPDATE_THREAD_DONE:
pUpdateProgressText (NULL, 0, NULL, FALSE);
g_Thread = NULL; if (g_Event) { CloseHandle (g_Event); g_Event = NULL; }
if (g_DynUpdtStatus->DUStatus == DUS_SUCCESSFUL) {
if (!g_DynUpdtStatus->Disabled && !g_DynUpdtStatus->RestartWinnt32) { DynUpdtDebugLog ( Winnt32LogInformation, TEXT("DynamicUpdate was completed successfully"), 0 ); }
SetDlgItemTextBold (hdlg, IDT_DYNSETUP_PROCESSING, FALSE); hBitmap = LoadImage (hInst, MAKEINTRESOURCE(IDB_CHECK), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS); hOld = (HANDLE) SendDlgItemMessage (hdlg, IDC_COPY_BMP3, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap); UpdateWindow (GetDlgItem (hdlg, IDC_COPY_BMP3)); UpdateWindow (hdlg);
} else if (g_DynUpdtStatus->DUStatus == DUS_ERROR) {
if (UnattendedScriptFile) { //
// in the unattended case, read the answer to decide if to stop or not
//
GetPrivateProfileString ( WINNT_UNATTENDED, WINNT_U_DYNAMICUPDATESTOPONERROR, WINNT_A_NO, buf, ARRAYSIZE(buf), UnattendedScriptFile ); if (!lstrcmpi (buf, WINNT_A_YES)) { DynUpdtDebugLog ( Winnt32LogSevereError, TEXT("Setup encountered an error during DynamicUpdate and failed as instructed in the unattend file"), 0 ); g_DynUpdtStatus->RestartWinnt32 = FALSE; Cancelled = TRUE; PropSheet_PressButton (GetParent (hdlg), PSBTN_CANCEL); break; } } } else if (g_DynUpdtStatus->DUStatus == DUS_FATALERROR) { DynUpdtDebugLog ( Winnt32LogSevereError, TEXT("Setup encountered a fatal error during DynamicUpdate and stopped"), 0 ); g_DynUpdtStatus->RestartWinnt32 = FALSE; Cancelled = TRUE; PropSheet_PressButton (GetParent (hdlg), PSBTN_CANCEL); break; }
//
// continue setup (this may actually restart winnt32)
//
if (DownloadPageActive) { PropSheet_SetWizButtons (GetParent(hdlg), WizPage->CommonData.Buttons | PSWIZB_NEXT); PropSheet_PressButton (GetParent (hdlg), PSBTN_NEXT); DownloadPageActive = FALSE; }
break;
case WMX_SETUPUPDATE_INIT_RETRY: //
// go to the retry page
//
if (DownloadPageActive) { PropSheet_SetWizButtons (GetParent(hdlg), WizPage->CommonData.Buttons | PSWIZB_NEXT); PropSheet_PressButton (GetParent (hdlg), PSBTN_NEXT); PropSheet_SetWizButtons (GetParent(hdlg), WizPage->CommonData.Buttons & ~PSWIZB_NEXT); DownloadPageActive = FALSE; } break;
case WMX_QUERYCANCEL: //
// on this page, CANCEL means "cancel download", not cancel Setup,
// but only while connecting or downloading
//
if (g_DynUpdtStatus->DUStatus != DUS_DOWNLOADING && g_DynUpdtStatus->DUStatus != DUS_PREPARING) { break; }
fRetVal = TRUE; if (lParam) { //
// don't cancel setup
//
*(BOOL*)lParam = FALSE; } if (!g_DynUpdtStatus->Cancelled) { //
// ask user if they really want to cancel DU
//
DWORD rc = IDYES; CancelDownloadPending = TRUE; Animate_Stop (GetDlgItem (hdlg, IDC_ANIMATE)); if (!CheckUpgradeOnly) { rc = MessageBoxFromMessage ( hdlg, g_DynUpdtStatus->IncompatibleDriversCount ? MSG_SURE_CANCEL_DOWNLOAD_DRIVERS : MSG_SURE_CANCEL_DOWNLOAD, FALSE, AppTitleStringId, MB_YESNO | MB_ICONQUESTION | MB_TASKMODAL | MB_DEFBUTTON2, g_DynUpdtStatus->IncompatibleDriversCount ); } if (rc == IDYES) { g_DynUpdtStatus->Cancelled = TRUE; DynamicUpdateCancel (); } else { Animate_Play (GetDlgItem (hdlg, IDC_ANIMATE), 0, -1, -1); } if (ResumeWorkerThread) { ResumeWorkerThread = FALSE; if (g_DynUpdtStatus->DUStatus != DUS_DOWNLOADING_ERROR) { MYASSERT (g_Event); SetEvent (g_Event); } } CancelDownloadPending = FALSE; } break;
case WM_TIMER: if (timer && (wParam == timer)) { if (g_DynUpdtStatus->DUStatus == DUS_DOWNLOADING) { //
// oops, the control didn't send any message in a long time now...
// abort download and continue
//
DynUpdtDebugLog ( Winnt32LogError, TEXT("The timeout for control feedback expired (%1!u! seconds); operation will be aborted"), 0, DOWNLOAD_NOTIFY_TIMEOUT / 1000 ); KillTimer (hdlg, timer); timer = 0;
DynamicUpdateCancel (); SendMessage (hdlg, WMX_SETUPUPDATE_RESULT, DU_STATUS_FAILED, ERROR_TIMEOUT); } } break; }
return fRetVal; }
BOOL RestartWizPage ( IN HWND hdlg, IN UINT msg, IN WPARAM wParam, IN LPARAM lParam ) /*++
Routine Description:
Dynamic Setup Restart page
Arguments:
Standard window proc arguments.
Returns:
Message-dependent value.
--*/ {
#define REBOOT_TIMEOUT_SECONDS 5
#define ID_REBOOT_TIMER 1
#define TICKS_PER_SECOND 10
static UINT Countdown; PCTSTR RestartText; BOOL fRetVal = FALSE;
switch(msg) {
case WM_TIMER: if (--Countdown) { SendDlgItemMessage (hdlg, IDC_PROGRESS1, PBM_STEPIT, 0, 0); } else { PropSheet_PressButton (GetParent (hdlg), PSBTN_FINISH); }
fRetVal = TRUE; break;
case WMX_ACTIVATEPAGE: if (wParam) { pUpdateInfoText (IDS_ESC_TOCANCEL); if (Winnt32Restarted () || g_DynUpdtStatus->DUStatus != DUS_SUCCESSFUL || !g_DynUpdtStatus->RestartWinnt32 ) { return FALSE; } //
// Setup needs to restart with option /Restart:<path to restart file>
//
if (!DynamicUpdatePrepareRestart ()) { DynUpdtDebugLog ( Winnt32LogError, TEXT("DynamicUpdatePrepareRestart failed"), 0 ); g_DynUpdtStatus->DUStatus = DUS_ERROR; return FALSE; }
pUpdateProgressText (NULL, IDS_RESTART_SETUP, NULL, FALSE); pUpdateInfoText (0);
EnableWindow (GetDlgItem(GetParent(hdlg), IDCANCEL), FALSE); PropSheet_SetWizButtons (GetParent(hdlg), PSWIZB_FINISH); RestartText = GetStringResource (MSG_RESTART); if (RestartText) { PropSheet_SetFinishText (GetParent (hdlg), RestartText); FreeStringResource (RestartText); }
Countdown = REBOOT_TIMEOUT_SECONDS * TICKS_PER_SECOND;
SendDlgItemMessage (hdlg, IDC_PROGRESS1, PBM_SETRANGE, 0, MAKELONG(0,Countdown)); SendDlgItemMessage (hdlg, IDC_PROGRESS1, PBM_SETSTEP, 1, 0); SendDlgItemMessage (hdlg, IDC_PROGRESS1, PBM_SETPOS, 0, 0);
SetTimer (hdlg, ID_REBOOT_TIMER, 1000 / TICKS_PER_SECOND, NULL); }
//
// Accept activation/deactivation.
//
fRetVal = TRUE; break;
case WMX_FINISHBUTTON: //
// Clean up the timer.
//
KillTimer (hdlg, ID_REBOOT_TIMER); //
// Let upgrade code do its cleanup.
//
if (UpgradeSupport.CleanupRoutine) { UpgradeSupport.CleanupRoutine (); } fRetVal = TRUE;
break;
}
return fRetVal; }
BOOL DynSetup3WizPage( IN HWND hdlg, IN UINT msg, IN WPARAM wParam, IN LPARAM lParam ) /*++
Routine Description:
Dynamic Setup page 3 (retrying connection establish)
Arguments:
Standard window proc arguments.
Returns:
Message-dependent value.
--*/ { TCHAR buffer[100]; BOOL cancel; static INT iSelected = IDR_DYNSETUP_MANUAL; static BOOL bFirstTime = TRUE; BOOL fRetVal = FALSE; switch(msg) {
case WM_INITDIALOG: //
// Set radio buttons.
//
pCheckRadioButtons (hdlg, iSelected, IDR_DYNSETUP_MANUAL, IDR_DYNSETUP_SKIP); //
// Set focus to radio buttons
//
SetFocus (GetDlgItem (hdlg, IDR_DYNSETUP_MANUAL)); break;
case WM_COMMAND: if(HIWORD(wParam) == BN_CLICKED) { switch (LOWORD (wParam)) { case IDR_DYNSETUP_MANUAL: case IDR_DYNSETUP_SKIP: iSelected = LOWORD (wParam); fRetVal = TRUE; break; } } break;
case WMX_ACTIVATEPAGE: if (wParam) { if (g_DynUpdtStatus->DUStatus != DUS_PREPARING_CONNECTIONUNAVAILABLE) { return FALSE; }
if (UnattendSwitchSpecified) { //
// skip DU by default
//
iSelected = IDR_DYNSETUP_SKIP; //
// now read the answer, if provided
//
if (UnattendedScriptFile) { GetPrivateProfileString ( WINNT_UNATTENDED, WINNT_U_DYNAMICUPDATESTOPONERROR, WINNT_A_NO, buffer, ARRAYSIZE(buffer), UnattendedScriptFile ); if (!lstrcmpi (buffer, WINNT_A_YES)) { DynUpdtDebugLog ( Winnt32LogSevereError, TEXT("Setup encountered an error during DynamicUpdate and failed as instructed in the unattend file"), 0 ); g_DynUpdtStatus->RestartWinnt32 = FALSE; Cancelled = TRUE; PropSheet_PressButton (GetParent (hdlg), PSBTN_CANCEL); break; } } UNATTENDED(PSBTN_NEXT); } else { iSelected = bFirstTime ? IDR_DYNSETUP_MANUAL : IDR_DYNSETUP_SKIP; bFirstTime = FALSE; } pCheckRadioButtons (hdlg, iSelected, IDR_DYNSETUP_MANUAL, IDR_DYNSETUP_SKIP); SendMessage(GetParent (hdlg), WMX_BBTEXT, (WPARAM)FALSE, 0); } else { if (Cancelled) { g_DynUpdtStatus->Cancelled = TRUE; } //
// let the worker thread continue
//
MYASSERT (g_Thread && g_Event); SetEvent (g_Event); }
fRetVal = TRUE;
break;
case WMX_BACKBUTTON: MYASSERT (FALSE);
case WMX_NEXTBUTTON: switch (iSelected) { case IDR_DYNSETUP_MANUAL: // do magical stuff to hide everything
ShowWindow(BackgroundWnd2, SW_MINIMIZE);
if (DialogBox(hInst, MAKEINTRESOURCE(IDD_DYNAMICSETUP_MANUAL), hdlg, DynSetup_ManualDialog)) { DynUpdtDebugLog ( Winnt32LogInformation, TEXT("Manual connect page: user connected manually"), 0 ); g_DynUpdtStatus->DUStatus = DUS_PREPARING; } else { g_DynUpdtStatus->DUStatus = DUS_SKIP; }
SETNEXTPAGE(IDD_DYNAMICSETUP2); // do magical stuff to unhide everything
ShowWindow(BackgroundWnd2, SW_SHOWMAXIMIZED); break;
case IDR_DYNSETUP_SKIP: DynUpdtDebugLog ( Winnt32LogInformation, TEXT("Manual connect page: operation was skipped"), 0 ); g_DynUpdtStatus->DUStatus = DUS_SKIP; break; } fRetVal = TRUE; break; }
return fRetVal; }
BOOL DynSetup4WizPage( IN HWND hdlg, IN UINT msg, IN WPARAM wParam, IN LPARAM lParam ) /*++
Routine Description:
Dynamic Setup page 4 (web site inaccessible)
Arguments:
Standard window proc arguments.
Returns:
Message-dependent value.
--*/ { TCHAR buffer[100]; BOOL cancel; static INT iSelected = IDR_DYNSETUP_RETRY; static BOOL bFirstTime = TRUE; BOOL fRetVal = FALSE; switch(msg) {
case WM_INITDIALOG: //
// Set radio buttons.
//
pCheckRadioButtons (hdlg, iSelected, IDR_DYNSETUP_RETRY, IDR_DYNSETUP_SKIP); //
// Set focus to radio buttons
//
SetFocus (GetDlgItem (hdlg, IDR_DYNSETUP_RETRY)); break;
case WM_COMMAND: if(HIWORD(wParam) == BN_CLICKED) { switch (LOWORD (wParam)) { case IDR_DYNSETUP_RETRY: case IDR_DYNSETUP_SKIP: iSelected = LOWORD (wParam); fRetVal = TRUE; break; } } break;
case WMX_ACTIVATEPAGE: if (wParam) { if (g_DynUpdtStatus->DUStatus != DUS_PREPARING_INVALIDURL) { return FALSE; }
if (UnattendSwitchSpecified) { //
// skip DU by default
//
iSelected = IDR_DYNSETUP_SKIP; //
// now read the answer, if provided
//
if (UnattendedScriptFile) { GetPrivateProfileString ( WINNT_UNATTENDED, WINNT_U_DYNAMICUPDATESTOPONERROR, WINNT_A_NO, buffer, ARRAYSIZE(buffer), UnattendedScriptFile ); if (!lstrcmpi (buffer, WINNT_A_YES)) { DynUpdtDebugLog ( Winnt32LogSevereError, TEXT("Setup encountered an error during DynamicUpdate and failed as instructed in the unattend file"), 0 ); g_DynUpdtStatus->RestartWinnt32 = FALSE; Cancelled = TRUE; PropSheet_PressButton (GetParent (hdlg), PSBTN_CANCEL); break; } } UNATTENDED(PSBTN_NEXT); } else { iSelected = bFirstTime ? IDR_DYNSETUP_RETRY : IDR_DYNSETUP_SKIP; bFirstTime = FALSE; } pCheckRadioButtons (hdlg, iSelected, IDR_DYNSETUP_RETRY, IDR_DYNSETUP_SKIP); SendMessage(GetParent (hdlg), WMX_BBTEXT, (WPARAM)FALSE, 0); } else { if (Cancelled) { g_DynUpdtStatus->Cancelled = TRUE; } //
// let the worker thread continue
//
MYASSERT (g_Thread && g_Event); SetEvent (g_Event); }
fRetVal = TRUE;
break;
case WMX_BACKBUTTON: MYASSERT (FALSE);
case WMX_NEXTBUTTON: switch (iSelected) { case IDR_DYNSETUP_RETRY: DynUpdtDebugLog ( Winnt32LogInformation, TEXT("Retry connection page: user chose to retry"), 0 ); g_DynUpdtStatus->DUStatus = DUS_PREPARING; SETNEXTPAGE(IDD_DYNAMICSETUP2); break;
case IDR_DYNSETUP_SKIP: DynUpdtDebugLog ( Winnt32LogInformation, TEXT("Retry connection page: operation was skipped"), 0 ); g_DynUpdtStatus->DUStatus = DUS_SKIP; break; } fRetVal = TRUE; break; }
return fRetVal; }
BOOL DynSetup5WizPage( IN HWND hdlg, IN UINT msg, IN WPARAM wParam, IN LPARAM lParam ) /*++
Routine Description:
Dynamic Setup page 5 (error while downloading)
Arguments:
Standard window proc arguments.
Returns:
Message-dependent value.
--*/ { TCHAR buffer[100]; BOOL cancel; static INT iSelected = IDR_DYNSETUP_RETRY; static BOOL bFirstTime = TRUE; BOOL fRetVal = FALSE; switch(msg) {
case WM_INITDIALOG: //
// Set radio buttons.
//
pCheckRadioButtons (hdlg, iSelected, IDR_DYNSETUP_RETRY, IDR_DYNSETUP_SKIP); //
// Set focus to radio buttons
//
SetFocus (GetDlgItem (hdlg, IDR_DYNSETUP_RETRY)); break;
case WM_COMMAND: if(HIWORD(wParam) == BN_CLICKED) { switch (LOWORD (wParam)) { case IDR_DYNSETUP_RETRY: case IDR_DYNSETUP_SKIP: iSelected = LOWORD (wParam); fRetVal = TRUE; break; } } break;
case WMX_ACTIVATEPAGE: if (wParam) { if (g_DynUpdtStatus->DUStatus != DUS_DOWNLOADING_ERROR) { SendMessage (hdlg, WMX_DYNAMIC_UPDATE_COMPLETE, 0, 0); return FALSE; }
if (UnattendSwitchSpecified) { //
// skip DU by default
//
iSelected = IDR_DYNSETUP_SKIP; //
// now read the answer, if provided
//
if (UnattendedScriptFile) { //
// Read answer
//
GetPrivateProfileString ( WINNT_UNATTENDED, WINNT_U_DYNAMICUPDATESTOPONERROR, WINNT_A_NO, buffer, ARRAYSIZE(buffer), UnattendedScriptFile ); if (!lstrcmpi (buffer, WINNT_A_YES)) { DynUpdtDebugLog ( Winnt32LogSevereError, TEXT("Setup encountered an error during DynamicUpdate and failed as instructed in the unattend file"), 0 ); g_DynUpdtStatus->RestartWinnt32 = FALSE; Cancelled = TRUE; PropSheet_PressButton (GetParent (hdlg), PSBTN_CANCEL); break; } } UNATTENDED(PSBTN_NEXT); } else { iSelected = bFirstTime ? IDR_DYNSETUP_RETRY : IDR_DYNSETUP_SKIP; bFirstTime = FALSE; } pCheckRadioButtons (hdlg, iSelected, IDR_DYNSETUP_RETRY, IDR_DYNSETUP_SKIP); SendMessage(GetParent (hdlg), WMX_BBTEXT, (WPARAM)FALSE, 0); } else { if (Cancelled) { g_DynUpdtStatus->Cancelled = TRUE; } //
// let the worker thread continue
//
MYASSERT (g_Thread && g_Event); SetEvent (g_Event); }
SendMessage (hdlg, WMX_DYNAMIC_UPDATE_COMPLETE, 0, 0); fRetVal = TRUE;
break;
case WMX_DYNAMIC_UPDATE_COMPLETE: #if defined(_X86_)
//
// Send upgrade report option to module. DU is
// now out of the picture.
//
switch (g_UpgradeReportMode) {
case IDC_CRITICAL_ISSUES: AppendUpgradeOption (TEXT("ShowReport=Auto")); break;
case IDC_ALL_ISSUES: AppendUpgradeOption (TEXT("ShowReport=Yes")); break;
case IDC_NO_REPORT: AppendUpgradeOption (TEXT("ShowReport=No")); break; } #endif
break;
case WMX_BACKBUTTON: MYASSERT (FALSE);
case WMX_NEXTBUTTON: switch (iSelected) { case IDR_DYNSETUP_RETRY: DynUpdtDebugLog ( Winnt32LogInformation, TEXT("Retry download page: user chose to retry"), 0 ); g_DynUpdtStatus->DUStatus = DUS_DOWNLOADING; SETNEXTPAGE(IDD_DYNAMICSETUP2); break;
case IDR_DYNSETUP_SKIP: DynUpdtDebugLog ( Winnt32LogInformation, TEXT("Retry download page: operation was skipped"), 0 ); g_DynUpdtStatus->DUStatus = DUS_SKIP; break; } fRetVal = TRUE; break; }
return fRetVal; }
INT_PTR DynSetup_ManualDialog( IN HWND hdlg, IN UINT msg, IN WPARAM wParam, IN LPARAM lParam ) /*++
Routine Description:
Dynamic Setup manual dialog
Arguments:
Standard window proc arguments.
Returns:
Message-dependent value.
--*/ { BOOL fRetVal = FALSE;
switch(msg) { case WM_INITDIALOG: fRetVal = TRUE; break; case WM_COMMAND: if(HIWORD(wParam) == BN_CLICKED) { if (LOWORD (wParam) == IDOK) { EndDialog(hdlg, 1); fRetVal = TRUE; } else { EndDialog(hdlg, 0); fRetVal = TRUE; } } }
return fRetVal; }
//
// Time estimate stuff
//
#define MAX_INDEX 100
typedef struct { DWORD D; DWORD T; ULONGLONG DT; ULONGLONG TT; } STDDEV_ELEM, *PSTDDEV_ELEM;
typedef struct { STDDEV_ELEM Array[MAX_INDEX]; STDDEV_ELEM Sums; UINT Index; UINT Count; DWORD T0; } STDDEV_COMPUTATION, *PSTDDEV_COMPUTATION;
HANDLE pInitializeOnlineSeconds ( VOID ) { PSTDDEV_COMPUTATION p = MALLOC (sizeof (STDDEV_COMPUTATION)); if (p) { ZeroMemory (p, sizeof (STDDEV_COMPUTATION));
#ifdef DOWNLOAD_DETAILS
//
// table header
//
DynUpdtDebugLog ( Winnt32LogDetailedInformation, TEXT("Count| MiliSec| Bytes| Baud|EstRemSec|\r\n") TEXT("-----|---------|---------|---------|---------|"), 0 ); #endif
} return (HANDLE)p; }
DWORD pGetOnlineRemainingSeconds ( IN HANDLE Handle, IN DWORD DownloadedBytes, IN DWORD TotalBytesToDownload, OUT PDWORD KbPerSec OPTIONAL ) { PSTDDEV_COMPUTATION p = (PSTDDEV_COMPUTATION)Handle; PSTDDEV_ELEM e; DWORD r = 0; DWORD remTimeSec; ULONGLONG div;
if (!p) { return 0; } if (p->Index >= ARRAYSIZE(p->Array)) { return 0; }
e = &p->Array[p->Index]; if (p->Count == 0) { //
// add the first pair
//
e->D = DownloadedBytes; // bytes
e->T = 0; // miliseconds
e->DT = 0; e->TT = 0; p->Sums.D = DownloadedBytes; p->Count++; p->Index++; //
// initialize timer
//
p->T0 = GetTickCount (); //
// no time estimate at this point (not enough data)
//
return 0; } //
// compute sum of prev pairs
//
p->Sums.D -= e->D; p->Sums.T -= e->T; p->Sums.DT -= e->DT; p->Sums.TT -= e->TT; //
// compute new values
//
e->D = DownloadedBytes; // bytes
e->T = GetTickCount () - p->T0; // miliseconds
e->DT = (ULONGLONG)e->D * (ULONGLONG)e->T; e->TT = (ULONGLONG)e->T * (ULONGLONG)e->T; //
// compute new sums
//
p->Sums.D += e->D; p->Sums.T += e->T; p->Sums.DT += e->DT; p->Sums.TT += e->TT; //
// adjust count and index
//
if (p->Count < ARRAYSIZE(p->Array)) { p->Count++; } p->Index++; if (p->Index == ARRAYSIZE(p->Array)) { p->Index = 0; } //
// compute new download rate, in bytes/milisec
//
div = p->Sums.TT * (ULONGLONG)p->Count - (ULONGLONG)p->Sums.T * (ULONGLONG)p->Sums.T; if (div) { r = (DWORD) ((p->Sums.DT * (ULONGLONG)p->Count - (ULONGLONG)p->Sums.D * (ULONGLONG)p->Sums.T) * 1000 / div / 1024); }
//
// now estimate remaining time based on the difference and this rate
// assume there's always something more to download (never 0)
//
remTimeSec = 1; if (r) { remTimeSec += (TotalBytesToDownload - DownloadedBytes) / r / 1000; }
#ifdef DOWNLOAD_DETAILS
//
// log this for debug purposes
//
DynUpdtDebugLog ( Winnt32LogDetailedInformation, TEXT("%1!5u!%2!10u!%3!10u!%4!10u!%5!10u!"), 0, p->Count, e->T, e->D, r * 8, remTimeSec ); #endif
if (KbPerSec) { *KbPerSec = r; } return remTimeSec; }
|