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.

820 lines
26 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation
  6. //
  7. // File: selclass.c
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "newdevp.h"
  11. int CALLBACK
  12. ClassListCompare(
  13. LPARAM lParam1,
  14. LPARAM lParam2,
  15. LPARAM lParamSort
  16. )
  17. {
  18. TCHAR ClassDescription1[LINE_LEN];
  19. TCHAR ClassDescription2[LINE_LEN];
  20. UNREFERENCED_PARAMETER(lParamSort);
  21. //
  22. // Check if the 1st item is GUID_DEVCLASS_UNKNOWN
  23. //
  24. if (IsEqualGUID((LPGUID)lParam1, &GUID_DEVCLASS_UNKNOWN)) {
  25. return -1;
  26. }
  27. //
  28. // Check if the 2nd item is GUID_DEVCLASS_UNKNOWN
  29. //
  30. if (IsEqualGUID((LPGUID)lParam2, &GUID_DEVCLASS_UNKNOWN)) {
  31. return 1;
  32. }
  33. if (SetupDiGetClassDescription((LPGUID)lParam1,
  34. ClassDescription1,
  35. LINE_LEN,
  36. NULL
  37. ) &&
  38. SetupDiGetClassDescription((LPGUID)lParam2,
  39. ClassDescription2,
  40. LINE_LEN,
  41. NULL
  42. )) {
  43. return (lstrcmpi(ClassDescription1, ClassDescription2));
  44. }
  45. return 0;
  46. }
  47. void
  48. InitNDW_PickClassDlg(
  49. HWND hwndClassList,
  50. PNEWDEVWIZ NewDevWiz
  51. )
  52. {
  53. LPGUID ClassGuid, lpClassGuidSelected;
  54. GUID ClassGuidSelected;
  55. int lvIndex;
  56. DWORD ClassGuidNum;
  57. LV_ITEM lviItem;
  58. TCHAR ClassDescription[LINE_LEN];
  59. SendMessage(hwndClassList, WM_SETREDRAW, FALSE, 0L);
  60. //
  61. // Clear the Class List
  62. //
  63. ListView_DeleteAllItems(hwndClassList);
  64. lviItem.mask = LVIF_TEXT | LVIF_PARAM;
  65. lviItem.iItem = -1;
  66. lviItem.iSubItem = 0;
  67. ClassGuid = NewDevWiz->ClassGuidList;
  68. ClassGuidNum = NewDevWiz->ClassGuidNum;
  69. //
  70. // Keep track of previosuly selected item
  71. //
  72. if (IsEqualGUID(&NewDevWiz->lvClassGuidSelected, &GUID_NULL)) {
  73. lpClassGuidSelected = NULL;
  74. }
  75. else {
  76. ClassGuidSelected = NewDevWiz->lvClassGuidSelected;
  77. NewDevWiz->lvClassGuidSelected = GUID_NULL;
  78. lpClassGuidSelected = &ClassGuidSelected;
  79. }
  80. while (ClassGuidNum--) {
  81. if (SetupDiGetClassDescription(ClassGuid,
  82. ClassDescription,
  83. SIZECHARS(ClassDescription),
  84. NULL
  85. ))
  86. {
  87. if (IsEqualGUID(ClassGuid, &GUID_DEVCLASS_UNKNOWN)) {
  88. //
  89. // We need to special case the UNKNOWN class and to give it a
  90. // special icon (blank) and special text (Show All Devices).
  91. //
  92. LoadString(hNewDev,
  93. IDS_SHOWALLDEVICES,
  94. ClassDescription,
  95. SIZECHARS(ClassDescription)
  96. );
  97. lviItem.iImage = g_BlankIconIndex;
  98. lviItem.mask |= LVIF_IMAGE;
  99. } else if (SetupDiGetClassImageIndex(&NewDevWiz->ClassImageList,
  100. ClassGuid,
  101. &lviItem.iImage
  102. )) {
  103. lviItem.mask |= LVIF_IMAGE;
  104. } else {
  105. lviItem.mask &= ~LVIF_IMAGE;
  106. }
  107. lviItem.pszText = ClassDescription;
  108. lviItem.lParam = (LPARAM) ClassGuid;
  109. lvIndex = ListView_InsertItem(hwndClassList, &lviItem);
  110. //
  111. // check for previous selection
  112. //
  113. if (lpClassGuidSelected &&
  114. IsEqualGUID(lpClassGuidSelected, ClassGuid))
  115. {
  116. ListView_SetItemState(hwndClassList,
  117. lvIndex,
  118. LVIS_SELECTED|LVIS_FOCUSED,
  119. LVIS_SELECTED|LVIS_FOCUSED
  120. );
  121. lpClassGuidSelected = NULL;
  122. }
  123. }
  124. ClassGuid++;
  125. }
  126. //
  127. // Sort the list
  128. //
  129. ListView_SortItems(hwndClassList, (PFNLVCOMPARE)ClassListCompare, NULL);
  130. //
  131. // if previous selection wasn't found select first in list.
  132. //
  133. if (IsEqualGUID(&NewDevWiz->lvClassGuidSelected, &GUID_NULL)) {
  134. lvIndex = 0;
  135. ListView_SetItemState(hwndClassList,
  136. lvIndex,
  137. LVIS_SELECTED|LVIS_FOCUSED,
  138. LVIS_SELECTED|LVIS_FOCUSED
  139. );
  140. }
  141. //
  142. // previous selection was found, fetch its current index
  143. //
  144. else {
  145. lvIndex = ListView_GetNextItem(hwndClassList,
  146. -1,
  147. LVNI_SELECTED
  148. );
  149. }
  150. //
  151. // scroll the selected item into view.
  152. //
  153. ListView_EnsureVisible(hwndClassList, lvIndex, FALSE);
  154. ListView_SetColumnWidth(hwndClassList, 0, LVSCW_AUTOSIZE_USEHEADER);
  155. SendMessage(hwndClassList, WM_SETREDRAW, TRUE, 0L);
  156. }
  157. INT_PTR CALLBACK
  158. NDW_PickClassDlgProc(
  159. HWND hDlg,
  160. UINT wMsg,
  161. WPARAM wParam,
  162. LPARAM lParam
  163. )
  164. {
  165. HWND hwndClassList = GetDlgItem(hDlg, IDC_NDW_PICKCLASS_CLASSLIST);
  166. HWND hwndParentDlg = GetParent(hDlg);
  167. PNEWDEVWIZ NewDevWiz = (PNEWDEVWIZ)GetWindowLongPtr(hDlg, DWLP_USER);
  168. switch (wMsg) {
  169. case WM_INITDIALOG: {
  170. LPPROPSHEETPAGE lppsp = (LPPROPSHEETPAGE)lParam;
  171. LV_COLUMN lvcCol;
  172. NewDevWiz = (PNEWDEVWIZ)lppsp->lParam;
  173. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)NewDevWiz);
  174. SetDlgText(hDlg, IDC_NDW_TEXT, IDS_NDW_PICKCLASS1, IDS_NDW_PICKCLASS1);
  175. //
  176. // Get the Class Icon Image Lists. We do this only the first
  177. // time this dialog is initialized.
  178. //
  179. if (NewDevWiz->ClassImageList.cbSize) {
  180. ListView_SetImageList(hwndClassList,
  181. NewDevWiz->ClassImageList.ImageList,
  182. LVSIL_SMALL
  183. );
  184. }
  185. //
  186. // Insert a column for the class list
  187. //
  188. lvcCol.mask = LVCF_FMT | LVCF_WIDTH;
  189. lvcCol.fmt = LVCFMT_LEFT;
  190. lvcCol.iSubItem = 0;
  191. ListView_InsertColumn(hwndClassList, 0, (LV_COLUMN FAR *)&lvcCol);
  192. //
  193. // Save the class before the user chooses one. This will be restored
  194. // in the event the install is cancelled.
  195. //
  196. NewDevWiz->SavedClassGuid = NewDevWiz->DeviceInfoData.ClassGuid;
  197. break;
  198. }
  199. case WM_DESTROY:
  200. break;
  201. case WM_NOTIFY:
  202. switch (((NMHDR FAR *)lParam)->code) {
  203. //
  204. // This dialog is being activated. Each time we are activated
  205. // we free up the current DeviceInfo and create a new one. Although
  206. // inefficient, its necessary to reenumerate the class list.
  207. //
  208. case PSN_SETACTIVE:
  209. PropSheet_SetWizButtons(hwndParentDlg, PSWIZB_BACK | PSWIZB_NEXT);
  210. NewDevWiz->PrevPage = IDD_NEWDEVWIZ_SELECTCLASS;
  211. //
  212. // If we have DeviceInfo from going forward delete it.
  213. //
  214. if (NewDevWiz->ClassGuidSelected) {
  215. SetClassGuid(NewDevWiz->hDeviceInfo,
  216. &NewDevWiz->DeviceInfoData,
  217. &NewDevWiz->SavedClassGuid
  218. );
  219. }
  220. NewDevWiz->ClassGuidSelected = NULL;
  221. NdwBuildClassInfoList(NewDevWiz, 0);
  222. InitNDW_PickClassDlg(hwndClassList, NewDevWiz);
  223. if (NewDevWiz->InstallType == NDWTYPE_FOUNDNEW) {
  224. SetTimer(hDlg, INSTALL_COMPLETE_CHECK_TIMERID, INSTALL_COMPLETE_CHECK_TIMEOUT, NULL);
  225. }
  226. break;
  227. case PSN_RESET:
  228. KillTimer(hDlg, INSTALL_COMPLETE_CHECK_TIMERID);
  229. SetClassGuid(NewDevWiz->hDeviceInfo,
  230. &NewDevWiz->DeviceInfoData,
  231. &NewDevWiz->SavedClassGuid
  232. );
  233. break;
  234. case PSN_WIZBACK:
  235. NewDevWiz->PrevPage = IDD_NEWDEVWIZ_SELECTCLASS;
  236. if (NewDevWiz->EnterInto == IDD_NEWDEVWIZ_SELECTCLASS) {
  237. SetDlgMsgResult(hDlg, wMsg, NewDevWiz->EnterFrom);
  238. }
  239. KillTimer(hDlg, INSTALL_COMPLETE_CHECK_TIMERID);
  240. break;
  241. case PSN_WIZNEXT: {
  242. LPGUID ClassGuidSelected;
  243. SetDlgMsgResult(hDlg, wMsg, IDD_NEWDEVWIZ_SELECTDEVICE);
  244. KillTimer(hDlg, INSTALL_COMPLETE_CHECK_TIMERID);
  245. if (IsEqualGUID(&NewDevWiz->lvClassGuidSelected, &GUID_NULL)) {
  246. NewDevWiz->ClassGuidSelected = NULL;
  247. break;
  248. }
  249. ClassGuidSelected = &NewDevWiz->lvClassGuidSelected;
  250. NewDevWiz->ClassGuidSelected = ClassGuidSelected;
  251. //
  252. // Add a new element to the DeviceInfo from the GUID and class name
  253. //
  254. NewDevWiz->DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  255. if (!SetupDiGetClassDescription(NewDevWiz->ClassGuidSelected,
  256. NewDevWiz->ClassDescription,
  257. SIZECHARS(NewDevWiz->ClassDescription),
  258. NULL
  259. )
  260. ||
  261. !SetupDiClassNameFromGuid(NewDevWiz->ClassGuidSelected,
  262. NewDevWiz->ClassName,
  263. SIZECHARS(NewDevWiz->ClassName),
  264. NULL
  265. ))
  266. {
  267. // unhandled error!
  268. NewDevWiz->ClassGuidSelected = NULL;
  269. break;
  270. }
  271. if (IsEqualGUID(NewDevWiz->ClassGuidSelected, &GUID_DEVCLASS_UNKNOWN)) {
  272. ClassGuidSelected = (LPGUID)&GUID_NULL;
  273. }
  274. SetClassGuid(NewDevWiz->hDeviceInfo,
  275. &NewDevWiz->DeviceInfoData,
  276. ClassGuidSelected
  277. );
  278. break;
  279. }
  280. case NM_DBLCLK:
  281. PropSheet_PressButton(hwndParentDlg, PSBTN_NEXT);
  282. break;
  283. case LVN_ITEMCHANGED: {
  284. LPNM_LISTVIEW lpnmlv = (LPNM_LISTVIEW)lParam;
  285. if ((lpnmlv->uChanged & LVIF_STATE)) {
  286. if (lpnmlv->uNewState & LVIS_SELECTED) {
  287. NewDevWiz->lvClassGuidSelected = *((LPGUID)lpnmlv->lParam);
  288. }
  289. else if (IsEqualGUID((LPGUID)lpnmlv->lParam,
  290. &NewDevWiz->lvClassGuidSelected
  291. ))
  292. {
  293. NewDevWiz->lvClassGuidSelected = GUID_NULL;
  294. }
  295. }
  296. break;
  297. }
  298. }
  299. break;
  300. case WM_SYSCOLORCHANGE:
  301. _OnSysColorChange(hDlg, wParam, lParam);
  302. //
  303. // Update the ImageList Background color
  304. //
  305. ImageList_SetBkColor((HIMAGELIST)SendMessage(GetDlgItem(hDlg, IDC_NDW_PICKCLASS_CLASSLIST), LVM_GETIMAGELIST, (WPARAM)(LVSIL_SMALL), 0L),
  306. GetSysColor(COLOR_WINDOW));
  307. break;
  308. case WM_TIMER:
  309. if (INSTALL_COMPLETE_CHECK_TIMERID == wParam) {
  310. if (IsInstallComplete(NewDevWiz->hDeviceInfo, &NewDevWiz->DeviceInfoData)) {
  311. PropSheet_PressButton(GetParent(hDlg), PSBTN_CANCEL);
  312. }
  313. }
  314. break;
  315. default:
  316. return(FALSE);
  317. }
  318. return(TRUE);
  319. }
  320. //
  321. // The real select device page is in setupapi. his page is a blank page which
  322. // never shows its face to have a consistent place to jump to when the class
  323. // is known.
  324. //
  325. INT_PTR CALLBACK
  326. NDW_SelectDeviceDlgProc(
  327. HWND hDlg,
  328. UINT wMsg,
  329. WPARAM wParam,
  330. LPARAM lParam
  331. )
  332. {
  333. HWND hwndParentDlg = GetParent(hDlg);
  334. PNEWDEVWIZ NewDevWiz = (PNEWDEVWIZ)GetWindowLongPtr(hDlg, DWLP_USER);
  335. UNREFERENCED_PARAMETER(wParam);
  336. switch (wMsg) {
  337. case WM_INITDIALOG: {
  338. LPPROPSHEETPAGE lppsp = (LPPROPSHEETPAGE)lParam;
  339. NewDevWiz = (PNEWDEVWIZ)lppsp->lParam;
  340. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)NewDevWiz);
  341. break;
  342. }
  343. case WM_DESTROY:
  344. break;
  345. case WM_NOTIFY:
  346. switch (((NMHDR FAR *)lParam)->code) {
  347. case PSN_SETACTIVE: {
  348. int PrevPage, BackUpPage;
  349. PrevPage = NewDevWiz->PrevPage;
  350. NewDevWiz->PrevPage = IDD_NEWDEVWIZ_SELECTDEVICE;
  351. BackUpPage = NewDevWiz->EnterInto == IDD_NEWDEVWIZ_SELECTDEVICE
  352. ? NewDevWiz->EnterFrom : IDD_NEWDEVWIZ_SELECTCLASS;
  353. if (!NewDevWiz->ClassGuidSelected || PrevPage == IDD_WIZARDEXT_SELECT) {
  354. //
  355. // going backwards, cleanup and backup
  356. //
  357. SetupDiSetSelectedDriver(NewDevWiz->hDeviceInfo,
  358. &NewDevWiz->DeviceInfoData,
  359. NULL
  360. );
  361. SetupDiDestroyDriverInfoList(NewDevWiz->hDeviceInfo,
  362. &NewDevWiz->DeviceInfoData,
  363. SPDIT_COMPATDRIVER
  364. );
  365. SetupDiDestroyDriverInfoList(NewDevWiz->hDeviceInfo,
  366. &NewDevWiz->DeviceInfoData,
  367. SPDIT_CLASSDRIVER
  368. );
  369. //
  370. // Cleanup the WizExtSelect Page
  371. //
  372. if (NewDevWiz->WizExtSelect.hPropSheet) {
  373. PropSheet_RemovePage(GetParent(hDlg),
  374. (WPARAM)-1,
  375. NewDevWiz->WizExtSelect.hPropSheet
  376. );
  377. }
  378. SetDlgMsgResult(hDlg, wMsg, BackUpPage);
  379. break;
  380. }
  381. //
  382. // Set the Cursor to an Hourglass
  383. //
  384. SetCursor(LoadCursor(NULL, IDC_WAIT));
  385. NewDevWiz->WizExtSelect.hPropSheet = CreateWizExtPage(IDD_WIZARDEXT_SELECT,
  386. WizExtSelectDlgProc,
  387. NewDevWiz
  388. );
  389. if (NewDevWiz->WizExtSelect.hPropSheet) {
  390. PropSheet_AddPage(hwndParentDlg, NewDevWiz->WizExtSelect.hPropSheet);
  391. SetDlgMsgResult(hDlg, wMsg, IDD_WIZARDEXT_SELECT);
  392. }
  393. else {
  394. SetDlgMsgResult(hDlg, wMsg, BackUpPage);
  395. }
  396. break;
  397. }
  398. }
  399. break;
  400. default:
  401. return(FALSE);
  402. }
  403. return(TRUE);
  404. }
  405. INT_PTR CALLBACK
  406. WizExtSelectDlgProc(
  407. HWND hDlg,
  408. UINT wMsg,
  409. WPARAM wParam,
  410. LPARAM lParam
  411. )
  412. {
  413. HWND hwndParentDlg = GetParent(hDlg);
  414. PNEWDEVWIZ NewDevWiz = (PNEWDEVWIZ )GetWindowLongPtr(hDlg, DWLP_USER);
  415. int PrevPageId;
  416. PSP_INSTALLWIZARD_DATA InstallWizard;
  417. UNREFERENCED_PARAMETER(wParam);
  418. switch (wMsg) {
  419. case WM_INITDIALOG: {
  420. LPPROPSHEETPAGE lppsp = (LPPROPSHEETPAGE)lParam;
  421. NewDevWiz = (PNEWDEVWIZ )lppsp->lParam;
  422. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)NewDevWiz);
  423. break;
  424. }
  425. case WM_DESTROY:
  426. break;
  427. case WM_NOTIFY:
  428. switch (((NMHDR FAR *)lParam)->code) {
  429. case PSN_SETACTIVE:
  430. PrevPageId = NewDevWiz->PrevPage;
  431. NewDevWiz->PrevPage = IDD_WIZARDEXT_SELECT;
  432. if (PrevPageId == IDD_NEWDEVWIZ_SELECTDEVICE) {
  433. SP_DEVINSTALL_PARAMS DeviceInstallParams;
  434. //
  435. // Moving forward on first page
  436. //
  437. // Prepare to call the class installer, for class install wizard pages.
  438. // and Add in setup's SelectDevice wizard page.
  439. //
  440. InstallWizard = &NewDevWiz->InstallDynaWiz;
  441. memset(InstallWizard, 0, sizeof(SP_INSTALLWIZARD_DATA));
  442. InstallWizard->ClassInstallHeader.InstallFunction = DIF_INSTALLWIZARD;
  443. InstallWizard->ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
  444. InstallWizard->hwndWizardDlg = GetParent(hDlg);
  445. if (!SetupDiSetClassInstallParams(NewDevWiz->hDeviceInfo,
  446. &NewDevWiz->DeviceInfoData,
  447. &InstallWizard->ClassInstallHeader,
  448. sizeof(SP_INSTALLWIZARD_DATA)
  449. ))
  450. {
  451. SetDlgMsgResult(hDlg, wMsg, IDD_WIZARDEXT_SELECT);
  452. break;
  453. }
  454. SetupDiSetSelectedDriver(NewDevWiz->hDeviceInfo,
  455. &NewDevWiz->DeviceInfoData,
  456. NULL
  457. );
  458. SetupDiDestroyDriverInfoList(NewDevWiz->hDeviceInfo,
  459. &NewDevWiz->DeviceInfoData,
  460. SPDIT_COMPATDRIVER
  461. );
  462. SetupDiDestroyDriverInfoList(NewDevWiz->hDeviceInfo,
  463. &NewDevWiz->DeviceInfoData,
  464. SPDIT_CLASSDRIVER
  465. );
  466. //
  467. // Get current DeviceInstall parameters, and then set the fields
  468. // we wanted changed from default
  469. //
  470. DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
  471. if (!SetupDiGetDeviceInstallParams(NewDevWiz->hDeviceInfo,
  472. &NewDevWiz->DeviceInfoData,
  473. &DeviceInstallParams
  474. ))
  475. {
  476. SetDlgMsgResult(hDlg, wMsg, IDD_WIZARDEXT_SELECT);
  477. break;
  478. }
  479. DeviceInstallParams.Flags |= DI_SHOWCLASS | DI_SHOWCOMPAT | DI_SHOWOEM | DI_CLASSINSTALLPARAMS;
  480. DeviceInstallParams.DriverPath[0] = TEXT('\0');
  481. if (IsEqualGUID(NewDevWiz->ClassGuidSelected, &GUID_DEVCLASS_UNKNOWN)) {
  482. DeviceInstallParams.FlagsEx &= ~DI_FLAGSEX_FILTERCLASSES;
  483. }
  484. else {
  485. DeviceInstallParams.FlagsEx |= DI_FLAGSEX_FILTERCLASSES;
  486. }
  487. //
  488. // Check to see if we should show all class drivers or only similar
  489. // drivers for this device.
  490. //
  491. if (GetBusInformation(NewDevWiz->DeviceInfoData.DevInst) & BIF_SHOWSIMILARDRIVERS) {
  492. DeviceInstallParams.FlagsEx |= DI_FLAGSEX_FILTERSIMILARDRIVERS;
  493. } else {
  494. DeviceInstallParams.FlagsEx &= ~DI_FLAGSEX_FILTERSIMILARDRIVERS;
  495. }
  496. DeviceInstallParams.hwndParent = hwndParentDlg;
  497. if (!SetupDiSetDeviceInstallParams(NewDevWiz->hDeviceInfo,
  498. &NewDevWiz->DeviceInfoData,
  499. &DeviceInstallParams
  500. ))
  501. {
  502. SetDlgMsgResult(hDlg, wMsg, IDD_WIZARDEXT_SELECT);
  503. break;
  504. }
  505. InstallWizard->DynamicPageFlags = 0;
  506. NewDevWiz->SelectDevicePage = NULL;
  507. NewDevWiz->SelectDevicePage = SetupDiGetWizardPage(NewDevWiz->hDeviceInfo,
  508. &NewDevWiz->DeviceInfoData,
  509. InstallWizard,
  510. SPWPT_SELECTDEVICE,
  511. SPWP_USE_DEVINFO_DATA
  512. );
  513. PropSheet_AddPage(hwndParentDlg, NewDevWiz->SelectDevicePage);
  514. //
  515. // Clear the class install parameters.
  516. //
  517. SetupDiSetClassInstallParams(NewDevWiz->hDeviceInfo,
  518. &NewDevWiz->DeviceInfoData,
  519. NULL,
  520. 0
  521. );
  522. //
  523. // Add the end page, which is the select end page.
  524. //
  525. NewDevWiz->WizExtSelect.hPropSheetEnd = CreateWizExtPage(IDD_WIZARDEXT_SELECT_END,
  526. WizExtSelectEndDlgProc,
  527. NewDevWiz
  528. );
  529. PropSheet_AddPage(hwndParentDlg, NewDevWiz->WizExtSelect.hPropSheetEnd);
  530. PropSheet_PressButton(hwndParentDlg, PSBTN_NEXT);
  531. }
  532. else {
  533. //
  534. // Moving backwards on first page
  535. //
  536. // Clean up proppages added.
  537. //
  538. if (NewDevWiz->SelectDevicePage) {
  539. PropSheet_RemovePage(hwndParentDlg,
  540. (WPARAM)-1,
  541. NewDevWiz->SelectDevicePage
  542. );
  543. NewDevWiz->SelectDevicePage = NULL;
  544. }
  545. if (NewDevWiz->WizExtSelect.hPropSheetEnd) {
  546. PropSheet_RemovePage(hwndParentDlg,
  547. (WPARAM)-1,
  548. NewDevWiz->WizExtSelect.hPropSheetEnd
  549. );
  550. NewDevWiz->WizExtSelect.hPropSheetEnd = NULL;
  551. }
  552. //
  553. // Jump back
  554. //
  555. SetDlgMsgResult(hDlg, wMsg, IDD_NEWDEVWIZ_SELECTDEVICE);
  556. }
  557. break;
  558. case PSN_WIZNEXT:
  559. SetDlgMsgResult(hDlg, wMsg, 0);
  560. break;
  561. }
  562. break;
  563. default:
  564. return(FALSE);
  565. }
  566. return(TRUE);
  567. }
  568. INT_PTR CALLBACK
  569. WizExtSelectEndDlgProc(
  570. HWND hDlg,
  571. UINT wMsg,
  572. WPARAM wParam,
  573. LPARAM lParam
  574. )
  575. {
  576. HWND hwndParentDlg = GetParent(hDlg);
  577. PNEWDEVWIZ NewDevWiz = (PNEWDEVWIZ )GetWindowLongPtr(hDlg, DWLP_USER);
  578. int PrevPageId;
  579. UNREFERENCED_PARAMETER(wParam);
  580. switch (wMsg) {
  581. case WM_INITDIALOG: {
  582. LPPROPSHEETPAGE lppsp = (LPPROPSHEETPAGE)lParam;
  583. NewDevWiz = (PNEWDEVWIZ )lppsp->lParam;
  584. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)NewDevWiz);
  585. break;
  586. }
  587. case WM_DESTROY:
  588. break;
  589. case WM_NOTIFY:
  590. switch (((NMHDR FAR *)lParam)->code) {
  591. case PSN_SETACTIVE:
  592. PrevPageId = NewDevWiz->PrevPage;
  593. NewDevWiz->PrevPage = IDD_WIZARDEXT_SELECT_END;
  594. if (PrevPageId == IDD_WIZARDEXT_SELECT) {
  595. //
  596. // Moving forward
  597. //
  598. SetDlgMsgResult(hDlg, wMsg, IDD_NEWDEVWIZ_INSTALLDEV);
  599. } else {
  600. //
  601. // Moving backwards
  602. //
  603. // Clean up proppages added.
  604. //
  605. if (NewDevWiz->WizExtSelect.hPropSheetEnd) {
  606. PropSheet_RemovePage(hwndParentDlg,
  607. (WPARAM)-1,
  608. NewDevWiz->WizExtSelect.hPropSheetEnd
  609. );
  610. NewDevWiz->WizExtSelect.hPropSheetEnd = NULL;
  611. }
  612. //
  613. // Jump back
  614. //
  615. NewDevWiz->PrevPage = IDD_WIZARDEXT_SELECT;
  616. SetDlgMsgResult(hDlg, wMsg, IDD_DYNAWIZ_SELECTDEV_PAGE);
  617. }
  618. break;
  619. case PSN_WIZNEXT:
  620. SetDlgMsgResult(hDlg, wMsg, 0);
  621. break;
  622. }
  623. break;
  624. default:
  625. return(FALSE);
  626. }
  627. return(TRUE);
  628. }