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.

1001 lines
32 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: selclass.c
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "newdevp.h" // Private header stuff not in the PCH
  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. //
  21. // Check if the 1st item is GUID_DEVCLASS_UNKNOWN
  22. //
  23. if (IsEqualGUID((LPGUID)lParam1, &GUID_DEVCLASS_UNKNOWN)) {
  24. return -1;
  25. }
  26. //
  27. // Check if the 2nd item is GUID_DEVCLASS_UNKNOWN
  28. //
  29. if (IsEqualGUID((LPGUID)lParam2, &GUID_DEVCLASS_UNKNOWN)) {
  30. return 1;
  31. }
  32. if (SetupDiGetClassDescription((LPGUID)lParam1,
  33. ClassDescription1,
  34. LINE_LEN,
  35. NULL
  36. ) &&
  37. SetupDiGetClassDescription((LPGUID)lParam2,
  38. ClassDescription2,
  39. LINE_LEN,
  40. NULL
  41. )) {
  42. return (lstrcmpi(ClassDescription1, ClassDescription2));
  43. }
  44. return 0;
  45. }
  46. void InitNDW_PickClassDlg(
  47. HWND hwndClassList,
  48. PNEWDEVWIZ NewDevWiz
  49. )
  50. {
  51. int Index;
  52. LPGUID ClassGuid, lpClassGuidSelected;
  53. GUID ClassGuidSelected;
  54. int lvIndex;
  55. DWORD ClassGuidNum;
  56. LV_ITEM lviItem;
  57. TCHAR ClassDescription[LINE_LEN];
  58. SendMessage(hwndClassList, WM_SETREDRAW, FALSE, 0L);
  59. //
  60. // Clear the Class List
  61. //
  62. ListView_DeleteAllItems(hwndClassList);
  63. lviItem.mask = LVIF_TEXT | LVIF_PARAM;
  64. lviItem.iItem = -1;
  65. lviItem.iSubItem = 0;
  66. ClassGuid = NewDevWiz->ClassGuidList;
  67. ClassGuidNum = NewDevWiz->ClassGuidNum;
  68. //
  69. // Keep track of previosuly selected item
  70. //
  71. if (IsEqualGUID(&NewDevWiz->lvClassGuidSelected, &GUID_NULL)) {
  72. lpClassGuidSelected = NULL;
  73. }
  74. else {
  75. ClassGuidSelected = NewDevWiz->lvClassGuidSelected;
  76. NewDevWiz->lvClassGuidSelected = GUID_NULL;
  77. lpClassGuidSelected = &ClassGuidSelected;
  78. }
  79. while (ClassGuidNum--) {
  80. if (SetupDiGetClassDescription(ClassGuid,
  81. ClassDescription,
  82. LINE_LEN,
  83. NULL
  84. ))
  85. {
  86. if (IsEqualGUID(ClassGuid, &GUID_DEVCLASS_UNKNOWN)) {
  87. //
  88. // We need to special case the UNKNOWN class and to give it a
  89. // special icon (blank) and special text (Show All Devices).
  90. //
  91. LoadString(hNewDev,
  92. IDS_SHOWALLDEVICES,
  93. ClassDescription,
  94. SIZECHARS(ClassDescription)
  95. );
  96. lviItem.iImage = g_BlankIconIndex;
  97. lviItem.mask |= LVIF_IMAGE;
  98. } else if (SetupDiGetClassImageIndex(&NewDevWiz->ClassImageList,
  99. ClassGuid,
  100. &lviItem.iImage
  101. )) {
  102. lviItem.mask |= LVIF_IMAGE;
  103. } else {
  104. lviItem.mask &= ~LVIF_IMAGE;
  105. }
  106. lviItem.pszText = ClassDescription;
  107. lviItem.lParam = (LPARAM) ClassGuid;
  108. lvIndex = ListView_InsertItem(hwndClassList, &lviItem);
  109. //
  110. // check for previous selection
  111. //
  112. if (lpClassGuidSelected &&
  113. IsEqualGUID(lpClassGuidSelected, ClassGuid))
  114. {
  115. ListView_SetItemState(hwndClassList,
  116. lvIndex,
  117. LVIS_SELECTED|LVIS_FOCUSED,
  118. LVIS_SELECTED|LVIS_FOCUSED
  119. );
  120. lpClassGuidSelected = NULL;
  121. }
  122. }
  123. ClassGuid++;
  124. }
  125. //
  126. // Sort the list
  127. //
  128. ListView_SortItems(hwndClassList, (PFNLVCOMPARE)ClassListCompare, NULL);
  129. //
  130. // if previous selection wasn't found select first in list.
  131. //
  132. if (IsEqualGUID(&NewDevWiz->lvClassGuidSelected, &GUID_NULL)) {
  133. lvIndex = 0;
  134. ListView_SetItemState(hwndClassList,
  135. lvIndex,
  136. LVIS_SELECTED|LVIS_FOCUSED,
  137. LVIS_SELECTED|LVIS_FOCUSED
  138. );
  139. }
  140. //
  141. // previous selection was found, fetch its current index
  142. //
  143. else {
  144. lvIndex = ListView_GetNextItem(hwndClassList,
  145. -1,
  146. LVNI_SELECTED
  147. );
  148. }
  149. //
  150. // scroll the selected item into view.
  151. //
  152. ListView_EnsureVisible(hwndClassList, lvIndex, FALSE);
  153. ListView_SetColumnWidth(hwndClassList, 0, LVSCW_AUTOSIZE_USEHEADER);
  154. SendMessage(hwndClassList, WM_SETREDRAW, TRUE, 0L);
  155. }
  156. INT_PTR CALLBACK
  157. NDW_PickClassDlgProc(
  158. HWND hDlg,
  159. UINT wMsg,
  160. WPARAM wParam,
  161. LPARAM lParam
  162. )
  163. {
  164. DWORD Error;
  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. HDEVINFO hDeviceInfo;
  243. LPGUID ClassGuidSelected;
  244. SP_DEVINSTALL_PARAMS DeviceInstallParams;
  245. SetDlgMsgResult(hDlg, wMsg, IDD_NEWDEVWIZ_SELECTDEVICE);
  246. KillTimer(hDlg, INSTALL_COMPLETE_CHECK_TIMERID);
  247. if (IsEqualGUID(&NewDevWiz->lvClassGuidSelected, &GUID_NULL)) {
  248. NewDevWiz->ClassGuidSelected = NULL;
  249. break;
  250. }
  251. ClassGuidSelected = &NewDevWiz->lvClassGuidSelected;
  252. NewDevWiz->ClassGuidSelected = ClassGuidSelected;
  253. //
  254. // Add a new element to the DeviceInfo from the GUID and class name
  255. //
  256. NewDevWiz->DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  257. if (!SetupDiGetClassDescription(NewDevWiz->ClassGuidSelected,
  258. NewDevWiz->ClassDescription,
  259. sizeof(NewDevWiz->ClassDescription)/sizeof(TCHAR),
  260. NULL
  261. )
  262. ||
  263. !SetupDiClassNameFromGuid(NewDevWiz->ClassGuidSelected,
  264. NewDevWiz->ClassName,
  265. sizeof(NewDevWiz->ClassName)/sizeof(TCHAR),
  266. NULL
  267. ))
  268. {
  269. // unhandled error!
  270. NewDevWiz->ClassGuidSelected = NULL;
  271. break;
  272. }
  273. if (IsEqualGUID(NewDevWiz->ClassGuidSelected, &GUID_DEVCLASS_UNKNOWN)) {
  274. ClassGuidSelected = (LPGUID)&GUID_NULL;
  275. }
  276. SetClassGuid(NewDevWiz->hDeviceInfo,
  277. &NewDevWiz->DeviceInfoData,
  278. ClassGuidSelected
  279. );
  280. break;
  281. }
  282. case NM_DBLCLK:
  283. PropSheet_PressButton(hwndParentDlg, PSBTN_NEXT);
  284. break;
  285. case LVN_ITEMCHANGED: {
  286. LPNM_LISTVIEW lpnmlv = (LPNM_LISTVIEW)lParam;
  287. if ((lpnmlv->uChanged & LVIF_STATE)) {
  288. if (lpnmlv->uNewState & LVIS_SELECTED) {
  289. NewDevWiz->lvClassGuidSelected = *((LPGUID)lpnmlv->lParam);
  290. }
  291. else if (IsEqualGUID((LPGUID)lpnmlv->lParam,
  292. &NewDevWiz->lvClassGuidSelected
  293. ))
  294. {
  295. NewDevWiz->lvClassGuidSelected = GUID_NULL;
  296. }
  297. }
  298. break;
  299. }
  300. }
  301. break;
  302. case WM_SYSCOLORCHANGE:
  303. _OnSysColorChange(hDlg, wParam, lParam);
  304. //
  305. // Update the ImageList Background color
  306. //
  307. ImageList_SetBkColor((HIMAGELIST)SendMessage(GetDlgItem(hDlg, IDC_NDW_PICKCLASS_CLASSLIST), LVM_GETIMAGELIST, (WPARAM)(LVSIL_SMALL), 0L),
  308. GetSysColor(COLOR_WINDOW));
  309. break;
  310. case WM_TIMER:
  311. if (INSTALL_COMPLETE_CHECK_TIMERID == wParam) {
  312. if (IsInstallComplete(NewDevWiz->hDeviceInfo, &NewDevWiz->DeviceInfoData)) {
  313. PropSheet_PressButton(GetParent(hDlg), PSBTN_CANCEL);
  314. }
  315. }
  316. break;
  317. default:
  318. return(FALSE);
  319. }
  320. return(TRUE);
  321. }
  322. void
  323. DestroyDynamicWizard(
  324. HWND hwndParentDlg,
  325. PNEWDEVWIZ NewDevWiz,
  326. BOOL WmDestroy
  327. )
  328. {
  329. DWORD Pages;
  330. PSP_INSTALLWIZARD_DATA InstallWizard = &NewDevWiz->InstallDynaWiz;
  331. SP_DEVINSTALL_PARAMS DeviceInstallParams;
  332. Pages = InstallWizard->NumDynamicPages;
  333. InstallWizard->NumDynamicPages = 0;
  334. if (InstallWizard->DynamicPageFlags & DYNAWIZ_FLAG_PAGESADDED) {
  335. if (!WmDestroy) {
  336. while (Pages--) {
  337. PropSheet_RemovePage(hwndParentDlg,
  338. (WPARAM)-1,
  339. InstallWizard->DynamicPages[Pages]
  340. );
  341. InstallWizard->DynamicPages[Pages] = NULL;
  342. }
  343. }
  344. DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
  345. if (SetupDiGetDeviceInstallParams(NewDevWiz->hDeviceInfo,
  346. &NewDevWiz->DeviceInfoData,
  347. &DeviceInstallParams
  348. ))
  349. {
  350. DeviceInstallParams.Flags |= DI_CLASSINSTALLPARAMS;
  351. SetupDiSetDeviceInstallParams(NewDevWiz->hDeviceInfo,
  352. &NewDevWiz->DeviceInfoData,
  353. &DeviceInstallParams
  354. );
  355. }
  356. InstallWizard->DynamicPageFlags &= ~DYNAWIZ_FLAG_PAGESADDED;
  357. InstallWizard->ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
  358. InstallWizard->ClassInstallHeader.InstallFunction = DIF_DESTROYWIZARDDATA;
  359. InstallWizard->hwndWizardDlg = hwndParentDlg;
  360. if (SetupDiSetClassInstallParams(NewDevWiz->hDeviceInfo,
  361. &NewDevWiz->DeviceInfoData,
  362. &InstallWizard->ClassInstallHeader,
  363. sizeof(SP_INSTALLWIZARD_DATA)
  364. ))
  365. {
  366. SetupDiCallClassInstaller(DIF_DESTROYWIZARDDATA,
  367. NewDevWiz->hDeviceInfo,
  368. &NewDevWiz->DeviceInfoData
  369. );
  370. }
  371. }
  372. }
  373. //
  374. // The real select device page is in either setupapi or the class installer
  375. // for dyanwiz. this page is a blank page which never shows its face
  376. // to have a consistent place to jump to when the class is known.
  377. //
  378. INT_PTR CALLBACK
  379. NDW_SelectDeviceDlgProc(
  380. HWND hDlg,
  381. UINT wMsg,
  382. WPARAM wParam,
  383. LPARAM lParam
  384. )
  385. {
  386. HWND hwndParentDlg = GetParent(hDlg);
  387. PNEWDEVWIZ NewDevWiz = (PNEWDEVWIZ)GetWindowLongPtr(hDlg, DWLP_USER);
  388. switch (wMsg) {
  389. case WM_INITDIALOG: {
  390. LPPROPSHEETPAGE lppsp = (LPPROPSHEETPAGE)lParam;
  391. NewDevWiz = (PNEWDEVWIZ)lppsp->lParam;
  392. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)NewDevWiz);
  393. break;
  394. }
  395. case WM_DESTROY:
  396. break;
  397. case WM_NOTIFY:
  398. switch (((NMHDR FAR *)lParam)->code) {
  399. case PSN_SETACTIVE: {
  400. int PrevPage, BackUpPage;
  401. PrevPage = NewDevWiz->PrevPage;
  402. NewDevWiz->PrevPage = IDD_NEWDEVWIZ_SELECTDEVICE;
  403. BackUpPage = NewDevWiz->EnterInto == IDD_NEWDEVWIZ_SELECTDEVICE
  404. ? NewDevWiz->EnterFrom : IDD_NEWDEVWIZ_SELECTCLASS;
  405. //
  406. // If we are coming from select class, driver update or Install NewDevice
  407. // then we are going forward.
  408. //
  409. if (!NewDevWiz->ClassGuidSelected || PrevPage == IDD_WIZARDEXT_PRESELECT) {
  410. //
  411. // going backwards, cleanup and backup
  412. //
  413. SetupDiSetSelectedDriver(NewDevWiz->hDeviceInfo,
  414. &NewDevWiz->DeviceInfoData,
  415. NULL
  416. );
  417. SetupDiDestroyDriverInfoList(NewDevWiz->hDeviceInfo,
  418. &NewDevWiz->DeviceInfoData,
  419. SPDIT_COMPATDRIVER
  420. );
  421. SetupDiDestroyDriverInfoList(NewDevWiz->hDeviceInfo,
  422. &NewDevWiz->DeviceInfoData,
  423. SPDIT_CLASSDRIVER
  424. );
  425. //
  426. // Cleanup the WizExtPreSelect Page
  427. //
  428. if (NewDevWiz->WizExtPreSelect.hPropSheet) {
  429. PropSheet_RemovePage(GetParent(hDlg),
  430. (WPARAM)-1,
  431. NewDevWiz->WizExtPreSelect.hPropSheet
  432. );
  433. }
  434. SetDlgMsgResult(hDlg, wMsg, BackUpPage);
  435. break;
  436. }
  437. //
  438. // Set the Cursor to an Hourglass
  439. //
  440. SetCursor(LoadCursor(NULL, IDC_WAIT));
  441. NewDevWiz->WizExtPreSelect.hPropSheet = CreateWizExtPage(IDD_WIZARDEXT_PRESELECT,
  442. WizExtPreSelectDlgProc,
  443. NewDevWiz
  444. );
  445. if (NewDevWiz->WizExtPreSelect.hPropSheet) {
  446. PropSheet_AddPage(hwndParentDlg, NewDevWiz->WizExtPreSelect.hPropSheet);
  447. SetDlgMsgResult(hDlg, wMsg, IDD_WIZARDEXT_PRESELECT);
  448. }
  449. else {
  450. SetDlgMsgResult(hDlg, wMsg, BackUpPage);
  451. }
  452. break;
  453. }
  454. }
  455. break;
  456. default:
  457. return(FALSE);
  458. }
  459. return(TRUE);
  460. }
  461. INT_PTR CALLBACK
  462. WizExtPreSelectDlgProc(
  463. HWND hDlg,
  464. UINT wMsg,
  465. WPARAM wParam,
  466. LPARAM lParam
  467. )
  468. {
  469. HWND hwndParentDlg = GetParent(hDlg);
  470. PNEWDEVWIZ NewDevWiz = (PNEWDEVWIZ )GetWindowLongPtr(hDlg, DWLP_USER);
  471. int PrevPageId;
  472. switch (wMsg) {
  473. case WM_INITDIALOG: {
  474. LPPROPSHEETPAGE lppsp = (LPPROPSHEETPAGE)lParam;
  475. NewDevWiz = (PNEWDEVWIZ )lppsp->lParam;
  476. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)NewDevWiz);
  477. break;
  478. }
  479. case WM_DESTROY:
  480. break;
  481. case WM_NOTIFY:
  482. switch (((NMHDR FAR *)lParam)->code) {
  483. case PSN_SETACTIVE:
  484. PrevPageId = NewDevWiz->PrevPage;
  485. NewDevWiz->PrevPage = IDD_WIZARDEXT_PRESELECT;
  486. if (PrevPageId == IDD_NEWDEVWIZ_SELECTDEVICE) {
  487. PSP_NEWDEVICEWIZARD_DATA WizardExt;
  488. //
  489. // Moving forward on first page
  490. //
  491. //
  492. // Set the Cursor to an Hourglass
  493. //
  494. SetCursor(LoadCursor(NULL, IDC_WAIT));
  495. //
  496. // Add ClassWizard Extension pages
  497. //
  498. if (NewDevWiz->Flags & IDI_FLAG_MANUALINSTALL) {
  499. AddClassWizExtPages(hwndParentDlg,
  500. NewDevWiz,
  501. &NewDevWiz->WizExtPreSelect.DeviceWizardData,
  502. DIF_NEWDEVICEWIZARD_PRESELECT,
  503. NULL
  504. );
  505. }
  506. //
  507. // Add the end page, which is first of the select page set
  508. //
  509. NewDevWiz->WizExtSelect.hPropSheet = CreateWizExtPage(IDD_WIZARDEXT_SELECT,
  510. WizExtSelectDlgProc,
  511. NewDevWiz
  512. );
  513. if (NewDevWiz->WizExtSelect.hPropSheet) {
  514. PropSheet_AddPage(hwndParentDlg, NewDevWiz->WizExtSelect.hPropSheet);
  515. }
  516. PropSheet_PressButton(hwndParentDlg, PSBTN_NEXT);
  517. }
  518. else {
  519. //
  520. // Moving backwards on first page
  521. //
  522. //
  523. // Clean up proppages added.
  524. //
  525. if (NewDevWiz->WizExtSelect.hPropSheet) {
  526. PropSheet_RemovePage(hwndParentDlg,
  527. (WPARAM)-1,
  528. NewDevWiz->WizExtSelect.hPropSheet
  529. );
  530. NewDevWiz->WizExtSelect.hPropSheet = NULL;
  531. }
  532. RemoveClassWizExtPages(hwndParentDlg,
  533. &NewDevWiz->WizExtPreSelect.DeviceWizardData
  534. );
  535. //
  536. // Jump back
  537. //
  538. SetDlgMsgResult(hDlg, wMsg, IDD_NEWDEVWIZ_SELECTDEVICE);
  539. }
  540. break;
  541. case PSN_WIZNEXT:
  542. SetDlgMsgResult(hDlg, wMsg, 0);
  543. break;
  544. }
  545. break;
  546. default:
  547. return(FALSE);
  548. }
  549. return(TRUE);
  550. }
  551. INT_PTR CALLBACK
  552. WizExtSelectDlgProc(
  553. HWND hDlg,
  554. UINT wMsg,
  555. WPARAM wParam,
  556. LPARAM lParam
  557. )
  558. {
  559. HWND hwndParentDlg = GetParent(hDlg);
  560. PNEWDEVWIZ NewDevWiz = (PNEWDEVWIZ )GetWindowLongPtr(hDlg, DWLP_USER);
  561. int PrevPageId;
  562. PSP_INSTALLWIZARD_DATA InstallWizard;
  563. switch (wMsg) {
  564. case WM_INITDIALOG: {
  565. LPPROPSHEETPAGE lppsp = (LPPROPSHEETPAGE)lParam;
  566. NewDevWiz = (PNEWDEVWIZ )lppsp->lParam;
  567. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)NewDevWiz);
  568. break;
  569. }
  570. case WM_DESTROY:
  571. DestroyDynamicWizard(hwndParentDlg, NewDevWiz, TRUE);
  572. break;
  573. case WM_NOTIFY:
  574. switch (((NMHDR FAR *)lParam)->code) {
  575. case PSN_SETACTIVE:
  576. PrevPageId = NewDevWiz->PrevPage;
  577. NewDevWiz->PrevPage = IDD_WIZARDEXT_SELECT;
  578. if (PrevPageId == IDD_WIZARDEXT_PRESELECT) {
  579. SP_DEVINSTALL_PARAMS DeviceInstallParams;
  580. //
  581. // Moving forward on first page
  582. //
  583. //
  584. // Prepare to call the class installer, for class install wizard pages.
  585. // and Add in setup's SelectDevice wizard page.
  586. //
  587. InstallWizard = &NewDevWiz->InstallDynaWiz;
  588. memset(InstallWizard, 0, sizeof(SP_INSTALLWIZARD_DATA));
  589. InstallWizard->ClassInstallHeader.InstallFunction = DIF_INSTALLWIZARD;
  590. InstallWizard->ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
  591. InstallWizard->hwndWizardDlg = GetParent(hDlg);
  592. if (!SetupDiSetClassInstallParams(NewDevWiz->hDeviceInfo,
  593. &NewDevWiz->DeviceInfoData,
  594. &InstallWizard->ClassInstallHeader,
  595. sizeof(SP_INSTALLWIZARD_DATA)
  596. ))
  597. {
  598. SetDlgMsgResult(hDlg, wMsg, IDD_WIZARDEXT_PRESELECT);
  599. break;
  600. }
  601. SetupDiSetSelectedDriver(NewDevWiz->hDeviceInfo,
  602. &NewDevWiz->DeviceInfoData,
  603. NULL
  604. );
  605. SetupDiDestroyDriverInfoList(NewDevWiz->hDeviceInfo,
  606. &NewDevWiz->DeviceInfoData,
  607. SPDIT_COMPATDRIVER
  608. );
  609. SetupDiDestroyDriverInfoList(NewDevWiz->hDeviceInfo,
  610. &NewDevWiz->DeviceInfoData,
  611. SPDIT_CLASSDRIVER
  612. );
  613. //
  614. // Get current DeviceInstall parameters, and then set the fields
  615. // we wanted changed from default
  616. //
  617. DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
  618. if (!SetupDiGetDeviceInstallParams(NewDevWiz->hDeviceInfo,
  619. &NewDevWiz->DeviceInfoData,
  620. &DeviceInstallParams
  621. ))
  622. {
  623. SetDlgMsgResult(hDlg, wMsg, IDD_WIZARDEXT_PRESELECT);
  624. break;
  625. }
  626. DeviceInstallParams.Flags |= DI_SHOWCLASS | DI_SHOWCOMPAT | DI_SHOWOEM | DI_CLASSINSTALLPARAMS;
  627. DeviceInstallParams.DriverPath[0] = TEXT('\0');
  628. if (IsEqualGUID(NewDevWiz->ClassGuidSelected, &GUID_DEVCLASS_UNKNOWN)) {
  629. DeviceInstallParams.FlagsEx &= ~DI_FLAGSEX_FILTERCLASSES;
  630. }
  631. else {
  632. DeviceInstallParams.FlagsEx |= DI_FLAGSEX_FILTERCLASSES;
  633. }
  634. //
  635. // Check to see if we should show all class drivers or only similar
  636. // drivers for this device.
  637. //
  638. if (GetBusInformation(NewDevWiz->DeviceInfoData.DevInst) & BIF_SHOWSIMILARDRIVERS) {
  639. DeviceInstallParams.FlagsEx |= DI_FLAGSEX_FILTERSIMILARDRIVERS;
  640. } else {
  641. DeviceInstallParams.FlagsEx &= ~DI_FLAGSEX_FILTERSIMILARDRIVERS;
  642. }
  643. DeviceInstallParams.hwndParent = hwndParentDlg;
  644. if (!SetupDiSetDeviceInstallParams(NewDevWiz->hDeviceInfo,
  645. &NewDevWiz->DeviceInfoData,
  646. &DeviceInstallParams
  647. ))
  648. {
  649. SetDlgMsgResult(hDlg, wMsg, IDD_WIZARDEXT_PRESELECT);
  650. break;
  651. }
  652. //
  653. // Call the class installer for installwizard
  654. // If no class install wizard pages default to run the standard
  655. // setup wizard select device page.
  656. //
  657. if ((NewDevWiz->Flags & IDI_FLAG_MANUALINSTALL) &&
  658. SetupDiCallClassInstaller(DIF_INSTALLWIZARD,
  659. NewDevWiz->hDeviceInfo,
  660. &NewDevWiz->DeviceInfoData
  661. )
  662. &&
  663. SetupDiGetClassInstallParams(NewDevWiz->hDeviceInfo,
  664. &NewDevWiz->DeviceInfoData,
  665. &InstallWizard->ClassInstallHeader,
  666. sizeof(SP_INSTALLWIZARD_DATA),
  667. NULL
  668. )
  669. &&
  670. InstallWizard->NumDynamicPages)
  671. {
  672. DWORD Pages;
  673. InstallWizard->DynamicPageFlags |= DYNAWIZ_FLAG_PAGESADDED;
  674. for (Pages = 0; Pages < InstallWizard->NumDynamicPages; ++Pages ) {
  675. PropSheet_AddPage(hwndParentDlg, InstallWizard->DynamicPages[Pages]);
  676. }
  677. NewDevWiz->SelectDevicePage = SetupDiGetWizardPage(NewDevWiz->hDeviceInfo,
  678. &NewDevWiz->DeviceInfoData,
  679. InstallWizard,
  680. SPWPT_SELECTDEVICE,
  681. SPWP_USE_DEVINFO_DATA
  682. );
  683. PropSheet_AddPage(hwndParentDlg, NewDevWiz->SelectDevicePage);
  684. }
  685. else {
  686. InstallWizard->DynamicPageFlags = 0;
  687. NewDevWiz->SelectDevicePage = NULL;
  688. if (!(NewDevWiz->Flags & IDI_FLAG_MANUALINSTALL) ||
  689. !AddClassWizExtPages(hwndParentDlg,
  690. NewDevWiz,
  691. &NewDevWiz->WizExtSelect.DeviceWizardData,
  692. DIF_NEWDEVICEWIZARD_SELECT,
  693. NULL
  694. ))
  695. {
  696. NewDevWiz->SelectDevicePage = SetupDiGetWizardPage(NewDevWiz->hDeviceInfo,
  697. &NewDevWiz->DeviceInfoData,
  698. InstallWizard,
  699. SPWPT_SELECTDEVICE,
  700. SPWP_USE_DEVINFO_DATA
  701. );
  702. PropSheet_AddPage(hwndParentDlg, NewDevWiz->SelectDevicePage);
  703. }
  704. }
  705. //
  706. // Clear the class install parameters.
  707. //
  708. SetupDiSetClassInstallParams(NewDevWiz->hDeviceInfo,
  709. &NewDevWiz->DeviceInfoData,
  710. NULL,
  711. 0
  712. );
  713. //
  714. // Add the end page, which is the preanalyze page.
  715. //
  716. NewDevWiz->WizExtPreAnalyze.hPropSheet = CreateWizExtPage(IDD_WIZARDEXT_PREANALYZE,
  717. WizExtPreAnalyzeDlgProc,
  718. NewDevWiz
  719. );
  720. PropSheet_AddPage(hwndParentDlg, NewDevWiz->WizExtPreAnalyze.hPropSheet);
  721. PropSheet_PressButton(hwndParentDlg, PSBTN_NEXT);
  722. }
  723. else {
  724. //
  725. // Moving backwards on first page
  726. //
  727. //
  728. // Clean up proppages added.
  729. //
  730. DestroyDynamicWizard(hwndParentDlg, NewDevWiz, FALSE);
  731. if (NewDevWiz->SelectDevicePage) {
  732. PropSheet_RemovePage(hwndParentDlg,
  733. (WPARAM)-1,
  734. NewDevWiz->SelectDevicePage
  735. );
  736. NewDevWiz->SelectDevicePage = NULL;
  737. }
  738. if (NewDevWiz->WizExtPreAnalyze.hPropSheet) {
  739. PropSheet_RemovePage(hwndParentDlg,
  740. (WPARAM)-1,
  741. NewDevWiz->WizExtPreAnalyze.hPropSheet
  742. );
  743. NewDevWiz->WizExtPreAnalyze.hPropSheet = NULL;
  744. }
  745. RemoveClassWizExtPages(hwndParentDlg,
  746. &NewDevWiz->WizExtSelect.DeviceWizardData
  747. );
  748. //
  749. // Jump back
  750. //
  751. SetDlgMsgResult(hDlg, wMsg, IDD_WIZARDEXT_PRESELECT);
  752. }
  753. break;
  754. case PSN_WIZNEXT:
  755. SetDlgMsgResult(hDlg, wMsg, 0);
  756. break;
  757. }
  758. break;
  759. default:
  760. return(FALSE);
  761. }
  762. return(TRUE);
  763. }