Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

504 lines
14 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. ui.c
  5. Abstract:
  6. The UI library contains all Win9x-side user interface code. UI_GetWizardPages
  7. is called by WINNT32 allowing the migration module to add its own wizard pages.
  8. UI_ReportThread is the thread that performs all report-phase migration processing.
  9. UI_Cleanup is called by WINNT32 when the user chooses to abort setup. The rest
  10. of the functions in this module support the progress bar.
  11. Author:
  12. Jim Schmidt (jimschm) 04-Mar-1997
  13. Revision History:
  14. Marc R. Whitten (marcw) 08-Jul-1998 - Ambigous Timezone page added.
  15. Jim Schmidt (jimschm) 21-Jan-1998 - Created macro expansion list for wizard pages
  16. Jim Schmidt (jimschm) 29-Jul-1997 - Moved accessible drives to here
  17. Marc R. Whitten (marcw) 25-Apr-1997 - Ras migration added.
  18. Marc R. Whitten (marcw) 21-Apr-1997 - hwcomp stuff moved to new wiz page.
  19. Checks for usable hdd and cdrom added.
  20. Marc R. Whitten (marcw) 14-Apr-1997 - Progress Bar handling revamped.
  21. --*/
  22. #include "pch.h"
  23. #include "uip.h"
  24. #include "drives.h"
  25. extern BOOL g_Terminated;
  26. /*++
  27. Macro Expansion List Description:
  28. PAGE_LIST lists each wizard page that will appear in any UI, in the order it appears
  29. in the wizard.
  30. Line Syntax:
  31. DEFMAC(DlgId, WizProc, Flags)
  32. Arguments:
  33. DlgId - Specifies the ID of a dialog. May not be zero. May be 1 if WizProc
  34. is NULL.
  35. WizProc - Specifies wizard proc for dialog ID. May be NULL to skip processing
  36. of page.
  37. Flags - Specifies one of the following:
  38. OPTIONAL_PAGE - Specifies page is not critical to the upgrade or
  39. incompatibility report
  40. REQUIRED_PAGE - Specifies page is required for the upgrade to work
  41. properly.
  42. Flags may also specify START_GROUP, a flag that begins a new group
  43. of wizard pages to pass back to WINNT32. Subsequent lines that do not
  44. have the START_GROUP flag are also added to the group.
  45. Currently there are exactly three groups. See winnt32p.h for details.
  46. Variables Generated From List:
  47. g_PageArray
  48. --*/
  49. #define PAGE_LIST \
  50. DEFMAC(IDD_BACKUP_PAGE, UI_BackupPageProc, START_GROUP|OPTIONAL_PAGE) \
  51. DEFMAC(IDD_HWCOMPDAT_PAGE, UI_HwCompDatPageProc, START_GROUP|REQUIRED_PAGE) \
  52. DEFMAC(IDD_BADCDROM_PAGE, UI_BadCdRomPageProc, OPTIONAL_PAGE) \
  53. DEFMAC(IDD_NAME_COLLISION_PAGE, UI_NameCollisionPageProc, REQUIRED_PAGE) \
  54. DEFMAC(IDD_BAD_TIMEZONE_PAGE, UI_BadTimeZonePageProc, OPTIONAL_PAGE) \
  55. DEFMAC(IDD_PREDOMAIN_PAGE, UI_PreDomainPageProc, REQUIRED_PAGE) \
  56. DEFMAC(IDD_DOMAIN_PAGE, UI_DomainPageProc, REQUIRED_PAGE) \
  57. DEFMAC(IDD_SUPPLY_MIGDLL_PAGE2, UI_UpgradeModulePageProc, OPTIONAL_PAGE) \
  58. DEFMAC(IDD_SCANNING_PAGE, UI_ScanningPageProc, START_GROUP|REQUIRED_PAGE) \
  59. DEFMAC(IDD_SUPPLY_DRIVER_PAGE2, UI_HardwareDriverPageProc, OPTIONAL_PAGE) \
  60. DEFMAC(IDD_BACKUP_YES_NO_PAGE, UI_BackupYesNoPageProc, REQUIRED_PAGE) \
  61. DEFMAC(IDD_BACKUP_DRIVE_SELECTION_PAGE, UI_BackupDriveSelectionProc,REQUIRED_PAGE) \
  62. DEFMAC(IDD_BACKUP_IMPOSSIBLE_INFO_PAGE, UI_BackupImpossibleInfoProc,REQUIRED_PAGE) \
  63. DEFMAC(IDD_BACKUP_IMPOSSIBLE_INFO_1_PAGE, UI_BackupImpExceedLimitProc,REQUIRED_PAGE) \
  64. DEFMAC(IDD_RESULTS_PAGE2, UI_ResultsPageProc, REQUIRED_PAGE) \
  65. DEFMAC(IDD_LAST_PAGE, UI_LastPageProc, OPTIONAL_PAGE) \
  66. // DEFMAC(IDD_BADHARDDRIVE_PAGE, UI_BadHardDrivePageProc, OPTIONAL_PAGE) \
  67. //
  68. // Create the macro expansion that defines g_PageArray
  69. //
  70. typedef BOOL(WINNT32_WIZARDPAGE_PROC_PROTOTYPE)(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  71. typedef WINNT32_WIZARDPAGE_PROC_PROTOTYPE *WINNT32_WIZARDPAGE_PROC;
  72. #define START_GROUP 0x0001
  73. #define OPTIONAL_PAGE 0x0002
  74. #define REQUIRED_PAGE 0x0000
  75. typedef struct {
  76. UINT DlgId;
  77. WINNT32_WIZARDPAGE_PROC WizProc;
  78. DWORD Flags;
  79. } WIZPAGE_DEFINITION, *PWIZPAGE_DEFINITION;
  80. #define DEFMAC(id,fn,flags) WINNT32_WIZARDPAGE_PROC_PROTOTYPE fn;
  81. PAGE_LIST
  82. #undef DEFMAC
  83. #define DEFMAC(id,fn,flags) {id,fn,flags},
  84. WIZPAGE_DEFINITION g_PageArray[] = {
  85. PAGE_LIST /* , */
  86. {0, NULL, 0}
  87. };
  88. #undef DEFMAC
  89. //
  90. // Globals
  91. //
  92. HANDLE g_WorkerThreadHandle = NULL;
  93. //
  94. // Implementation
  95. //
  96. BOOL
  97. WINAPI
  98. UI_Entry (
  99. IN HINSTANCE hinstDLL,
  100. IN DWORD dwReason,
  101. IN PVOID lpv
  102. )
  103. {
  104. switch (dwReason) {
  105. case DLL_PROCESS_ATTACH:
  106. if (!InitCompatTable()) {
  107. return FALSE;
  108. }
  109. MsgMgr_Init();
  110. RegisterTextViewer();
  111. break;
  112. case DLL_PROCESS_DETACH:
  113. FreeCompatTable();
  114. MsgMgr_Cleanup();
  115. FreePunctTable();
  116. break;
  117. }
  118. return TRUE;
  119. }
  120. DWORD
  121. UI_GetWizardPages (
  122. OUT UINT *FirstCountPtr,
  123. OUT PROPSHEETPAGE **FirstArray,
  124. OUT UINT *SecondCountPtr,
  125. OUT PROPSHEETPAGE **SecondArray,
  126. OUT UINT *ThirdCountPtr,
  127. OUT PROPSHEETPAGE **ThirdArray
  128. )
  129. /*++
  130. Routine Description:
  131. UI_GetWizardPages is called by WINNT32 when it is preparing the wizard (very
  132. early in Setup). It inserts pages we give it into its wizard page array and
  133. then creates the wizard. Eventually our wizard procs get called (see wizproc.c)
  134. no matter if we are upgrading or not.
  135. The first array comes right after the user chooses to upgrade or not to upgrade.
  136. The second array comes after the user has specified the source directory.
  137. The third array comes after DOSNET.INF has been processed.
  138. Arguments:
  139. FirstCountPtr - Receives the number of elements of FirstArray
  140. FirstArray - Receives a pointer to an initialized array of PROPSHEETPAGE elements.
  141. These pages are inserted immediately after the page giving the user
  142. a choice to upgrade.
  143. SecondCountPtr - Receives the number of elements of SecondArray
  144. SecondArray - Receives a pointer to an initialized array of PROPSHEETPAGE elements.
  145. These pages are inserted immediately after the NT media directory has
  146. been chosen.
  147. ThirdCountPtr - Receives the number of elements of ThridArray
  148. ThirdArray - Receives a pointer to an initialized array of PROPSHEETPAGE elements.
  149. These pages are inserted immediately after the DOSNET.INF processing
  150. page.
  151. Return Value:
  152. Win32 status code.
  153. --*/
  154. {
  155. static PROPSHEETPAGE StaticPageArray[32];
  156. INT i, j, k;
  157. UINT *CountPtrs[3];
  158. PROPSHEETPAGE **PageArrayPtrs[3];
  159. CountPtrs[0] = FirstCountPtr;
  160. CountPtrs[1] = SecondCountPtr;
  161. CountPtrs[2] = ThirdCountPtr;
  162. PageArrayPtrs[0] = FirstArray;
  163. PageArrayPtrs[1] = SecondArray;
  164. PageArrayPtrs[2] = ThirdArray;
  165. MYASSERT (g_PageArray[0].Flags & START_GROUP);
  166. for (i = 0, j = -1, k = 0 ; g_PageArray[i].DlgId ; i++) {
  167. MYASSERT (k < 32);
  168. //
  169. // Set the array start pointer
  170. //
  171. if (g_PageArray[i].Flags & START_GROUP) {
  172. j++;
  173. MYASSERT (j >= 0 && j <= 2);
  174. *CountPtrs[j] = 0;
  175. *PageArrayPtrs[j] = &StaticPageArray[k];
  176. }
  177. //
  178. // Allow group to be skipped with NULL function. Also, guard against
  179. // array declaration bug.
  180. //
  181. if (!g_PageArray[i].WizProc || j < 0 || j > 2) {
  182. continue;
  183. }
  184. ZeroMemory (&StaticPageArray[k], sizeof (PROPSHEETPAGE));
  185. StaticPageArray[k].dwSize = sizeof (PROPSHEETPAGE);
  186. StaticPageArray[k].dwFlags = PSP_DEFAULT;
  187. StaticPageArray[k].hInstance = g_hInst;
  188. StaticPageArray[k].pszTemplate = MAKEINTRESOURCE(g_PageArray[i].DlgId);
  189. StaticPageArray[k].pfnDlgProc = g_PageArray[i].WizProc;
  190. k++;
  191. *CountPtrs[j] += 1;
  192. }
  193. return ERROR_SUCCESS;
  194. }
  195. DWORD
  196. UI_CreateNewHwCompDat (
  197. PVOID p
  198. )
  199. {
  200. HWND hdlg;
  201. DWORD rc = ERROR_SUCCESS;
  202. UINT SliceId;
  203. hdlg = (HWND) p;
  204. __try {
  205. //
  206. // This code executes only when the hwcomp.dat file needs to
  207. // be rebuilt. It runs in a separate thread so the UI is
  208. // responsive.
  209. //
  210. InitializeProgressBar (
  211. GetDlgItem (hdlg, IDC_PROGRESS),
  212. GetDlgItem (hdlg, IDC_COMPONENT),
  213. GetDlgItem (hdlg, IDC_SUBCOMPONENT),
  214. g_CancelFlagPtr
  215. );
  216. ProgressBar_SetComponentById(MSG_PREPARING_LIST);
  217. ProgressBar_SetSubComponent(NULL);
  218. SliceId = RegisterProgressBarSlice (HwComp_GetProgressMax());
  219. BeginSliceProcessing (SliceId);
  220. if (!CreateNtHardwareList (
  221. SOURCEDIRECTORYARRAY(),
  222. SOURCEDIRECTORYCOUNT(),
  223. NULL,
  224. REGULAR_OUTPUT
  225. )) {
  226. DEBUGMSG ((DBG_ERROR, "hwcomp.dat could not be generated"));
  227. rc = GetLastError();
  228. }
  229. EndSliceProcessing();
  230. ProgressBar_SetComponent(NULL);
  231. ProgressBar_SetSubComponent(NULL);
  232. TerminateProgressBar();
  233. }
  234. __finally {
  235. SetLastError (rc);
  236. if (!(*g_CancelFlagPtr)) {
  237. //
  238. // Advance the page when no error, otherwise cancel WINNT32
  239. //
  240. PostMessage (hdlg, WMX_REPORT_COMPLETE, 0, rc);
  241. DEBUGMSG_IF ((
  242. rc != ERROR_SUCCESS,
  243. DBG_ERROR,
  244. "Error in UI_CreateNewHwCompDat caused setup to terminate"
  245. ));
  246. }
  247. }
  248. return rc;
  249. }
  250. DWORD
  251. UI_ReportThread (
  252. PVOID p
  253. )
  254. {
  255. HWND hdlg;
  256. DWORD rc = ERROR_SUCCESS;
  257. TCHAR TextRc[32];
  258. hdlg = (HWND) p;
  259. //
  260. // Start the progress bar
  261. //
  262. InitializeProgressBar (
  263. GetDlgItem (hdlg, IDC_PROGRESS),
  264. GetDlgItem (hdlg, IDC_COMPONENT),
  265. GetDlgItem (hdlg, IDC_SUBCOMPONENT),
  266. g_CancelFlagPtr
  267. );
  268. ProgressBar_SetComponentById(MSG_PREPARING_LIST);
  269. PrepareProcessingProgressBar();
  270. //
  271. // Process each component
  272. //
  273. __try {
  274. DEBUGLOGTIME (("Starting System First Routines"));
  275. rc = RunSysFirstMigrationRoutines ();
  276. if (rc != ERROR_SUCCESS) {
  277. __leave;
  278. }
  279. DEBUGLOGTIME (("Starting user functions"));
  280. rc = RunUserMigrationRoutines ();
  281. if (rc != ERROR_SUCCESS) {
  282. __leave;
  283. }
  284. DEBUGLOGTIME (("Starting System Last Routines"));
  285. rc = RunSysLastMigrationRoutines ();
  286. if (rc != ERROR_SUCCESS) {
  287. __leave;
  288. }
  289. ProgressBar_SetComponent(NULL);
  290. ProgressBar_SetSubComponent(NULL);
  291. }
  292. __finally {
  293. TerminateProgressBar();
  294. SetLastError (rc);
  295. if (rc == ERROR_CANCELLED) {
  296. PostMessage (hdlg, WMX_REPORT_COMPLETE, 0, rc);
  297. DEBUGMSG ((DBG_VERBOSE, "User requested to cancel"));
  298. }
  299. else if (!(*g_CancelFlagPtr)) {
  300. //
  301. // Advance the page when no error, otherwise cancel WINNT32
  302. //
  303. if (rc == 5 || rc == 32 || rc == 53 || rc == 54 || rc == 55 ||
  304. rc == 65 || rc == 66 || rc == 67 || rc == 68 || rc == 88 ||
  305. rc == 123 || rc == 148 || rc == 1203 || rc == 1222 ||
  306. rc == 123 || rc == 2250
  307. ) {
  308. //
  309. // The error is caused by some sort of network or device
  310. // failure. Give a general Access Denied message.
  311. //
  312. LOG ((LOG_ERROR, (PCSTR)MSG_ACCESS_DENIED));
  313. } else if (rc != ERROR_SUCCESS) {
  314. //
  315. // Woah, totally unexpected error. Call Microsoft!!
  316. //
  317. if (rc < 1024) {
  318. wsprintf (TextRc, TEXT("%u"), rc);
  319. } else {
  320. wsprintf (TextRc, TEXT("0%Xh"), rc);
  321. }
  322. LOG ((LOG_ERROR, __FUNCTION__ " failed, rc=%u", rc));
  323. LOG ((LOG_FATAL_ERROR, (PCSTR)MSG_UNEXPECTED_ERROR_ENCOUNTERED, TextRc));
  324. }
  325. PostMessage (hdlg, WMX_REPORT_COMPLETE, 0, rc);
  326. DEBUGMSG_IF ((
  327. rc != ERROR_SUCCESS,
  328. DBG_ERROR,
  329. "Error in UI_ReportThread caused setup to terminate"
  330. ));
  331. }
  332. }
  333. return rc;
  334. }
  335. PCTSTR UI_GetMemDbDat (void)
  336. {
  337. static TCHAR FileName[MAX_TCHAR_PATH];
  338. StringCopy (FileName, g_TempDir);
  339. StringCopy (AppendWack (FileName), S_NTSETUPDAT);
  340. return FileName;
  341. }
  342. //
  343. // WINNT32 calls this from a cleanup thread
  344. //
  345. VOID
  346. UI_Cleanup(
  347. VOID
  348. )
  349. {
  350. MEMDB_ENUM e;
  351. // Stop the worker thread
  352. if (g_WorkerThreadHandle) {
  353. MYASSERT (*g_CancelFlagPtr);
  354. WaitForSingleObject (g_WorkerThreadHandle, INFINITE);
  355. CloseHandle (g_WorkerThreadHandle);
  356. g_WorkerThreadHandle = NULL;
  357. }
  358. // Require the background copy thread to complete
  359. EndCopyThread();
  360. if (!g_Terminated) {
  361. // Delete anything in CancelFileDel
  362. if (*g_CancelFlagPtr) {
  363. if (MemDbGetValueEx (&e, MEMDB_CATEGORY_CANCELFILEDEL, NULL, NULL)) {
  364. do {
  365. SetFileAttributes (e.szName, FILE_ATTRIBUTE_NORMAL);
  366. DeleteFile (e.szName);
  367. } while (MemDbEnumNextValue (&e));
  368. }
  369. }
  370. }
  371. }