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.

752 lines
24 KiB

  1. #include "pch.h"
  2. #pragma hdrstop
  3. #include <shlobj.h>
  4. #include <shlobjp.h>
  5. #include "nceh.h"
  6. #include "ncatlui.h"
  7. #include "ncnetcon.h"
  8. #include "ncreg.h"
  9. #include "ncui.h"
  10. #include "resource.h"
  11. #include "shortcut.h"
  12. #include "wizard.h"
  13. #include "htmlhelp.h"
  14. #include "wgenericpage.h"
  15. static const WCHAR c_szHomenetWizDLL[] = L"hnetwiz.dll";
  16. static const CHAR c_szfnHomeNetWizardRunDll[] = "HomeNetWizardRunDll";
  17. static const WCHAR c_szMSNPath[] = L"\\MSN\\MSNCoreFiles\\msn6.exe";
  18. static const WCHAR c_szMigrationWiz[] = L"\\usmt\\migwiz.exe";
  19. static const DWORD c_dwStartupmsForExternalApps = 500;
  20. static const WCHAR c_szOnlineServiceEnglish[] = L"Online Services";
  21. CGenericFinishPage::IDDLIST CGenericFinishPage::m_dwIddList;
  22. typedef void APIENTRY FNHomeNetWizardRunDll(HWND hwndStub, HINSTANCE hAppInstance, LPSTR pszCmdLine, int nCmdShow);
  23. //
  24. // Function: RunHomeNetWizard
  25. //
  26. // Purpose: Thread to execute the Network Setup Wizard
  27. //
  28. // Parameters:
  29. // lpParameter [in] - Reserved - must be NULL
  30. //
  31. // Returns: HRESULT converted to DWORD
  32. //
  33. // Author: deon 12 April 2001
  34. //
  35. DWORD CALLBACK RunHomeNetWizard(PVOID lpParameter)
  36. {
  37. HRESULT hrExitCode = S_OK;
  38. try
  39. {
  40. HMODULE hModHomeNet = LoadLibrary(c_szHomenetWizDLL);
  41. if (hModHomeNet)
  42. {
  43. FNHomeNetWizardRunDll *pfnHomeNewWizardRunDll = reinterpret_cast<FNHomeNetWizardRunDll *>(GetProcAddress(hModHomeNet, c_szfnHomeNetWizardRunDll));
  44. if (pfnHomeNewWizardRunDll)
  45. {
  46. pfnHomeNewWizardRunDll(NULL, _Module.GetModuleInstance(), NULL, 0);
  47. }
  48. else
  49. {
  50. hrExitCode = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  51. }
  52. FreeLibrary(hModHomeNet);
  53. }
  54. else
  55. {
  56. hrExitCode = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  57. }
  58. }
  59. catch (SE_Exception e)
  60. {
  61. hrExitCode = HRESULT_FROM_WIN32(GetLastError());
  62. if (SUCCEEDED(hrExitCode))
  63. {
  64. hrExitCode = E_FAIL;
  65. }
  66. }
  67. catch (std::bad_alloc)
  68. {
  69. hrExitCode = E_OUTOFMEMORY;
  70. }
  71. return static_cast<DWORD>(hrExitCode);
  72. }
  73. BOOL fIsMSNPresent()
  74. {
  75. BOOL bRet = TRUE;
  76. WCHAR szExecutePath[MAX_PATH+1];
  77. HRESULT hr = SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES, NULL, SHGFP_TYPE_CURRENT, szExecutePath);
  78. if (SUCCEEDED(hr))
  79. {
  80. WCHAR szPath[MAX_PATH+1];
  81. DwFormatString(L"%1!s!%2!s!", szPath, celems(szPath), szExecutePath, c_szMSNPath);
  82. DWORD dwRet = GetFileAttributes(szPath);
  83. if (0xFFFFFFFF != dwRet)
  84. {
  85. hr = S_OK;
  86. }
  87. else
  88. {
  89. bRet = FALSE;
  90. }
  91. }
  92. return bRet;
  93. }
  94. //
  95. // Function: ShellExecuteFromCSIDL
  96. //
  97. // Purpose: Execute a command on this computer based on a CSIDL
  98. //
  99. // Parameters:
  100. // hwndParent [in] - Handle of parent, or NULL for Desktop
  101. // nFolder [in] - CSIDL of base path
  102. // szCommand [in] - Command to be appended to CSIDL
  103. // fIsFolder [in] - Open a folder?
  104. // dwSleepTime [in] - Time to sleep after execute or 0 for none
  105. //
  106. // Returns: HRESULT
  107. //
  108. // Author: deon 12 April 2001
  109. //
  110. HRESULT ShellExecuteFromCSIDL(HWND hWndParent, int nFolder, LPCWSTR szCommand, BOOL fIsFolder, DWORD dwSleepTime)
  111. {
  112. HRESULT hr = S_OK;
  113. WCHAR szExecutePath[MAX_PATH+1];
  114. hr = SHGetFolderPath(NULL, nFolder, NULL, SHGFP_TYPE_CURRENT, szExecutePath);
  115. if (SUCCEEDED(hr))
  116. {
  117. if (NULL == hWndParent)
  118. {
  119. hWndParent = GetDesktopWindow();
  120. }
  121. wcsncat(szExecutePath, szCommand, MAX_PATH);
  122. if (fIsFolder)
  123. {
  124. // Make sure path points to a folder and not some or other virus
  125. DWORD dwRet = GetFileAttributes(szExecutePath);
  126. if ( (0xFFFFFFFF != dwRet) &&
  127. (FILE_ATTRIBUTE_DIRECTORY & dwRet) )
  128. {
  129. hr = S_OK;
  130. }
  131. else
  132. {
  133. hr = E_FAIL;
  134. }
  135. }
  136. if (SUCCEEDED(hr))
  137. {
  138. // Execute the file / folder
  139. if (::ShellExecute(hWndParent, NULL, szExecutePath, NULL, NULL, SW_SHOWNORMAL) <= reinterpret_cast<HINSTANCE>(32))
  140. {
  141. hr = E_FAIL;
  142. }
  143. else
  144. {
  145. hr = S_OK;
  146. if (dwSleepTime)
  147. {
  148. Sleep(dwSleepTime); // Give time to startup
  149. }
  150. }
  151. }
  152. if (FAILED(hr))
  153. {
  154. NcMsgBox(_Module.GetResourceInstance(),
  155. NULL,
  156. IDS_WIZARD_CAPTION,
  157. IDS_ERR_COULD_NOT_OPEN_DIR,
  158. MB_OK | MB_ICONERROR,
  159. szExecutePath);
  160. }
  161. }
  162. else
  163. {
  164. NcMsgBox(_Module.GetResourceInstance(),
  165. NULL,
  166. IDS_WIZARD_CAPTION,
  167. IDS_ERR_COULD_NOT_OPEN_DIR,
  168. MB_OK | MB_ICONERROR,
  169. szCommand);
  170. }
  171. return hr;
  172. }
  173. //
  174. // Function: CGenericFinishPage::OnCGenericFinishPagePageNext
  175. //
  176. // Purpose: Handle the pressing of the Next button
  177. //
  178. // Parameters: hwndDlg [IN] - Handle to the CGenericFinishPage dialog
  179. //
  180. // Returns: BOOL, TRUE
  181. //
  182. BOOL CGenericFinishPage::OnCGenericFinishPagePageNext(HWND hwndDlg)
  183. {
  184. TraceFileFunc(ttidWizard);
  185. HCURSOR hOldCursor = NULL;
  186. INetConnection * pConn = NULL;
  187. // Retrieve the CWizard instance from the dialog
  188. CWizard * pWizard =
  189. reinterpret_cast<CWizard *>(::GetWindowLongPtr(hwndDlg, DWLP_USER));
  190. Assert(NULL != pWizard);
  191. HRESULT hr = S_OK;
  192. switch (m_dwMyIDD)
  193. {
  194. case IDD_FinishOtherWays:
  195. {
  196. if (IsDlgButtonChecked(hwndDlg, CHK_SETUP_MSN) &&
  197. (fIsMSNPresent()) )
  198. {
  199. hr = ShellExecuteFromCSIDL(NULL, CSIDL_PROGRAM_FILES, c_szMSNPath, FALSE, c_dwStartupmsForExternalApps);
  200. }
  201. else if (fIsMSNPresent() || IsDlgButtonChecked(hwndDlg, CHK_SELECTOTHER))
  202. {
  203. WCHAR szPath[MAX_PATH+1];
  204. // As per RAID: 450478.
  205. // If we are running on a MUI platform and the user is logged in a non-primary
  206. // language (IOW: not English), the UserDefaultUILanguage will be different from the
  207. // SystemDefaultUILanguage
  208. if (GetUserDefaultUILanguage() != GetSystemDefaultUILanguage())
  209. {
  210. // Use the English name instead, since on the MUI platform
  211. // the folder name wil be in English.
  212. //
  213. // ISSUE: This will cause the caption of the folder to appear in English
  214. // for a non-Enlish user.
  215. DwFormatString(L"\\%1!s!", szPath, celems(szPath), c_szOnlineServiceEnglish);
  216. }
  217. else
  218. {
  219. DwFormatString(L"\\%1!s!", szPath, celems(szPath), SzLoadIds(IDS_OnlineServices));
  220. }
  221. hr = ShellExecuteFromCSIDL(NULL, CSIDL_PROGRAM_FILES, szPath, TRUE, c_dwStartupmsForExternalApps);
  222. }
  223. }
  224. break;
  225. case IDD_FinishNetworkSetupWizard:
  226. {
  227. Assert(S_OK == HrShouldHaveHomeNetWizard());
  228. DWORD dwThreadId;
  229. HANDLE hHomeNetThread = CreateThread(NULL, STACK_SIZE_COMPACT, RunHomeNetWizard, NULL, 0, &dwThreadId);
  230. if (NULL != hHomeNetThread)
  231. {
  232. HRESULT hrExitCode = S_OK;
  233. ShowWindow(GetParent(hwndDlg), SW_HIDE);
  234. WaitForSingleObject(hHomeNetThread, INFINITE);
  235. GetExitCodeThread(hHomeNetThread, reinterpret_cast<LPDWORD>(&hrExitCode));
  236. if (S_OK == hrExitCode) // user finished the wizard
  237. {
  238. #ifdef DBG
  239. // Make sure we don't leave the window open & hidden
  240. ShowWindow(GetParent(hwndDlg), SW_SHOW);
  241. #endif
  242. // Go to close page
  243. ::SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  244. PostMessage(GetParent(hwndDlg), PSM_SETCURSEL, 0, (LPARAM)pWizard->GetPageHandle(IDD_Exit));
  245. }
  246. else if (S_FALSE == hrExitCode) // user pressed back button
  247. {
  248. ShowWindow(GetParent(hwndDlg), SW_SHOW);
  249. }
  250. else
  251. {
  252. ShowWindow(GetParent(hwndDlg), SW_SHOW);
  253. }
  254. CloseHandle(hHomeNetThread);
  255. }
  256. }
  257. default:
  258. break;
  259. }
  260. if (SUCCEEDED(hr))
  261. {
  262. PostMessage(GetParent(hwndDlg), PSM_SETCURSEL, 0, (LPARAM)pWizard->GetPageHandle(IDD_Exit));
  263. }
  264. else
  265. {
  266. PostMessage(GetParent(hwndDlg), PSM_SETCURSEL, 0, (LPARAM)pWizard->GetPageHandle(m_dwMyIDD));
  267. }
  268. return TRUE;
  269. }
  270. //
  271. // Function: CGenericFinishPage::OnCGenericFinishPagePageBack
  272. //
  273. // Purpose: Handle the BACK notification on the CGenericFinishPage page
  274. //
  275. // Parameters: hwndDlg [IN] - Handle to the CGenericFinishPage dialog
  276. //
  277. // Returns: BOOL, TRUE
  278. //
  279. BOOL CGenericFinishPage::OnCGenericFinishPagePageBack(HWND hwndDlg)
  280. {
  281. TraceFileFunc(ttidWizard);
  282. UINT nCnt = 0;
  283. HPROPSHEETPAGE hPage = NULL;
  284. // Retrieve the CWizard instance from the dialog
  285. CWizard * pWizard =
  286. reinterpret_cast<CWizard *>(::GetWindowLongPtr(hwndDlg, DWLP_USER));
  287. Assert(NULL != pWizard);
  288. LPARAM iddOrigin = pWizard->GetPageOrigin(m_dwMyIDD, NULL);
  289. if (iddOrigin)
  290. {
  291. ::SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, iddOrigin);
  292. }
  293. return TRUE;
  294. }
  295. //
  296. // Function: OnCGenericFinishPagePageActivate
  297. //
  298. // Purpose: Handle the page activation
  299. //
  300. // Parameters: hwndDlg [IN] - Handle to the CGenericFinishPage dialog
  301. //
  302. // Returns: BOOL, TRUE
  303. //
  304. BOOL CGenericFinishPage::OnCGenericFinishPagePageActivate(HWND hwndDlg)
  305. {
  306. TraceFileFunc(ttidWizard);
  307. HRESULT hr;
  308. CWizard* pWizard =
  309. reinterpret_cast<CWizard *>(::GetWindowLongPtr(hwndDlg, DWLP_USER));
  310. Assert(NULL != pWizard);
  311. TraceTag(ttidWizard, "Entering generic page...");
  312. if (IsPostInstall(pWizard))
  313. {
  314. LPARAM lFlags = PSWIZB_BACK | PSWIZB_FINISH;
  315. PropSheet_SetWizButtons(GetParent(hwndDlg), lFlags);
  316. }
  317. ::SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, 0);
  318. if (fIsMSNPresent())
  319. {
  320. ShowWindow(GetDlgItem(hwndDlg, IDC_SELECT_ISP_FINISH) , SW_HIDE);
  321. ShowWindow(GetDlgItem(hwndDlg, CHK_SETUP_MSN) , SW_SHOW);
  322. ShowWindow(GetDlgItem(hwndDlg, IDC_SELECT_MSN_ISP) , SW_SHOW);
  323. ShowWindow(GetDlgItem(hwndDlg, IDC_CLOSE_CHOICE_FINISH) , SW_SHOW);
  324. ShowWindow(GetDlgItem(hwndDlg, CHK_SELECTOTHER), SW_SHOW);
  325. }
  326. else
  327. {
  328. ShowWindow(GetDlgItem(hwndDlg, IDC_SELECT_ISP_FINISH) , SW_SHOW);
  329. ShowWindow(GetDlgItem(hwndDlg, CHK_SETUP_MSN) , SW_HIDE);
  330. ShowWindow(GetDlgItem(hwndDlg, IDC_SELECT_MSN_ISP) , SW_HIDE);
  331. ShowWindow(GetDlgItem(hwndDlg, IDC_CLOSE_CHOICE_FINISH) , SW_HIDE);
  332. ShowWindow(GetDlgItem(hwndDlg, CHK_SELECTOTHER), SW_HIDE);
  333. CheckDlgButton(hwndDlg, CHK_SELECTOTHER, BST_CHECKED);
  334. }
  335. return TRUE;
  336. }
  337. // ***************************************************************************
  338. //
  339. // Function: OnCGenericFinishPageInitDialog
  340. //
  341. // Purpose: Handle WM_INITDIALOG message
  342. //
  343. // Parameters: hwndDlg [IN] - Handle to the CGenericFinishPage dialog
  344. // lParam [IN] - LPARAM value from the WM_INITDIALOG message
  345. //
  346. // Returns: FALSE - Accept default control activation
  347. //
  348. BOOL CGenericFinishPage::OnCGenericFinishPageInitDialog(HWND hwndDlg, LPARAM lParam)
  349. {
  350. TraceFileFunc(ttidWizard);
  351. // Initialize our pointers to property sheet info.
  352. PROPSHEETPAGE* psp = (PROPSHEETPAGE*)lParam;
  353. Assert(psp->lParam);
  354. ::SetWindowLongPtr(hwndDlg, DWLP_USER, psp->lParam);
  355. CWizard * pWizard = reinterpret_cast<CWizard *>(psp->lParam);
  356. Assert(NULL != pWizard);
  357. SetupFonts(hwndDlg, &m_hBoldFont, TRUE);
  358. if (NULL != m_hBoldFont)
  359. {
  360. HWND hwndCtl = GetDlgItem(hwndDlg, IDC_WELCOME_CAPTION);
  361. if (hwndCtl)
  362. {
  363. SetWindowFont(hwndCtl, m_hBoldFont, TRUE);
  364. }
  365. }
  366. switch (m_dwMyIDD)
  367. {
  368. case IDD_FinishOtherWays:
  369. {
  370. INT nrgChks[] = {CHK_SETUP_MSN, CHK_SELECTOTHER};
  371. // Find the top most enabled radio button
  372. for (int nIdx = 0; nIdx < celems(nrgChks); nIdx++)
  373. {
  374. if (IsWindowEnabled(GetDlgItem(hwndDlg, nrgChks[nIdx])))
  375. {
  376. CheckRadioButton(hwndDlg, CHK_SETUP_MSN, CHK_SELECTOTHER, nrgChks[nIdx]);
  377. break;
  378. }
  379. }
  380. }
  381. break;
  382. default:
  383. break;
  384. }
  385. return FALSE; // Accept default control focus
  386. }
  387. BOOL CGenericFinishPage::CGenericFinishPagePageOnClick(HWND hwndDlg, UINT idFrom)
  388. {
  389. BOOL fRet = TRUE;
  390. switch (idFrom)
  391. {
  392. case IDC_ST_AUTOCONFIGLINK:
  393. {
  394. HRESULT hr = ShellExecuteFromCSIDL(hwndDlg, CSIDL_SYSTEM, c_szMigrationWiz, FALSE, 0);
  395. if (FAILED(hr))
  396. {
  397. fRet= FALSE;
  398. }
  399. }
  400. break;
  401. case IDC_ST_DSL_HELPLINK:
  402. // HtmlHelp(hwndDlg, L"netcfg.chm::/howto_highspeed_repair.htm", HH_DISPLAY_TOPIC, 0);
  403. ShellExecute(NULL, NULL, L"HELPCTR.EXE", L" -url hcp://services/subsite?node=TopLevelBucket_4/Hardware&topic=ms-its%3A%25HELP_LOCATION%25%5Cnetcfg.chm%3A%3A/howto_highspeed_repair.htm", NULL, SW_SHOWNORMAL);
  404. break;
  405. case IDC_ST_INTERNETLINK:
  406. // HtmlHelp(hwndDlg, L"netcfg.chm::/i_client.htm", HH_DISPLAY_TOPIC, 0);
  407. ShellExecute(NULL, NULL, L"HELPCTR.EXE", L" -url hcp://services/subsite?node=TopLevelBucket_4/Hardware&topic=ms-its%3A%25HELP_LOCATION%25%5Cnetcfg.chm%3A%3A/i_client.htm", NULL, SW_SHOWNORMAL);
  408. break;
  409. default:
  410. AssertSz(FALSE, "Unexpected notify message");
  411. }
  412. return fRet;
  413. }
  414. //
  415. // Function: CGenericFinishPage::CreateCGenericFinishPagePage
  416. //
  417. // Purpose: To determine if the CGenericFinishPage page needs to be shown, and to
  418. // to create the page if requested. Note the CGenericFinishPage page is
  419. // responsible for initial installs also.
  420. //
  421. // Parameters: idd [IN] - IDD of dialog
  422. // pWizard [IN] - Ptr to a Wizard instance
  423. // pData [IN] - Context data to describe the world in
  424. // which the Wizard will be run
  425. // fCountOnly [IN] - If True, only the maximum number of
  426. // pages this routine will create need
  427. // be determined.
  428. // pnPages [IN] - Increment by the number of pages
  429. // to create/created
  430. //
  431. // Returns: HRESULT, S_OK on success
  432. //
  433. HRESULT CGenericFinishPage::HrCreateCGenericFinishPagePage(DWORD idd, CWizard *pWizard, PINTERNAL_SETUP_DATA pData, BOOL fCountOnly, UINT *pnPages)
  434. {
  435. TraceFileFunc(ttidWizard);
  436. CGenericFinishPage *pCGenericFinishPage = new CGenericFinishPage;
  437. if (!pCGenericFinishPage)
  438. {
  439. return E_OUTOFMEMORY;
  440. }
  441. pCGenericFinishPage->m_dwMyIDD = idd;
  442. HRESULT hr = S_OK;
  443. if (IsPostInstall(pWizard) && ( ! pWizard->FProcessLanPages()))
  444. {
  445. (*pnPages)++;
  446. // If not only counting, create and register the page
  447. if ( ! fCountOnly)
  448. {
  449. LinkWindow_RegisterClass();
  450. HPROPSHEETPAGE hpsp;
  451. PROPSHEETPAGE psp;
  452. ZeroMemory(&psp, sizeof(PROPSHEETPAGE));
  453. TraceTag(ttidWizard, "Creating CGenericFinishPage Page for IID %d", idd);
  454. psp.dwSize = sizeof( PROPSHEETPAGE );
  455. psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
  456. psp.hInstance = _Module.GetResourceInstance();
  457. psp.pszTemplate = MAKEINTRESOURCE( idd );
  458. psp.hIcon = NULL;
  459. psp.pfnDlgProc = CGenericFinishPage::dlgprocCGenericFinishPage;
  460. psp.lParam = reinterpret_cast<LPARAM>(pWizard);
  461. hpsp = CreatePropertySheetPage( &psp );
  462. if (hpsp)
  463. {
  464. pWizard->RegisterPage(idd, hpsp,
  465. CGenericFinishPage::CGenericFinishPagePageCleanup, idd);
  466. m_dwIddList[idd] = pCGenericFinishPage;
  467. }
  468. else
  469. {
  470. hr = E_OUTOFMEMORY;
  471. }
  472. }
  473. }
  474. TraceHr(ttidWizard, FAL, hr, FALSE, "HrCreateCGenericFinishPagePage");
  475. return hr;
  476. }
  477. //
  478. // Function: CGenericFinishPage::AppendCGenericFinishPagePage
  479. //
  480. // Purpose: Add the CGenericFinishPage page, if it was created, to the set of pages
  481. // that will be displayed.
  482. //
  483. // Parameters: idd [IN] - IDD of the dialog - should be created with HrCreateCGenericFinishPagePage first.
  484. // pWizard [IN] - Ptr to Wizard Instance
  485. // pahpsp [IN,OUT] - Array of pages to add our page to
  486. // pcPages [IN,OUT] - Count of pages in pahpsp
  487. //
  488. // Returns: Nothing
  489. //
  490. VOID CGenericFinishPage::AppendCGenericFinishPagePage(DWORD idd, CWizard *pWizard, HPROPSHEETPAGE* pahpsp, UINT *pcPages)
  491. {
  492. TraceFileFunc(ttidWizard);
  493. if (IsPostInstall(pWizard) && ( ! pWizard->FProcessLanPages()))
  494. {
  495. HPROPSHEETPAGE hPage = pWizard->GetPageHandle(idd);
  496. Assert(hPage);
  497. pahpsp[*pcPages] = hPage;
  498. (*pcPages)++;
  499. }
  500. }
  501. //
  502. // Function: CGenericFinishPage::dlgproCGenericFinishPage
  503. //
  504. // Purpose: Dialog Procedure for the CGenericFinishPage wizard page
  505. //
  506. // Parameters: standard dlgproc parameters
  507. //
  508. // Returns: INT_PTR
  509. //
  510. INT_PTR CALLBACK CGenericFinishPage::dlgprocCGenericFinishPage( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  511. {
  512. TraceFileFunc(ttidWizard);
  513. BOOL frt = FALSE;
  514. CGenericFinishPage *pCGenericFinishPage = NULL;
  515. // Can't do a GetCGenericFinishPageFromHWND over here, since it will recurse & stack overflow.
  516. switch (uMsg)
  517. {
  518. case WM_INITDIALOG:
  519. {
  520. PROPSHEETPAGE *pPropSheetPage = reinterpret_cast<PROPSHEETPAGE *>(lParam);
  521. if (FAILED(GetCGenericFinishPageFromIDD(MAKERESOURCEINT(pPropSheetPage->pszTemplate), &pCGenericFinishPage)))
  522. {
  523. return FALSE;
  524. }
  525. frt = pCGenericFinishPage->OnCGenericFinishPageInitDialog(hwndDlg, lParam);
  526. }
  527. break;
  528. case WM_NOTIFY:
  529. {
  530. LPNMHDR pnmh = (LPNMHDR)lParam;
  531. switch (pnmh->code)
  532. {
  533. case NM_CLICK:
  534. if (FAILED(GetCGenericFinishPageFromHWND(hwndDlg, &pCGenericFinishPage)))
  535. {
  536. return FALSE;
  537. }
  538. frt = (BOOL)pCGenericFinishPage->CGenericFinishPagePageOnClick(hwndDlg, (UINT)pnmh->idFrom);
  539. break;
  540. // propsheet notification
  541. case PSN_HELP:
  542. break;
  543. case PSN_SETACTIVE:
  544. if (FAILED(GetCGenericFinishPageFromHWND(hwndDlg, &pCGenericFinishPage)))
  545. {
  546. return FALSE;
  547. }
  548. frt = pCGenericFinishPage->OnCGenericFinishPagePageActivate(hwndDlg);
  549. break;
  550. case PSN_APPLY:
  551. break;
  552. case PSN_KILLACTIVE:
  553. break;
  554. case PSN_RESET:
  555. break;
  556. case PSN_WIZBACK:
  557. if (FAILED(GetCGenericFinishPageFromHWND(hwndDlg, &pCGenericFinishPage)))
  558. {
  559. return FALSE;
  560. }
  561. frt = pCGenericFinishPage->OnCGenericFinishPagePageBack(hwndDlg);
  562. break;
  563. case PSN_WIZFINISH:
  564. if (FAILED(GetCGenericFinishPageFromHWND(hwndDlg, &pCGenericFinishPage)))
  565. {
  566. return FALSE;
  567. }
  568. frt = pCGenericFinishPage->OnCGenericFinishPagePageNext(hwndDlg);
  569. break;
  570. case PSN_WIZNEXT:
  571. if (FAILED(GetCGenericFinishPageFromHWND(hwndDlg, &pCGenericFinishPage)))
  572. {
  573. return FALSE;
  574. }
  575. frt = pCGenericFinishPage->OnCGenericFinishPagePageNext(hwndDlg);
  576. break;
  577. default:
  578. break;
  579. }
  580. }
  581. break;
  582. default:
  583. break;
  584. }
  585. return( frt );
  586. }
  587. //
  588. // Function: CGenericFinishPage::CGenericFinishPagePageCleanup
  589. //
  590. // Purpose: As a callback function to allow any page allocated memory
  591. // to be cleaned up, after the page will no longer be accessed.
  592. //
  593. // Parameters: pWizard [IN] - The wizard against which the page called
  594. // register page
  595. // lParam [IN] - The lParam supplied in the RegisterPage call
  596. //
  597. // Returns: nothing
  598. //
  599. VOID CGenericFinishPage::CGenericFinishPagePageCleanup(CWizard *pWizard, LPARAM lParam)
  600. {
  601. TraceFileFunc(ttidWizard);
  602. Assert(lParam);
  603. CGenericFinishPage *pCGenericFinishPage;
  604. if (FAILED(GetCGenericFinishPageFromIDD((DWORD)lParam, &pCGenericFinishPage)))
  605. {
  606. AssertSz(FALSE, "Could not find page");
  607. return;
  608. }
  609. if (IsPostInstall(pWizard))
  610. {
  611. LinkWindow_UnregisterClass(_Module.GetResourceInstance());
  612. if (NULL != pCGenericFinishPage->m_hBoldFont)
  613. DeleteObject(pCGenericFinishPage->m_hBoldFont);
  614. // 1 means it removed 1 element
  615. Assert(1 == CGenericFinishPage::m_dwIddList.erase(pCGenericFinishPage->m_dwMyIDD));
  616. delete pCGenericFinishPage;
  617. }
  618. }
  619. HRESULT CGenericFinishPage::GetCGenericFinishPageFromIDD(DWORD idd, CGenericFinishPage **pCGenericFinishPage)
  620. {
  621. AssertSz(pCGenericFinishPage, "Invalid pointer to GetCGenericFinishPageFromHWND");
  622. if (!pCGenericFinishPage)
  623. {
  624. return E_POINTER;
  625. }
  626. IDDLIST::const_iterator iter = CGenericFinishPage::m_dwIddList.find(idd);
  627. if (iter != CGenericFinishPage::m_dwIddList.end())
  628. {
  629. *pCGenericFinishPage = iter->second;
  630. }
  631. else
  632. {
  633. AssertSz(FALSE, "Could not find this page in the IDD map");
  634. return E_FAIL;
  635. }
  636. return S_OK;
  637. }
  638. HRESULT CGenericFinishPage::GetCGenericFinishPageFromHWND(HWND hwndDlg, CGenericFinishPage **pCGenericFinishPage)
  639. {
  640. AssertSz(pCGenericFinishPage, "Invalid pointer to GetCGenericFinishPageFromHWND");
  641. if (!pCGenericFinishPage)
  642. {
  643. return E_POINTER;
  644. }
  645. *pCGenericFinishPage = NULL;
  646. int iIndex = PropSheet_HwndToIndex(GetParent(hwndDlg), hwndDlg);
  647. AssertSz(-1 != iIndex, "Could not convert HWND to Index");
  648. if (-1 == iIndex)
  649. {
  650. return E_FAIL;
  651. }
  652. int iIdd = (int)PropSheet_IndexToId(GetParent(hwndDlg), iIndex);
  653. AssertSz(iIdd, "Could not convert Index to IDD");
  654. if (!iIdd)
  655. {
  656. return E_FAIL;
  657. }
  658. return GetCGenericFinishPageFromIDD(iIdd, pCGenericFinishPage);
  659. }