Leaked source code of windows server 2003
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.

1477 lines
39 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. welcome.c
  5. Abstract:
  6. Routines for welcomong the user.
  7. Author:
  8. Ted Miller (tedm) 27-July-1995
  9. Revision History:
  10. --*/
  11. #include "setupp.h"
  12. #pragma hdrstop
  13. #define HARWARE_DETECTION_BOOT_TIMEOUT 5
  14. extern BOOLEAN
  15. AsrIsEnabled( VOID );
  16. //
  17. // Setup mode (custom, typical, laptop, etc)
  18. //
  19. UINT SetupMode = SETUPMODE_TYPICAL;
  20. //
  21. // Flag telling us whether we've already prepared for installation.
  22. //
  23. BOOL PreparedAlready;
  24. static HBRUSH s_hbrWindow = NULL;
  25. VOID AdjustAndPaintWatermarkBitmap(
  26. IN HWND hdlg,
  27. IN HDC hdc
  28. )
  29. /*
  30. Function used to adjust and paint the watermark bitmap so that it will fit correctly
  31. into the welcome and finish window, even if it is scalled differently than
  32. it would look when run on a usa build.
  33. some code borrowed from winnt32\dll\{rsrcutil,wizard}.c
  34. some code borrowed from shell\comctl32\prsht.c
  35. Arguments:
  36. hdlg, input handle for the window which the dialog shall be drawn into.
  37. hdc, input device context of the current window.
  38. Return Value:
  39. none: this is an attempt to scale the bitmap correctly for the cases
  40. where the win2k logo will be clipped. In order to get a chance to scale
  41. the bitmap, we can not let wiz97 take care of it, and thus if this function
  42. fails, there will be no watermark drawn.
  43. We treat errors in a way similarly
  44. to how property sheet would, which is that while we won't die hard, we
  45. make sure not to use any NULL resources.
  46. */
  47. {
  48. RECT rect;
  49. HBITMAP hDib;
  50. HRSRC BlockHandle;
  51. HGLOBAL MemoryHandle;
  52. BITMAPINFOHEADER *BitmapInfoHeader;
  53. BITMAPINFO *BitmapInfo;
  54. HDC MemDC;
  55. UINT ColorCount;
  56. HPALETTE PreviousPalette;
  57. HBITMAP Bitmap;
  58. BOOLEAN b;
  59. PVOID Bits;
  60. PVOID Bits2;
  61. int i;
  62. s_hbrWindow = GetSysColorBrush(COLOR_WINDOW);
  63. BlockHandle = FindResource(MyModuleHandle,MAKEINTRESOURCE(IDB_BITMAP1),RT_BITMAP);
  64. if(!BlockHandle) {
  65. SetupDebugPrint1(L"SETUP: AdjustAndPaintWatermarkBitmap: Couldn't find resource, error %d\n",
  66. GetLastError());
  67. //nothing to clean up.
  68. return;
  69. }
  70. MemoryHandle = LoadResource(MyModuleHandle,BlockHandle);
  71. if(!MemoryHandle) {
  72. SetupDebugPrint1(L"SETUP: AdjustAndPaintWatermarkBitmap: Couldn't load resource, error %d\n",
  73. GetLastError());
  74. //nothing to clean up.
  75. return;
  76. }
  77. BitmapInfoHeader = LockResource(MemoryHandle);
  78. if(BitmapInfoHeader == NULL) {
  79. SetupDebugPrint1(L"SETUP: AdjustAndPaintWatermarkBitmap: Couldn't lock resource, error %d\n",
  80. GetLastError());
  81. goto c0;
  82. }
  83. // First we have to paint the background on the right side of the window
  84. // (this is not auto done for us because we aren't using the wizard's watermark)
  85. GetClientRect(hdlg,&rect);
  86. rect.left = BitmapInfoHeader->biWidth;
  87. FillRect(hdc,&rect,s_hbrWindow);
  88. ColorCount = (BitmapInfoHeader->biBitCount <= 8)
  89. ? (1 << BitmapInfoHeader->biBitCount)
  90. : 0;
  91. BitmapInfo = MyMalloc(BitmapInfoHeader->biSize + (ColorCount * sizeof(RGBQUAD)));
  92. if (!BitmapInfo){
  93. SetupDebugPrint(L"SETUP: AdjustAndPaintWatermarkBitmap: Couldn't malloc BitmapInfo.\n");
  94. goto c0;
  95. }
  96. CopyMemory(
  97. BitmapInfo,
  98. BitmapInfoHeader,
  99. BitmapInfoHeader->biSize + (ColorCount * sizeof(RGBQUAD))
  100. );
  101. BitmapInfo->bmiHeader.biHeight = rect.bottom;
  102. BitmapInfo->bmiHeader.biWidth = BitmapInfoHeader->biWidth;
  103. hDib = CreateDIBSection(NULL,BitmapInfo,DIB_RGB_COLORS,&Bits,NULL,0);
  104. if(!hDib) {
  105. SetupDebugPrint1(L"SETUP: AdjustAndPaintWatermarkBitmap: Couldn't create DIB, error %d\n",
  106. GetLastError());
  107. goto c1;
  108. }
  109. //
  110. // Create a "template" memory DC and select the DIB we created
  111. // into it. Passing NULL to CreateCompatibleDC creates a DC into which
  112. // any format bitmap can be selected. We don't want to use the dialog's
  113. // DC because if the pixel depth of the watermark bitmap differs from
  114. // the screen, we wouldn't be able to select the dib into the mem dc.
  115. //
  116. MemDC = CreateCompatibleDC(NULL);
  117. if(!MemDC) {
  118. SetupDebugPrint1(L"SETUP: AdjustAndPaintWatermarkBitmap: Couldn't create DC, error %d\n",
  119. GetLastError());
  120. goto c2;
  121. }
  122. if (!SelectObject(MemDC,hDib)){
  123. SetupDebugPrint1(L"SETUP: AdjustAndPaintWatermarkBitmap: Couldn't Select DC, error %d\n",
  124. GetLastError());
  125. goto c3;
  126. }
  127. //
  128. // Do the stretch operation from the source bitmap onto
  129. // the dib.
  130. //
  131. Bits2 = (LPBYTE)BitmapInfoHeader + BitmapInfoHeader->biSize + (ColorCount * sizeof(RGBQUAD));
  132. SetStretchBltMode(MemDC,COLORONCOLOR);
  133. i = StretchDIBits(
  134. MemDC,
  135. 0,0,
  136. BitmapInfoHeader->biWidth,
  137. rect.bottom,
  138. 0,0,
  139. BitmapInfoHeader->biWidth,
  140. BitmapInfoHeader->biHeight,
  141. Bits2,
  142. (BITMAPINFO *)BitmapInfoHeader,
  143. DIB_RGB_COLORS,
  144. SRCCOPY
  145. );
  146. if(i == GDI_ERROR) {
  147. SetupDebugPrint1(L"SETUP: AdjustAndPaintWatermarkBitmap: Couldn't stretch bitmap, error %d\n",
  148. GetLastError());
  149. goto c3;
  150. }
  151. i = BitBlt(hdc,0,0,BitmapInfoHeader->biWidth,rect.bottom,MemDC,0,0,SRCCOPY);
  152. if (0 == i){
  153. SetupDebugPrint1(L"SETUP: AdjustAndPaintWatermarkBitmap: Couldn't paint bitmap, error %d\n",
  154. GetLastError());
  155. }
  156. c3:
  157. DeleteDC(MemDC);
  158. c2:
  159. DeleteObject(hDib);
  160. c1:
  161. MyFree(BitmapInfo);
  162. c0:
  163. DeleteObject(MemoryHandle);
  164. }
  165. INT_PTR
  166. CALLBACK
  167. WelcomeDlgProc(
  168. IN HWND hdlg,
  169. IN UINT msg,
  170. IN WPARAM wParam,
  171. IN LPARAM lParam
  172. )
  173. /*++
  174. Routine Description:
  175. Dialog procedure for first wizard page of Setup.
  176. It essentially just welcomes the user.
  177. Arguments:
  178. Standard dialog procedure arguments.
  179. Return Value:
  180. Standard dialog procedure return.
  181. --*/
  182. {
  183. HFONT Font;
  184. LOGFONT LogFont;
  185. WCHAR str[20];
  186. int Height;
  187. HDC hdc;
  188. NMHDR *NotifyParams;
  189. PVOID p;
  190. static BOOL FirstInit=TRUE,FirstTime=TRUE;
  191. switch(msg) {
  192. case WM_INITDIALOG:
  193. WizardHandle = GetParent (hdlg);
  194. if((Font = (HFONT)SendDlgItemMessage(hdlg,IDT_STATIC_1,WM_GETFONT,0,0))
  195. && GetObject(Font,sizeof(LOGFONT),&LogFont)) {
  196. LogFont.lfWeight = FW_BOLD;
  197. if(!LoadString(MyModuleHandle, IDS_WELCOME_FONT_NAME, LogFont.lfFaceName, LF_FACESIZE)){
  198. LogFont.lfFaceName[LF_FACESIZE - 1] = '\0';
  199. }
  200. if(!LoadString(MyModuleHandle, IDS_WELCOME_FONT_SIZE, str, ARRAYSIZE(str))){
  201. str[ARRAYSIZE(str) - 1] = '\0';
  202. }
  203. Height = (int)wcstoul(str,NULL,10);
  204. if(hdc = GetDC(hdlg)) {
  205. LogFont.lfHeight = 0 - (GetDeviceCaps(hdc,LOGPIXELSY) * Height / 72);
  206. if(Font = CreateFontIndirect(&LogFont)) {
  207. SendDlgItemMessage(hdlg,IDT_STATIC_1,WM_SETFONT,(WPARAM)Font,MAKELPARAM(TRUE,0));
  208. }
  209. ReleaseDC(hdlg,hdc);
  210. }
  211. }
  212. if(p = MyLoadString((ProductType == PRODUCT_WORKSTATION) ?
  213. IDS_WORKSTATION_WELCOME_1 : IDS_SERVER_WELCOME_1)) {
  214. //
  215. // Use this instead of SetText because we need to pass wParam
  216. // to the control.
  217. //
  218. SendDlgItemMessage(hdlg,IDT_STATIC_2,WM_SETTEXT,0,(LPARAM)p);
  219. MyFree(p);
  220. }
  221. if(p = MyLoadString((ProductType == PRODUCT_WORKSTATION) ?
  222. IDS_WORKSTATION_WELCOME_2 : IDS_SERVER_WELCOME_2)) {
  223. //
  224. // Use this instead of SetText because we need to pass wParam
  225. // to the control.
  226. //
  227. SendDlgItemMessage(hdlg,IDT_STATIC_3,WM_SETTEXT,0,(LPARAM)p);
  228. MyFree(p);
  229. }
  230. #define SECOND 1000
  231. // Don't set the timer if we have a billboard, we don't show the page.
  232. if (FirstInit && !Unattended && (GetBBhwnd() == NULL)) {
  233. SetTimer(hdlg,1,10 * SECOND,NULL);
  234. FirstInit = FALSE;
  235. }
  236. #if 0
  237. //
  238. // Load steps text and set.
  239. //
  240. if(Preinstall) {
  241. //
  242. // Hide some text and don't display any steps.
  243. //
  244. ShowWindow(GetDlgItem(hdlg,IDT_STATIC_3),SW_HIDE);
  245. EnableWindow(GetDlgItem(hdlg,IDT_STATIC_3),FALSE);
  246. } else {
  247. if(p = MyLoadString(Upgrade ? IDS_STEPS_UPGRADE : IDS_STEPS)) {
  248. //
  249. // Use this instead of SetText because we need to pass wParam
  250. // to the control.
  251. //
  252. SendDlgItemMessage(hdlg,IDC_LIST1,WM_SETTEXT,0,(LPARAM)p);
  253. MyFree(p);
  254. }
  255. }
  256. //
  257. // Set up some of the static text on this page, which uses different
  258. // effects (boldface, different fonts, etc).
  259. //
  260. {
  261. HFONT Font;
  262. LOGFONT LogFont;
  263. WCHAR str[20];
  264. int Height;
  265. HDC hdc;
  266. //
  267. // First handle the text that "introduces" the title, which is in
  268. // the same font as the rest of the dialog, only bold.
  269. //
  270. if((Font = (HFONT)SendDlgItemMessage(hdlg,IDT_STATIC_1,WM_GETFONT,0,0))
  271. && GetObject(Font,sizeof(LOGFONT),&LogFont)) {
  272. LogFont.lfWeight = FW_BOLD;
  273. if(Font = CreateFontIndirect(&LogFont)) {
  274. SendDlgItemMessage(hdlg,IDT_STATIC_1,WM_SETFONT,(WPARAM)Font,MAKELPARAM(TRUE,0));
  275. }
  276. }
  277. //
  278. // Next do the title, which is in a different font, larger and in boldface.
  279. //
  280. if((Font = (HFONT)SendDlgItemMessage(hdlg,IDT_STATIC_2,WM_GETFONT,0,0))
  281. && GetObject(Font,sizeof(LOGFONT),&LogFont)) {
  282. LogFont.lfWeight = FW_BOLD;
  283. if(!LoadString(MyModuleHandle, IDS_MSSERIF, LogFont.lfFaceName, LF_FACESIZE){
  284. LogFont.lfFaceName[LF_FACESIZE - 1] = '\0';
  285. }
  286. if(!LoadString(MyModuleHandle, IDS_LARGEFONTSIZE, str, ARRAYSIZE(str)){
  287. str[ARRAYSIZE(str) - 1] = '\0';
  288. }
  289. Height = (int)wcstoul(str,NULL,10);
  290. if(hdc = GetDC(hdlg)) {
  291. LogFont.lfHeight = 0 - (GetDeviceCaps(hdc,LOGPIXELSY) * Height / 72);
  292. if(Font = CreateFontIndirect(&LogFont)) {
  293. SendDlgItemMessage(hdlg,IDT_STATIC_2,WM_SETFONT,(WPARAM)Font,MAKELPARAM(TRUE,0));
  294. }
  295. ReleaseDC(hdlg,hdc);
  296. }
  297. }
  298. }
  299. #endif
  300. //
  301. // Center the wizard dialog on-screen.
  302. //
  303. // if we have the BB window, do the positioning on that. MainWindowHandle point to that window
  304. //
  305. if (GetBBhwnd())
  306. CenterWindowRelativeToWindow(GetParent(hdlg), MainWindowHandle, TRUE);
  307. else
  308. pSetupCenterWindowRelativeToParent(GetParent(hdlg));
  309. break;
  310. case WM_SIMULATENEXT:
  311. // Simulate the next button somehow
  312. PropSheet_PressButton( GetParent(hdlg), PSBTN_NEXT);
  313. break;
  314. case WMX_VALIDATE:
  315. // No data on this page, unattended should skip it
  316. return ReturnDlgResult (hdlg, VALIDATE_DATA_OK);
  317. case WM_TIMER:
  318. KillTimer(hdlg, 1);
  319. if (FirstTime) {
  320. PropSheet_PressButton( GetParent(hdlg), PSBTN_NEXT);
  321. FirstTime = FALSE;
  322. }
  323. break;
  324. case WM_CTLCOLOREDIT:
  325. case WM_CTLCOLORDLG:
  326. case WM_CTLCOLORMSGBOX:
  327. case WM_CTLCOLORLISTBOX:
  328. case WM_CTLCOLORBTN:
  329. case WM_CTLCOLORSCROLLBAR:
  330. case WM_CTLCOLORSTATIC:
  331. SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT));
  332. SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW));
  333. return (LRESULT)s_hbrWindow;
  334. case WM_ERASEBKGND:
  335. AdjustAndPaintWatermarkBitmap(hdlg,(HDC)wParam);
  336. break;
  337. case WM_NOTIFY:
  338. NotifyParams = (NMHDR *)lParam;
  339. switch(NotifyParams->code) {
  340. case PSN_SETACTIVE:
  341. TESTHOOK(510);
  342. BEGIN_SECTION(L"Welcome Page");
  343. SetWizardButtons(hdlg,WizPageWelcome);
  344. if(Preinstall) {
  345. //
  346. // Show unless OEMSkipWelcome = 1
  347. //
  348. if (GetPrivateProfileInt(pwGuiUnattended,L"OEMSkipWelcome",0,AnswerFile)) {
  349. FirstTime = FALSE;
  350. }
  351. SetWindowLongPtr(
  352. hdlg,
  353. DWLP_MSGRESULT,
  354. GetPrivateProfileInt(pwGuiUnattended,L"OEMSkipWelcome",0,AnswerFile) ? -1 : 0
  355. );
  356. } else {
  357. FirstTime = FALSE;
  358. if(Unattended) {
  359. UnattendSetActiveDlg(hdlg,IDD_WELCOME);
  360. }
  361. else if (GetBBhwnd() != NULL)
  362. {
  363. // If we have a billoard, don't show the page.
  364. SetWindowLongPtr(hdlg,DWLP_MSGRESULT,-1);
  365. }
  366. }
  367. break;
  368. case PSN_WIZNEXT:
  369. FirstTime = FALSE;
  370. SetWindowLongPtr(hdlg,DWLP_MSGRESULT,0);
  371. break;
  372. case PSN_KILLACTIVE:
  373. END_SECTION(L"Welcome Page");
  374. default:
  375. break;
  376. }
  377. break;
  378. default:
  379. return(FALSE);
  380. }
  381. return(TRUE);
  382. }
  383. //
  384. // global variable used for subclassing.
  385. //
  386. WNDPROC OldEditProc;
  387. LRESULT
  388. CALLBACK
  389. EulaEditSubProc(
  390. IN HWND hwnd,
  391. IN UINT msg,
  392. IN WPARAM wParam,
  393. IN LPARAM lParam
  394. )
  395. /*++
  396. Routine Description:
  397. Edit control subclass routine, to avoid highlighting text when user
  398. tabs to the edit control.
  399. Arguments:
  400. Standard window proc arguments.
  401. Returns:
  402. Message-dependent value.
  403. --*/
  404. {
  405. //
  406. // For setsel messages, make start and end the same.
  407. //
  408. if((msg == EM_SETSEL) && ((LPARAM)wParam != lParam)) {
  409. lParam = wParam;
  410. }
  411. return(CallWindowProc(OldEditProc,hwnd,msg,wParam,lParam));
  412. }
  413. INT_PTR
  414. CALLBACK
  415. EulaDlgProc(
  416. IN HWND hdlg,
  417. IN UINT msg,
  418. IN WPARAM wParam,
  419. IN LPARAM lParam
  420. )
  421. /*++
  422. Routine Description:
  423. Dialog procedure for the wizard page that displays the End User License
  424. Agreement.
  425. Arguments:
  426. Standard dialog procedure arguments.
  427. Return Value:
  428. Standard dialog procedure return.
  429. --*/
  430. {
  431. NMHDR *NotifyParams;
  432. HWND EditControl;
  433. WCHAR EulaPath[MAX_PATH];
  434. static HANDLE hFile = NULL, hFileMapping = NULL;
  435. DWORD FileSize;
  436. static BYTE *pbFile = NULL;
  437. static PWSTR EulaText = NULL;
  438. int i;
  439. switch(msg) {
  440. case WM_INITDIALOG:
  441. //
  442. // If not preinstall then this was displayed at start of text mode
  443. // and we don't do it here.
  444. //
  445. if (EulaComplete || TextmodeEula || OemSkipEula) {
  446. break;
  447. }
  448. //
  449. // Map the file containing the licensing agreement.
  450. //
  451. if(!GetSystemDirectory(EulaPath, MAX_PATH)){
  452. FatalError(MSG_EULA_ERROR,0,0);
  453. }
  454. pSetupConcatenatePaths (EulaPath, L"eula.txt", MAX_PATH, NULL);
  455. hFile = CreateFile (
  456. EulaPath,
  457. GENERIC_READ,
  458. 0,
  459. NULL,
  460. OPEN_EXISTING,
  461. FILE_ATTRIBUTE_NORMAL,
  462. NULL
  463. );
  464. if(hFile == INVALID_HANDLE_VALUE) {
  465. FatalError(MSG_EULA_ERROR,0,0);
  466. }
  467. hFileMapping = CreateFileMapping (
  468. hFile,
  469. NULL,
  470. PAGE_READONLY,
  471. 0, 0,
  472. NULL
  473. );
  474. if(hFileMapping == NULL) {
  475. FatalError(MSG_EULA_ERROR,0,0);
  476. }
  477. pbFile = MapViewOfFile (
  478. hFileMapping,
  479. FILE_MAP_READ,
  480. 0, 0,
  481. 0
  482. );
  483. if(pbFile == NULL) {
  484. FatalError(MSG_EULA_ERROR,0,0);
  485. }
  486. //
  487. // Translate the text from ANSI to Unicode.
  488. //
  489. FileSize = GetFileSize (hFile, NULL);
  490. if(FileSize == 0xFFFFFFFF) {
  491. FatalError(MSG_EULA_ERROR,0,0);
  492. }
  493. EulaText = MyMalloc ((FileSize+1) * sizeof(WCHAR));
  494. if(EulaText == NULL) {
  495. FatalError(MSG_EULA_ERROR,0,0);
  496. }
  497. MultiByteToWideChar (
  498. CP_ACP,
  499. 0,
  500. pbFile,
  501. FileSize,
  502. EulaText,
  503. FileSize+1
  504. );
  505. EulaText[FileSize] = 0;
  506. EditControl = GetDlgItem(hdlg,IDT_EDIT1);
  507. OldEditProc = (WNDPROC)GetWindowLongPtr(EditControl,GWLP_WNDPROC);
  508. SetWindowLongPtr(EditControl,GWLP_WNDPROC,(LONG_PTR)EulaEditSubProc);
  509. SetWindowText(EditControl,(PCWSTR)EulaText);
  510. break;
  511. case WM_DESTROY:
  512. //
  513. // Clean up
  514. //
  515. if( EulaText )
  516. MyFree (EulaText);
  517. if (pbFile)
  518. UnmapViewOfFile (pbFile);
  519. if (hFileMapping)
  520. CloseHandle (hFileMapping);
  521. if (hFile)
  522. CloseHandle (hFile);
  523. break;
  524. case WM_SIMULATENEXT:
  525. PropSheet_PressButton( GetParent(hdlg), PSBTN_NEXT);
  526. break;
  527. case WM_NOTIFY:
  528. NotifyParams = (NMHDR *)lParam;
  529. switch(NotifyParams->code) {
  530. case PSN_SETACTIVE:
  531. TESTHOOK(511);
  532. BEGIN_SECTION(L"Eula Page");
  533. SetWizardButtons(hdlg,WizPageEula);
  534. SetFocus(GetDlgItem(hdlg,IDYES));
  535. if (EulaComplete || TextmodeEula || OemSkipEula) {
  536. SetWindowLongPtr(hdlg,DWLP_MSGRESULT,-1);
  537. END_SECTION(L"Eula Page");
  538. } else {
  539. SetWindowLongPtr(hdlg,DWLP_MSGRESULT,0);
  540. // Make sure we're initialized if we're going to show it.
  541. MYASSERT(EulaText);
  542. }
  543. break;
  544. case PSN_WIZBACK:
  545. case PSN_WIZNEXT:
  546. case PSN_WIZFINISH:
  547. //
  548. // Allow the next page to be activated.
  549. //
  550. SetWindowLongPtr(hdlg,DWLP_MSGRESULT,0);
  551. break;
  552. case PSN_KILLACTIVE:
  553. if(IsDlgButtonChecked(hdlg,IDYES)) {
  554. SetWindowLongPtr(hdlg,DWLP_MSGRESULT,0);
  555. } else {
  556. //
  557. // Are you sure you want to exit?
  558. //
  559. i = MessageBoxFromMessage(
  560. hdlg,
  561. MSG_SURE_EXIT,
  562. FALSE,
  563. IDS_WINNT_SETUP,
  564. MB_YESNO | MB_ICONQUESTION | MB_TASKMODAL | MB_DEFBUTTON2
  565. );
  566. if(i == IDYES) {
  567. FatalError(MSG_NOT_ACCEPT_EULA,0,0);
  568. } else {
  569. SetWindowLongPtr(hdlg,DWLP_MSGRESULT,-1);
  570. }
  571. END_SECTION(L"Eula Page");
  572. }
  573. break;
  574. default:
  575. break;
  576. }
  577. break;
  578. default:
  579. return(FALSE);
  580. }
  581. return(TRUE);
  582. }
  583. INT_PTR
  584. CALLBACK
  585. StepsDlgProc(
  586. IN HWND hdlg,
  587. IN UINT msg,
  588. IN WPARAM wParam,
  589. IN LPARAM lParam
  590. )
  591. /*++
  592. Routine Description:
  593. Dialog procedure for "steps" dialog page. This is the one just before
  594. we go into the network wizard.
  595. When the user clicks next to go to the next page, we have to perform
  596. some actions to prepare. So we put up a billboard telling the user
  597. that we are preparing. When preparation is done, we continue.
  598. Arguments:
  599. Standard dialog procedure arguments.
  600. Return Value:
  601. Standard dialog procedure return.
  602. --*/
  603. {
  604. NMHDR *NotifyParams;
  605. PVOID p;
  606. HWND billboard;
  607. HCURSOR OldCursor;
  608. switch(msg) {
  609. case WM_INITDIALOG:
  610. break;
  611. case WMX_VALIDATE:
  612. //
  613. // If unattended, we put up a wait cursor instead of a billboard
  614. //
  615. PropSheet_SetWizButtons(GetParent(hdlg),0);
  616. OldCursor = SetCursor (LoadCursor (NULL, IDC_WAIT));
  617. if(!UiTest) {
  618. if(Upgrade) {
  619. PrepareForNetUpgrade();
  620. } else {
  621. PrepareForNetSetup();
  622. }
  623. }
  624. SetCursor (OldCursor);
  625. return ReturnDlgResult (hdlg, VALIDATE_DATA_OK);
  626. #if 0
  627. case WM_SIMULATENEXT:
  628. PropSheet_PressButton( GetParent(hdlg), PSBTN_NEXT);
  629. break;
  630. #endif
  631. case WM_NOTIFY:
  632. NotifyParams = (NMHDR *)lParam;
  633. switch(NotifyParams->code) {
  634. case PSN_SETACTIVE:
  635. TESTHOOK(512);
  636. BEGIN_SECTION(L"Pre-Network Steps Page");
  637. // Page does not show, hide wizard
  638. SendMessage(GetParent(hdlg), WMX_BBTEXT, (WPARAM)TRUE, 0);
  639. SendDlgMessage (hdlg, WMX_VALIDATE, 0, TRUE);
  640. SetWindowLongPtr(hdlg,DWLP_MSGRESULT,-1);
  641. END_SECTION(L"Pre-Network Steps Page");
  642. break;
  643. #if 0
  644. case PSN_WIZNEXT:
  645. UnattendAdvanceIfValid (hdlg);
  646. break;
  647. #endif
  648. case PSN_KILLACTIVE:
  649. END_SECTION(L"Pre-Network Steps Page");
  650. default:
  651. break;
  652. }
  653. break;
  654. default:
  655. return(FALSE);
  656. }
  657. return(TRUE);
  658. }
  659. WNDPROC OldProgressProc;
  660. BOOL
  661. NewProgessProc(
  662. IN HWND hdlg,
  663. IN UINT msg,
  664. IN WPARAM wParam,
  665. IN LPARAM lParam
  666. )
  667. {
  668. switch (msg)
  669. {
  670. case WMX_PROGRESSTICKS:
  671. case PBM_DELTAPOS:
  672. case PBM_SETRANGE:
  673. case PBM_SETRANGE32:
  674. case PBM_STEPIT:
  675. case PBM_SETPOS:
  676. case PBM_SETSTEP:
  677. ProgressGaugeMsgWrapper(msg, wParam, lParam);
  678. break;
  679. }
  680. return (BOOL)CallWindowProc(OldProgressProc,hdlg,msg,wParam,lParam);
  681. }
  682. INT_PTR
  683. CALLBACK
  684. CopyFilesDlgProc(
  685. IN HWND hdlg,
  686. IN UINT msg,
  687. IN WPARAM wParam,
  688. IN LPARAM lParam
  689. )
  690. /*++
  691. Routine Description:
  692. Dialog procedure for the wizard page where we do all the work.
  693. Arguments:
  694. Standard dialog procedure arguments.
  695. Return Value:
  696. Standard dialog procedure return.
  697. --*/
  698. {
  699. static BOOL WorkFinished = FALSE;
  700. NMHDR *NotifyParams;
  701. static HCURSOR hcur;
  702. static FINISH_THREAD_PARAMS Context;
  703. static HWND hProgress;
  704. DWORD ThreadId;
  705. HANDLE ThreadHandle = NULL;
  706. UINT GaugeRange;
  707. switch(msg) {
  708. case WM_INITDIALOG:
  709. //
  710. // Initialize the progress indicator control.
  711. //
  712. hProgress = GetDlgItem(hdlg, IDC_PROGRESS1);
  713. OldProgressProc = (WNDPROC)SetWindowLongPtr(hProgress,GWLP_WNDPROC,(LONG_PTR)NewProgessProc);
  714. GaugeRange = 100;
  715. SendDlgItemMessage(hdlg,IDC_PROGRESS1,PBM_SETRANGE,0,MAKELPARAM(0,GaugeRange));
  716. SendDlgItemMessage(hdlg,IDC_PROGRESS1,PBM_SETPOS,0,0);
  717. SendDlgItemMessage(hdlg,IDC_PROGRESS1,PBM_SETSTEP,1,0);
  718. // Do calls into the billboard to prepare the progress there.
  719. SendMessage(GetParent(hdlg), WMX_BBPROGRESSGAUGE, SW_SHOW, 0);
  720. #ifdef _OCM
  721. //
  722. // the lparam is really the context pointer for ocm
  723. //
  724. Context.OcManagerContext = (PVOID)((PROPSHEETPAGE *)lParam)->lParam;
  725. MYASSERT(Context.OcManagerContext);
  726. #endif
  727. break;
  728. case WM_NOTIFY:
  729. NotifyParams = (NMHDR *)lParam;
  730. switch(NotifyParams->code) {
  731. case PSN_SETACTIVE:
  732. TESTHOOK(513);
  733. BEGIN_SECTION(L"Copying Files Page");
  734. SetWizardButtons(hdlg,WizPageCopyFiles);
  735. if(WorkFinished) {
  736. //
  737. // Don't activate; we've already been here before.
  738. // Nothing to do.
  739. //
  740. SetWindowLongPtr(hdlg,DWLP_MSGRESULT,-1);
  741. } else {
  742. //
  743. // Need to prepare for installation.
  744. // Want next/back buttons disabled until we're done.
  745. //
  746. PropSheet_SetWizButtons(GetParent(hdlg),0);
  747. SendMessage(GetParent(hdlg), WMX_BBTEXT, (WPARAM)TRUE, 0);
  748. PostMessage(hdlg,WM_IAMVISIBLE,0,0);
  749. WorkFinished = TRUE;
  750. }
  751. break;
  752. case PSN_KILLACTIVE:
  753. END_SECTION(L"Copying Files Page");
  754. default:
  755. break;
  756. }
  757. break;
  758. case WM_IAMVISIBLE:
  759. //
  760. // Force repainting first to make sure the page is visible.
  761. //
  762. InvalidateRect(hdlg,NULL,FALSE);
  763. UpdateWindow(hdlg);
  764. hcur = SetCursor(LoadCursor(NULL,IDC_WAIT));
  765. if(!UiTest) {
  766. Context.ThreadId = GetCurrentThreadId();
  767. Context.hdlg = hdlg;
  768. MYASSERT(Context.OcManagerContext);
  769. ThreadHandle = CreateThread(
  770. NULL,
  771. 0,
  772. FinishThread,
  773. &Context,
  774. 0,
  775. &ThreadId
  776. );
  777. if(ThreadHandle) {
  778. CloseHandle(ThreadHandle);
  779. } else {
  780. SetupDebugPrint1(
  781. L"SETUP: CreateThread() failed for FinishThread. Error = %d",
  782. GetLastError()
  783. );
  784. }
  785. }
  786. break;
  787. case WM_MY_PROGRESS:
  788. if(wParam) {
  789. SendMessage (hProgress, PBM_STEPIT, 0, 0);
  790. } else {
  791. SendMessage (hProgress, PBM_SETRANGE, 0, MAKELPARAM(0,lParam));
  792. SendMessage (hProgress, PBM_SETPOS, 0, 0);
  793. }
  794. break;
  795. case WMX_TERMINATE:
  796. //
  797. // Enable next and back buttons and move to next page.
  798. //
  799. SendMessage(GetParent(hdlg),WMX_SETPROGRESSTEXT,0,0);
  800. SendMessage(GetParent(hdlg), WMX_BBPROGRESSGAUGE, SW_HIDE, 0);
  801. SetCursor(hcur);
  802. if(!UiTest) {
  803. PropSheet_PressButton(GetParent(hdlg),PSBTN_NEXT);
  804. }
  805. break;
  806. default:
  807. return(FALSE);
  808. }
  809. return(TRUE);
  810. }
  811. INT_PTR
  812. CALLBACK
  813. LastPageDlgProc(
  814. IN HWND hdlg,
  815. IN UINT msg,
  816. IN WPARAM wParam,
  817. IN LPARAM lParam
  818. )
  819. /*++
  820. Routine Description:
  821. Dialog procedure for last wizard page of Setup.
  822. Arguments:
  823. Standard dialog procedure arguments.
  824. Return Value:
  825. Standard dialog procedure return.
  826. --*/
  827. {
  828. HFONT Font;
  829. LOGFONT LogFont;
  830. WCHAR str[20];
  831. int Height;
  832. HDC hdc;
  833. NMHDR *NotifyParams;
  834. PVOID p = NULL;
  835. switch(msg) {
  836. case WM_INITDIALOG:
  837. if((Font = (HFONT)SendDlgItemMessage(hdlg,IDT_STATIC_1,WM_GETFONT,0,0))
  838. && GetObject(Font,sizeof(LOGFONT),&LogFont)) {
  839. LogFont.lfWeight = FW_BOLD;
  840. if(!LoadString(MyModuleHandle, IDS_WELCOME_FONT_NAME, LogFont.lfFaceName, LF_FACESIZE)){
  841. LogFont.lfFaceName[LF_FACESIZE - 1] = '\0';
  842. }
  843. if(!LoadString(MyModuleHandle, IDS_WELCOME_FONT_SIZE, str, ARRAYSIZE(str))){
  844. str[ARRAYSIZE(str) - 1] = '\0';
  845. }
  846. Height = (int)wcstoul(str,NULL,10);
  847. if(hdc = GetDC(hdlg)) {
  848. LogFont.lfHeight = 0 - (GetDeviceCaps(hdc,LOGPIXELSY) * Height / 72);
  849. if(Font = CreateFontIndirect(&LogFont)) {
  850. SendDlgItemMessage(hdlg,IDT_STATIC_1,WM_SETFONT,(WPARAM)Font,MAKELPARAM(TRUE,0));
  851. }
  852. ReleaseDC(hdlg,hdc);
  853. }
  854. }
  855. break;
  856. case WM_SIMULATENEXT:
  857. // Simulate the next button somehow
  858. PropSheet_PressButton(GetParent(hdlg),PSBTN_FINISH);
  859. break;
  860. case WM_CTLCOLOREDIT:
  861. case WM_CTLCOLORDLG:
  862. case WM_CTLCOLORMSGBOX:
  863. case WM_CTLCOLORLISTBOX:
  864. case WM_CTLCOLORBTN:
  865. case WM_CTLCOLORSCROLLBAR:
  866. case WM_CTLCOLORSTATIC:
  867. SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT));
  868. SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW));
  869. return (LRESULT)s_hbrWindow;
  870. case WM_ERASEBKGND:
  871. AdjustAndPaintWatermarkBitmap(hdlg,(HDC)wParam);
  872. break;
  873. case WM_NOTIFY:
  874. NotifyParams = (NMHDR *)lParam;
  875. switch(NotifyParams->code) {
  876. case PSN_SETACTIVE:
  877. TESTHOOK(514);
  878. BEGIN_SECTION(L"Finish Page");
  879. if( AsrIsEnabled()) {
  880. if(p = MyLoadString(IDS_EMPTY_STRING)) {
  881. BB_SetTimeEstimateText(p);
  882. SendMessage(GetParent(hdlg), WMX_SETPROGRESSTEXT, 0, (LPARAM)p);
  883. SendMessage(GetParent(hdlg), WMX_BB_SETINFOTEXT, 0, (LPARAM)p);
  884. MyFree(p);
  885. }
  886. else {
  887. BB_SetTimeEstimateText(TEXT(""));
  888. SendMessage(GetParent(hdlg), WMX_SETPROGRESSTEXT, 0, (LPARAM)TEXT(""));
  889. SendMessage(GetParent(hdlg), WMX_BB_SETINFOTEXT, 0, (LPARAM)TEXT(""));
  890. }
  891. SendMessage(GetParent(hdlg), WMX_BBPROGRESSGAUGE, (WPARAM)SW_HIDE, 0);
  892. StartStopBB(FALSE);
  893. PostMessage(hdlg,WM_SIMULATENEXT,0,0);
  894. break;
  895. }
  896. SetWizardButtons(hdlg,WizPageLast);
  897. if (hinstBB)
  898. {
  899. PostMessage(hdlg,WM_SIMULATENEXT,0,0);
  900. }
  901. else
  902. {
  903. //
  904. // Don't want back button in upgrade case, since that would
  905. // land us in the middle of the network upgrade. In non-upgrade
  906. // case we only allow the user to go back if he didn't install
  907. // the net, to allow him to change his mind.
  908. //
  909. if(Upgrade || (InternalSetupData.OperationFlags & SETUPOPER_NETINSTALLED)) {
  910. PropSheet_SetWizButtons(GetParent(hdlg),PSWIZB_FINISH);
  911. }
  912. //
  913. // If NoWaitAfterGuiMode is zero, turn off Unattend mode
  914. //
  915. GetPrivateProfileString (L"Unattended", L"NoWaitAfterGuiMode", L"", str, 20, AnswerFile);
  916. if (!lstrcmp (str, L"0")) {
  917. Unattended = FALSE;
  918. }
  919. if (Unattended) {
  920. if(!UnattendSetActiveDlg(hdlg,IDD_LAST_WIZARD_PAGE))
  921. {
  922. END_SECTION(L"Finish Page");
  923. }
  924. }
  925. }
  926. break;
  927. case PSN_KILLACTIVE:
  928. END_SECTION(L"Finish Page");
  929. default:
  930. break;
  931. }
  932. break;
  933. default:
  934. return(FALSE);
  935. }
  936. return(TRUE);
  937. }
  938. INT_PTR
  939. CALLBACK
  940. PreparingDlgProc(
  941. IN HWND hdlg,
  942. IN UINT msg,
  943. IN WPARAM wParam,
  944. IN LPARAM lParam
  945. )
  946. /*++
  947. Routine Description:
  948. Dialog procedure for "preparing computer" Wizard page.
  949. When the user is viewing this page we are essentially preparing
  950. BaseWinOptions, initializing optional components stuff, and installing P&P devices.
  951. Arguments:
  952. Standard dialog procedure arguments.
  953. Return Value:
  954. Standard dialog procedure return.
  955. --*/
  956. {
  957. WCHAR str[1024];
  958. NMHDR *NotifyParams;
  959. HCURSOR hcur;
  960. switch(msg) {
  961. case WM_NOTIFY:
  962. NotifyParams = (NMHDR *)lParam;
  963. switch(NotifyParams->code) {
  964. case PSN_SETACTIVE:
  965. TESTHOOK(515);
  966. BEGIN_SECTION(L"Installing Devices Page");
  967. if(PreparedAlready) {
  968. //
  969. // Don't activate; we've already been here before.
  970. // Nothing to do.
  971. //
  972. SetWindowLongPtr(hdlg,DWLP_MSGRESULT,-1);
  973. } else {
  974. if(AsrIsEnabled()) {
  975. //
  976. // If this is ASR, load the appropriate wizard page
  977. //
  978. SetWizardButtons(hdlg, WizPagePreparingAsr);
  979. }
  980. //
  981. // Need to prepare for installation.
  982. // Want next/back buttons disabled until we're done.
  983. //
  984. PropSheet_SetWizButtons(GetParent(hdlg),0);
  985. SendMessage(GetParent(hdlg), WMX_BBTEXT, (WPARAM)TRUE, 0);
  986. PostMessage(hdlg,WM_IAMVISIBLE,0,0);
  987. PreparedAlready = TRUE;
  988. }
  989. break;
  990. case PSN_KILLACTIVE:
  991. END_SECTION(L"Installing Devices Page");
  992. default:
  993. break;
  994. }
  995. break;
  996. case WM_IAMVISIBLE:
  997. //
  998. // Force repainting first to make sure the page is visible.
  999. //
  1000. InvalidateRect(hdlg,NULL,FALSE);
  1001. UpdateWindow(hdlg);
  1002. hcur = SetCursor(LoadCursor(NULL,IDC_WAIT));
  1003. OldProgressProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(hdlg, IDC_PROGRESS1),GWLP_WNDPROC,(LONG_PTR)NewProgessProc);
  1004. // Do calls into the billboard to prepare the progress there.
  1005. if(!LoadString(MyModuleHandle, IDS_BB_INSTALLING_DEVICES, str, SIZECHARS(str)))
  1006. {
  1007. *str = L'\0';
  1008. }
  1009. SendMessage(GetParent(hdlg), WMX_SETPROGRESSTEXT,0,(LPARAM)str);
  1010. SendMessage(GetParent(hdlg), WMX_BBPROGRESSGAUGE, SW_SHOW, 0);
  1011. if(!UiTest) {
  1012. ULONG StartAtPercent = 0;
  1013. ULONG StopAtPercent = 0;
  1014. if (AsrIsEnabled()) {
  1015. //
  1016. // Update the UI
  1017. //
  1018. SetFinishItemAttributes(hdlg,
  1019. IDC_ASR_PNP_BMP,
  1020. LoadImage (MyModuleHandle, MAKEINTRESOURCE(IDB_ARROW), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS),
  1021. IDC_ASR_PNP_TXT,
  1022. FW_BOLD
  1023. );
  1024. }
  1025. if( !MiniSetup ){
  1026. //
  1027. // Set Security use 10% of gauge
  1028. //
  1029. StopAtPercent = 30;
  1030. RemainingTime = CalcTimeRemaining(Phase_InstallSecurity);
  1031. SetRemainingTime(RemainingTime);
  1032. BEGIN_SECTION(L"Installing security");
  1033. SetupInstallSecurity(hdlg,
  1034. GetDlgItem(hdlg, IDC_PROGRESS1),
  1035. StartAtPercent,
  1036. StopAtPercent
  1037. );
  1038. END_SECTION(L"Installing security");
  1039. CallSceSetupRootSecurity();
  1040. SetupDebugPrint(L"SETUP: CallSceSetupRootSecurity started");
  1041. }
  1042. //
  1043. // Installation of PnP devices use the last 95% of the gauge
  1044. //
  1045. StartAtPercent = StopAtPercent;
  1046. StopAtPercent = 100;
  1047. BEGIN_SECTION(L"Installing PnP devices");
  1048. if (UninstallEnabled) {
  1049. //
  1050. // If uninstall mode, revert the timeout back to 5 seconds, so
  1051. // PNP can reboot for failed device detections
  1052. //
  1053. ChangeBootTimeout (HARWARE_DETECTION_BOOT_TIMEOUT);
  1054. }
  1055. InstallPnpDevices(hdlg,
  1056. SyssetupInf,
  1057. GetDlgItem(hdlg,IDC_PROGRESS1),
  1058. StartAtPercent,
  1059. StopAtPercent
  1060. );
  1061. END_SECTION(L"Installing PnP devices");
  1062. if (AsrIsEnabled()) {
  1063. //
  1064. // Update the UI
  1065. //
  1066. SetFinishItemAttributes(hdlg,
  1067. IDC_ASR_PNP_BMP,
  1068. LoadImage (MyModuleHandle, MAKEINTRESOURCE(IDB_CHECK), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS),
  1069. IDC_ASR_PNP_TXT,
  1070. FW_NORMAL
  1071. );
  1072. }
  1073. if( !MiniSetup ) {
  1074. BEGIN_SECTION(L"Loading service pack (phase 2)");
  1075. CALL_SERVICE_PACK( SVCPACK_PHASE_2, 0, 0, 0 );
  1076. END_SECTION(L"Loading service pack (phase 2)");
  1077. }
  1078. if(ScreenReader) {
  1079. InvokeExternalApplication(L"narrator.exe", L"", NULL);
  1080. }
  1081. }
  1082. SetCursor(hcur);
  1083. SetWindowLongPtr(GetDlgItem(hdlg, IDC_PROGRESS1),GWLP_WNDPROC,(LONG_PTR)OldProgressProc );
  1084. SendMessage(GetParent(hdlg),WMX_SETPROGRESSTEXT,0,0);
  1085. SendMessage(GetParent(hdlg), WMX_BBPROGRESSGAUGE, SW_HIDE, 0);
  1086. //
  1087. // Enable next and back buttons and move to next page.
  1088. //
  1089. SetWizardButtons(hdlg,WizPagePreparing);
  1090. if(!UiTest) {
  1091. PropSheet_PressButton(GetParent(hdlg),PSBTN_NEXT);
  1092. }
  1093. break;
  1094. default:
  1095. return(FALSE);
  1096. }
  1097. return(TRUE);
  1098. }
  1099. INT_PTR
  1100. CALLBACK
  1101. SetupPreNetDlgProc(
  1102. IN HWND hdlg,
  1103. IN UINT msg,
  1104. IN WPARAM wParam,
  1105. IN LPARAM lParam
  1106. )
  1107. {
  1108. NMHDR *NotifyParams;
  1109. switch(msg) {
  1110. case WM_NOTIFY:
  1111. NotifyParams = (NMHDR *)lParam;
  1112. switch(NotifyParams->code) {
  1113. case PSN_SETACTIVE:
  1114. TESTHOOK(516);
  1115. // Update time remaining.
  1116. // The network code knows how to hide the wizard pages
  1117. // and make them visible no need to do that here.
  1118. RemainingTime = CalcTimeRemaining(Phase_NetInstall);
  1119. SetRemainingTime(RemainingTime);
  1120. BEGIN_SECTION(L"Network Setup Pages");
  1121. SetWindowLongPtr(hdlg,DWLP_MSGRESULT,-1);
  1122. break;
  1123. default:
  1124. break;
  1125. }
  1126. break;
  1127. default:
  1128. return(FALSE);
  1129. }
  1130. return(TRUE);
  1131. }
  1132. INT_PTR
  1133. CALLBACK
  1134. SetupPostNetDlgProc(
  1135. IN HWND hdlg,
  1136. IN UINT msg,
  1137. IN WPARAM wParam,
  1138. IN LPARAM lParam
  1139. )
  1140. {
  1141. NMHDR *NotifyParams;
  1142. switch(msg) {
  1143. case WM_NOTIFY:
  1144. NotifyParams = (NMHDR *)lParam;
  1145. switch(NotifyParams->code) {
  1146. case PSN_SETACTIVE:
  1147. TESTHOOK(517);
  1148. END_SECTION(L"Network Setup Pages");
  1149. // Hide the progress bar when we get here.
  1150. // Just to make sure. There are scenarios where the progress bar was still visible
  1151. //
  1152. SendMessage(GetParent(hdlg), WMX_SETPROGRESSTEXT,0,0);
  1153. SendMessage(GetParent(hdlg), WMX_BBPROGRESSGAUGE, SW_HIDE, 0);
  1154. // update the time estimate display
  1155. // no need to make the wizard visible. The OC manager does this if needed.
  1156. RemainingTime = CalcTimeRemaining(Phase_OCInstall);
  1157. SetRemainingTime(RemainingTime);
  1158. SetWindowLongPtr(hdlg,DWLP_MSGRESULT,-1);
  1159. if(Win32ComputerName[0]){
  1160. SetEnvironmentVariable(L"COMPUTERNAME", Win32ComputerName);
  1161. }
  1162. break;
  1163. default:
  1164. break;
  1165. }
  1166. break;
  1167. default:
  1168. return(FALSE);
  1169. }
  1170. return(TRUE);
  1171. }