505 lines
14 KiB
C
505 lines
14 KiB
C
/*++
|
|
|
|
Copyright (c) 1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
ui.c
|
|
|
|
Abstract:
|
|
|
|
The UI library contains all Win9x-side user interface code. UI_GetWizardPages
|
|
is called by WINNT32 allowing the migration module to add its own wizard pages.
|
|
UI_ReportThread is the thread that performs all report-phase migration processing.
|
|
UI_Cleanup is called by WINNT32 when the user chooses to abort setup. The rest
|
|
of the functions in this module support the progress bar.
|
|
|
|
Author:
|
|
|
|
Jim Schmidt (jimschm) 04-Mar-1997
|
|
|
|
Revision History:
|
|
|
|
Marc R. Whitten (marcw) 08-Jul-1998 - Ambigous Timezone page added.
|
|
Jim Schmidt (jimschm) 21-Jan-1998 - Created macro expansion list for wizard pages
|
|
Jim Schmidt (jimschm) 29-Jul-1997 - Moved accessible drives to here
|
|
Marc R. Whitten (marcw) 25-Apr-1997 - Ras migration added.
|
|
Marc R. Whitten (marcw) 21-Apr-1997 - hwcomp stuff moved to new wiz page.
|
|
Checks for usable hdd and cdrom added.
|
|
Marc R. Whitten (marcw) 14-Apr-1997 - Progress Bar handling revamped.
|
|
|
|
--*/
|
|
|
|
#include "pch.h"
|
|
#include "uip.h"
|
|
#include "drives.h"
|
|
|
|
extern BOOL g_Terminated;
|
|
|
|
/*++
|
|
|
|
Macro Expansion List Description:
|
|
|
|
PAGE_LIST lists each wizard page that will appear in any UI, in the order it appears
|
|
in the wizard.
|
|
|
|
Line Syntax:
|
|
|
|
DEFMAC(DlgId, WizProc, Flags)
|
|
|
|
Arguments:
|
|
|
|
DlgId - Specifies the ID of a dialog. May not be zero. May be 1 if WizProc
|
|
is NULL.
|
|
|
|
WizProc - Specifies wizard proc for dialog ID. May be NULL to skip processing
|
|
of page.
|
|
|
|
Flags - Specifies one of the following:
|
|
|
|
OPTIONAL_PAGE - Specifies page is not critical to the upgrade or
|
|
incompatibility report
|
|
|
|
REQUIRED_PAGE - Specifies page is required for the upgrade to work
|
|
properly.
|
|
|
|
|
|
Flags may also specify START_GROUP, a flag that begins a new group
|
|
of wizard pages to pass back to WINNT32. Subsequent lines that do not
|
|
have the START_GROUP flag are also added to the group.
|
|
|
|
Currently there are exactly three groups. See winnt32p.h for details.
|
|
|
|
Variables Generated From List:
|
|
|
|
g_PageArray
|
|
|
|
--*/
|
|
|
|
#define PAGE_LIST \
|
|
DEFMAC(IDD_BACKUP_PAGE, UI_BackupPageProc, START_GROUP|OPTIONAL_PAGE) \
|
|
DEFMAC(IDD_HWCOMPDAT_PAGE, UI_HwCompDatPageProc, START_GROUP|REQUIRED_PAGE) \
|
|
DEFMAC(IDD_BADCDROM_PAGE, UI_BadCdRomPageProc, OPTIONAL_PAGE) \
|
|
DEFMAC(IDD_NAME_COLLISION_PAGE, UI_NameCollisionPageProc, REQUIRED_PAGE) \
|
|
DEFMAC(IDD_BAD_TIMEZONE_PAGE, UI_BadTimeZonePageProc, OPTIONAL_PAGE) \
|
|
DEFMAC(IDD_PREDOMAIN_PAGE, UI_PreDomainPageProc, REQUIRED_PAGE) \
|
|
DEFMAC(IDD_DOMAIN_PAGE, UI_DomainPageProc, REQUIRED_PAGE) \
|
|
DEFMAC(IDD_SUPPLY_MIGDLL_PAGE2, UI_UpgradeModulePageProc, OPTIONAL_PAGE) \
|
|
DEFMAC(IDD_SCANNING_PAGE, UI_ScanningPageProc, START_GROUP|REQUIRED_PAGE) \
|
|
DEFMAC(IDD_SUPPLY_DRIVER_PAGE2, UI_HardwareDriverPageProc, OPTIONAL_PAGE) \
|
|
DEFMAC(IDD_BACKUP_YES_NO_PAGE, UI_BackupYesNoPageProc, REQUIRED_PAGE) \
|
|
DEFMAC(IDD_BACKUP_DRIVE_SELECTION_PAGE, UI_BackupDriveSelectionProc,REQUIRED_PAGE) \
|
|
DEFMAC(IDD_BACKUP_IMPOSSIBLE_INFO_PAGE, UI_BackupImpossibleInfoProc,REQUIRED_PAGE) \
|
|
DEFMAC(IDD_BACKUP_IMPOSSIBLE_INFO_1_PAGE, UI_BackupImpExceedLimitProc,REQUIRED_PAGE) \
|
|
DEFMAC(IDD_RESULTS_PAGE2, UI_ResultsPageProc, REQUIRED_PAGE) \
|
|
DEFMAC(IDD_LAST_PAGE, UI_LastPageProc, OPTIONAL_PAGE) \
|
|
|
|
// DEFMAC(IDD_BADHARDDRIVE_PAGE, UI_BadHardDrivePageProc, OPTIONAL_PAGE) \
|
|
|
|
//
|
|
// Create the macro expansion that defines g_PageArray
|
|
//
|
|
|
|
typedef BOOL(WINNT32_WIZARDPAGE_PROC_PROTOTYPE)(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
typedef WINNT32_WIZARDPAGE_PROC_PROTOTYPE *WINNT32_WIZARDPAGE_PROC;
|
|
|
|
#define START_GROUP 0x0001
|
|
#define OPTIONAL_PAGE 0x0002
|
|
#define REQUIRED_PAGE 0x0000
|
|
|
|
typedef struct {
|
|
UINT DlgId;
|
|
WINNT32_WIZARDPAGE_PROC WizProc;
|
|
DWORD Flags;
|
|
} WIZPAGE_DEFINITION, *PWIZPAGE_DEFINITION;
|
|
|
|
#define DEFMAC(id,fn,flags) WINNT32_WIZARDPAGE_PROC_PROTOTYPE fn;
|
|
|
|
PAGE_LIST
|
|
|
|
#undef DEFMAC
|
|
|
|
|
|
#define DEFMAC(id,fn,flags) {id,fn,flags},
|
|
|
|
WIZPAGE_DEFINITION g_PageArray[] = {
|
|
PAGE_LIST /* , */
|
|
{0, NULL, 0}
|
|
};
|
|
|
|
#undef DEFMAC
|
|
|
|
//
|
|
// Globals
|
|
//
|
|
|
|
HANDLE g_WorkerThreadHandle = NULL;
|
|
|
|
|
|
//
|
|
// Implementation
|
|
//
|
|
|
|
BOOL
|
|
WINAPI
|
|
UI_Entry (
|
|
IN HINSTANCE hinstDLL,
|
|
IN DWORD dwReason,
|
|
IN PVOID lpv
|
|
)
|
|
{
|
|
switch (dwReason) {
|
|
|
|
case DLL_PROCESS_ATTACH:
|
|
if (!InitCompatTable()) {
|
|
return FALSE;
|
|
}
|
|
MsgMgr_Init();
|
|
RegisterTextViewer();
|
|
break;
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
FreeCompatTable();
|
|
MsgMgr_Cleanup();
|
|
FreePunctTable();
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
DWORD
|
|
UI_GetWizardPages (
|
|
OUT UINT *FirstCountPtr,
|
|
OUT PROPSHEETPAGE **FirstArray,
|
|
OUT UINT *SecondCountPtr,
|
|
OUT PROPSHEETPAGE **SecondArray,
|
|
OUT UINT *ThirdCountPtr,
|
|
OUT PROPSHEETPAGE **ThirdArray
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
UI_GetWizardPages is called by WINNT32 when it is preparing the wizard (very
|
|
early in Setup). It inserts pages we give it into its wizard page array and
|
|
then creates the wizard. Eventually our wizard procs get called (see wizproc.c)
|
|
no matter if we are upgrading or not.
|
|
|
|
The first array comes right after the user chooses to upgrade or not to upgrade.
|
|
The second array comes after the user has specified the source directory.
|
|
The third array comes after DOSNET.INF has been processed.
|
|
|
|
Arguments:
|
|
|
|
FirstCountPtr - Receives the number of elements of FirstArray
|
|
|
|
FirstArray - Receives a pointer to an initialized array of PROPSHEETPAGE elements.
|
|
These pages are inserted immediately after the page giving the user
|
|
a choice to upgrade.
|
|
|
|
SecondCountPtr - Receives the number of elements of SecondArray
|
|
|
|
SecondArray - Receives a pointer to an initialized array of PROPSHEETPAGE elements.
|
|
These pages are inserted immediately after the NT media directory has
|
|
been chosen.
|
|
|
|
ThirdCountPtr - Receives the number of elements of ThridArray
|
|
|
|
ThirdArray - Receives a pointer to an initialized array of PROPSHEETPAGE elements.
|
|
These pages are inserted immediately after the DOSNET.INF processing
|
|
page.
|
|
|
|
Return Value:
|
|
|
|
Win32 status code.
|
|
|
|
--*/
|
|
|
|
{
|
|
static PROPSHEETPAGE StaticPageArray[32];
|
|
INT i, j, k;
|
|
UINT *CountPtrs[3];
|
|
PROPSHEETPAGE **PageArrayPtrs[3];
|
|
|
|
CountPtrs[0] = FirstCountPtr;
|
|
CountPtrs[1] = SecondCountPtr;
|
|
CountPtrs[2] = ThirdCountPtr;
|
|
|
|
PageArrayPtrs[0] = FirstArray;
|
|
PageArrayPtrs[1] = SecondArray;
|
|
PageArrayPtrs[2] = ThirdArray;
|
|
|
|
MYASSERT (g_PageArray[0].Flags & START_GROUP);
|
|
|
|
for (i = 0, j = -1, k = 0 ; g_PageArray[i].DlgId ; i++) {
|
|
MYASSERT (k < 32);
|
|
|
|
//
|
|
// Set the array start pointer
|
|
//
|
|
|
|
if (g_PageArray[i].Flags & START_GROUP) {
|
|
j++;
|
|
MYASSERT (j >= 0 && j <= 2);
|
|
|
|
*CountPtrs[j] = 0;
|
|
*PageArrayPtrs[j] = &StaticPageArray[k];
|
|
}
|
|
|
|
//
|
|
// Allow group to be skipped with NULL function. Also, guard against
|
|
// array declaration bug.
|
|
//
|
|
|
|
if (!g_PageArray[i].WizProc || j < 0 || j > 2) {
|
|
continue;
|
|
}
|
|
|
|
ZeroMemory (&StaticPageArray[k], sizeof (PROPSHEETPAGE));
|
|
StaticPageArray[k].dwSize = sizeof (PROPSHEETPAGE);
|
|
StaticPageArray[k].dwFlags = PSP_DEFAULT;
|
|
StaticPageArray[k].hInstance = g_hInst;
|
|
StaticPageArray[k].pszTemplate = MAKEINTRESOURCE(g_PageArray[i].DlgId);
|
|
StaticPageArray[k].pfnDlgProc = g_PageArray[i].WizProc;
|
|
|
|
k++;
|
|
*CountPtrs[j] += 1;
|
|
}
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
|
|
DWORD
|
|
UI_CreateNewHwCompDat (
|
|
PVOID p
|
|
)
|
|
{
|
|
HWND hdlg;
|
|
DWORD rc = ERROR_SUCCESS;
|
|
UINT SliceId;
|
|
|
|
hdlg = (HWND) p;
|
|
|
|
__try {
|
|
|
|
//
|
|
// This code executes only when the hwcomp.dat file needs to
|
|
// be rebuilt. It runs in a separate thread so the UI is
|
|
// responsive.
|
|
//
|
|
|
|
InitializeProgressBar (
|
|
GetDlgItem (hdlg, IDC_PROGRESS),
|
|
GetDlgItem (hdlg, IDC_COMPONENT),
|
|
GetDlgItem (hdlg, IDC_SUBCOMPONENT),
|
|
g_CancelFlagPtr
|
|
);
|
|
|
|
ProgressBar_SetComponentById(MSG_PREPARING_LIST);
|
|
ProgressBar_SetSubComponent(NULL);
|
|
|
|
SliceId = RegisterProgressBarSlice (HwComp_GetProgressMax());
|
|
|
|
BeginSliceProcessing (SliceId);
|
|
|
|
if (!CreateNtHardwareList (
|
|
SOURCEDIRECTORYARRAY(),
|
|
SOURCEDIRECTORYCOUNT(),
|
|
NULL,
|
|
REGULAR_OUTPUT
|
|
)) {
|
|
DEBUGMSG ((DBG_ERROR, "hwcomp.dat could not be generated"));
|
|
rc = GetLastError();
|
|
}
|
|
|
|
EndSliceProcessing();
|
|
|
|
ProgressBar_SetComponent(NULL);
|
|
ProgressBar_SetSubComponent(NULL);
|
|
|
|
TerminateProgressBar();
|
|
}
|
|
__finally {
|
|
SetLastError (rc);
|
|
|
|
if (!(*g_CancelFlagPtr)) {
|
|
//
|
|
// Advance the page when no error, otherwise cancel WINNT32
|
|
//
|
|
PostMessage (hdlg, WMX_REPORT_COMPLETE, 0, rc);
|
|
|
|
DEBUGMSG_IF ((
|
|
rc != ERROR_SUCCESS,
|
|
DBG_ERROR,
|
|
"Error in UI_CreateNewHwCompDat caused setup to terminate"
|
|
));
|
|
}
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
|
|
DWORD
|
|
UI_ReportThread (
|
|
PVOID p
|
|
)
|
|
{
|
|
HWND hdlg;
|
|
DWORD rc = ERROR_SUCCESS;
|
|
TCHAR TextRc[32];
|
|
|
|
hdlg = (HWND) p;
|
|
|
|
//
|
|
// Start the progress bar
|
|
//
|
|
|
|
InitializeProgressBar (
|
|
GetDlgItem (hdlg, IDC_PROGRESS),
|
|
GetDlgItem (hdlg, IDC_COMPONENT),
|
|
GetDlgItem (hdlg, IDC_SUBCOMPONENT),
|
|
g_CancelFlagPtr
|
|
);
|
|
|
|
ProgressBar_SetComponentById(MSG_PREPARING_LIST);
|
|
PrepareProcessingProgressBar();
|
|
|
|
//
|
|
// Process each component
|
|
//
|
|
|
|
|
|
__try {
|
|
|
|
DEBUGLOGTIME (("Starting System First Routines"));
|
|
rc = RunSysFirstMigrationRoutines ();
|
|
if (rc != ERROR_SUCCESS) {
|
|
__leave;
|
|
}
|
|
|
|
DEBUGLOGTIME (("Starting user functions"));
|
|
rc = RunUserMigrationRoutines ();
|
|
if (rc != ERROR_SUCCESS) {
|
|
__leave;
|
|
}
|
|
|
|
DEBUGLOGTIME (("Starting System Last Routines"));
|
|
rc = RunSysLastMigrationRoutines ();
|
|
if (rc != ERROR_SUCCESS) {
|
|
__leave;
|
|
}
|
|
|
|
ProgressBar_SetComponent(NULL);
|
|
ProgressBar_SetSubComponent(NULL);
|
|
}
|
|
__finally {
|
|
TerminateProgressBar();
|
|
|
|
SetLastError (rc);
|
|
|
|
if (rc == ERROR_CANCELLED) {
|
|
PostMessage (hdlg, WMX_REPORT_COMPLETE, 0, rc);
|
|
DEBUGMSG ((DBG_VERBOSE, "User requested to cancel"));
|
|
}
|
|
else if (!(*g_CancelFlagPtr)) {
|
|
//
|
|
// Advance the page when no error, otherwise cancel WINNT32
|
|
//
|
|
if (rc == 5 || rc == 32 || rc == 53 || rc == 54 || rc == 55 ||
|
|
rc == 65 || rc == 66 || rc == 67 || rc == 68 || rc == 88 ||
|
|
rc == 123 || rc == 148 || rc == 1203 || rc == 1222 ||
|
|
rc == 123 || rc == 2250
|
|
) {
|
|
|
|
//
|
|
// The error is caused by some sort of network or device
|
|
// failure. Give a general Access Denied message.
|
|
//
|
|
|
|
LOG ((LOG_ERROR, (PCSTR)MSG_ACCESS_DENIED));
|
|
|
|
} else if (rc != ERROR_SUCCESS) {
|
|
|
|
//
|
|
// Woah, totally unexpected error. Call Microsoft!!
|
|
//
|
|
|
|
if (rc < 1024) {
|
|
wsprintf (TextRc, TEXT("%u"), rc);
|
|
} else {
|
|
wsprintf (TextRc, TEXT("0%Xh"), rc);
|
|
}
|
|
|
|
LOG ((LOG_ERROR, __FUNCTION__ " failed, rc=%u", rc));
|
|
LOG ((LOG_FATAL_ERROR, (PCSTR)MSG_UNEXPECTED_ERROR_ENCOUNTERED, TextRc));
|
|
}
|
|
|
|
PostMessage (hdlg, WMX_REPORT_COMPLETE, 0, rc);
|
|
DEBUGMSG_IF ((
|
|
rc != ERROR_SUCCESS,
|
|
DBG_ERROR,
|
|
"Error in UI_ReportThread caused setup to terminate"
|
|
));
|
|
}
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PCTSTR UI_GetMemDbDat (void)
|
|
{
|
|
static TCHAR FileName[MAX_TCHAR_PATH];
|
|
|
|
StringCopy (FileName, g_TempDir);
|
|
StringCopy (AppendWack (FileName), S_NTSETUPDAT);
|
|
|
|
return FileName;
|
|
}
|
|
|
|
|
|
//
|
|
// WINNT32 calls this from a cleanup thread
|
|
//
|
|
|
|
VOID
|
|
UI_Cleanup(
|
|
VOID
|
|
)
|
|
{
|
|
MEMDB_ENUM e;
|
|
|
|
// Stop the worker thread
|
|
if (g_WorkerThreadHandle) {
|
|
MYASSERT (*g_CancelFlagPtr);
|
|
|
|
WaitForSingleObject (g_WorkerThreadHandle, INFINITE);
|
|
CloseHandle (g_WorkerThreadHandle);
|
|
g_WorkerThreadHandle = NULL;
|
|
}
|
|
|
|
// Require the background copy thread to complete
|
|
EndCopyThread();
|
|
|
|
if (!g_Terminated) {
|
|
// Delete anything in CancelFileDel
|
|
if (*g_CancelFlagPtr) {
|
|
if (MemDbGetValueEx (&e, MEMDB_CATEGORY_CANCELFILEDEL, NULL, NULL)) {
|
|
do {
|
|
SetFileAttributes (e.szName, FILE_ATTRIBUTE_NORMAL);
|
|
DeleteFile (e.szName);
|
|
} while (MemDbEnumNextValue (&e));
|
|
}
|
|
}
|
|
}
|
|
}
|