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.

888 lines
26 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: init.c
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "hdwwiz.h"
  11. HMODULE hHdwWiz;
  12. int g_BlankIconIndex;
  13. INT CALLBACK
  14. iHdwWizardDlgCallback(
  15. IN HWND hwndDlg,
  16. IN UINT uMsg,
  17. IN LPARAM lParam
  18. )
  19. /*++
  20. Routine Description:
  21. Call back used to remove the "?" from the wizard page.
  22. Arguments:
  23. hwndDlg - Handle to the property sheet dialog box.
  24. uMsg - Identifies the message being received. This parameter
  25. is one of the following values:
  26. PSCB_INITIALIZED - Indicates that the property sheet is
  27. being initialized. The lParam value is zero for this message.
  28. PSCB_PRECREATE Indicates that the property sheet is about
  29. to be created. The hwndDlg parameter is NULL and the lParam
  30. parameter is a pointer to a dialog template in memory. This
  31. template is in the form of a DLGTEMPLATE structure followed
  32. by one or more DLGITEMTEMPLATE structures.
  33. lParam - Specifies additional information about the message. The
  34. meaning of this value depends on the uMsg parameter.
  35. Return Value:
  36. The function returns zero.
  37. --*/
  38. {
  39. switch( uMsg ) {
  40. case PSCB_INITIALIZED:
  41. break;
  42. case PSCB_PRECREATE:
  43. if( lParam ){
  44. DLGTEMPLATE *pDlgTemplate = (DLGTEMPLATE *)lParam;
  45. pDlgTemplate->style &= ~(DS_CONTEXTHELP | WS_SYSMENU);
  46. }
  47. break;
  48. }
  49. return FALSE;
  50. }
  51. PHDWPROPERTYSHEET
  52. HdwWizard(
  53. HWND hwndParent,
  54. PHARDWAREWIZ HardwareWiz,
  55. int StartPageId
  56. )
  57. {
  58. PHDWPROPERTYSHEET HdwPropertySheet;
  59. LPPROPSHEETHEADER PropSheetHeader;
  60. PROPSHEETPAGE psp;
  61. LPTSTR Title;
  62. LONG Error;
  63. LONG DialogBaseUnits;
  64. int Index;
  65. //
  66. // Allocate memory for the header and the page array.
  67. //
  68. HdwPropertySheet = LocalAlloc(LPTR, sizeof(HDWPROPERTYSHEET));
  69. if (!HdwPropertySheet) {
  70. return NULL;
  71. }
  72. memset(HdwPropertySheet, 0, sizeof(*HdwPropertySheet));
  73. if (ERROR_SUCCESS != HdwBuildClassInfoList(HardwareWiz,
  74. DIBCI_NOINSTALLCLASS,
  75. HardwareWiz->hMachine ? HardwareWiz->MachineName : NULL)) {
  76. return NULL;
  77. }
  78. //
  79. // Initialize the PropertySheet Header
  80. //
  81. PropSheetHeader = &HdwPropertySheet->PropSheetHeader;
  82. PropSheetHeader->dwSize = sizeof(HdwPropertySheet->PropSheetHeader);
  83. PropSheetHeader->dwFlags = PSH_WIZARD | PSH_USECALLBACK | PSH_WIZARD97 | PSH_WATERMARK | PSH_STRETCHWATERMARK | PSH_HEADER;
  84. PropSheetHeader->hwndParent = hwndParent;
  85. PropSheetHeader->hInstance = hHdwWiz;
  86. PropSheetHeader->pszCaption = MAKEINTRESOURCE(IDS_HDWWIZNAME);
  87. PropSheetHeader->phpage = HdwPropertySheet->PropSheetPages;
  88. PropSheetHeader->pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK);
  89. PropSheetHeader->pszbmHeader = MAKEINTRESOURCE(IDB_BANNER);
  90. PropSheetHeader->pfnCallback = iHdwWizardDlgCallback;
  91. PropSheetHeader->nStartPage = 0;
  92. PropSheetHeader->nPages = 0;
  93. psp.dwSize = sizeof(PROPSHEETPAGE);
  94. psp.hInstance = hHdwWiz;
  95. psp.lParam = (LPARAM)HardwareWiz;
  96. psp.pszTitle = MAKEINTRESOURCE(IDS_HDWWIZNAME);
  97. //
  98. // If the StartPageId is IDD_INSTALLNEWDEVICE then we don't need to create the detection
  99. // and removal pages.
  100. //
  101. if (IDD_INSTALLNEWDEVICE == StartPageId) {
  102. psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
  103. psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_INSTALLNEWDEVICE);
  104. psp.pszHeaderSubTitle = NULL;
  105. psp.pszTemplate = MAKEINTRESOURCE(IDD_INSTALLNEWDEVICE);
  106. psp.pfnDlgProc = InstallNewDeviceDlgProc;
  107. PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp);
  108. }
  109. else {
  110. psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_HIDEHEADER;
  111. psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_WELCOME);
  112. psp.pfnDlgProc = HdwIntroDlgProc;
  113. PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp);
  114. psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
  115. //
  116. // Add Hardware wizard pages
  117. //
  118. psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
  119. psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ADDDEVICE_PNPENUM);
  120. psp.pszHeaderSubTitle = NULL;
  121. psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_PNPENUM);
  122. psp.pfnDlgProc = HdwPnpEnumDlgProc;
  123. PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp);
  124. //
  125. // Finish page
  126. //
  127. psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_HIDEHEADER;
  128. psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_PNPFINISH);
  129. psp.pfnDlgProc = HdwPnpFinishDlgProc;
  130. PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp);
  131. psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
  132. psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ADDDEVICE_CONNECTED);
  133. psp.pszHeaderSubTitle = NULL;
  134. psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_CONNECTED);
  135. psp.pfnDlgProc = HdwConnectedDlgProc;
  136. PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp);
  137. //
  138. // Finish page
  139. //
  140. psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_HIDEHEADER;
  141. psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_CONNECTED_FINISH);
  142. psp.pfnDlgProc = HdwConnectedFinishDlgProc;
  143. PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp);
  144. psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
  145. psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ADDDEVICE_PROBLIST);
  146. psp.pszHeaderSubTitle = NULL;
  147. psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_PROBLIST);
  148. psp.pfnDlgProc = HdwProbListDlgProc;
  149. PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp);
  150. psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_HIDEHEADER;
  151. psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_PROBLIST_FINISH);
  152. psp.pfnDlgProc = HdwProbListFinishDlgProc;
  153. PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp);
  154. psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
  155. psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ADDDEVICE_ASKDETECT);
  156. psp.pszHeaderSubTitle = NULL;
  157. psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_ASKDETECT);
  158. psp.pfnDlgProc = HdwAskDetectDlgProc;
  159. PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp);
  160. psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
  161. psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ADDDEVICE_DETECTION);
  162. psp.pszHeaderSubTitle = NULL;
  163. psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_DETECTION);
  164. psp.pfnDlgProc = HdwDetectionDlgProc;
  165. PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp);
  166. psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
  167. psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ADDDEVICE_DETECTINSTALL);
  168. psp.pszHeaderSubTitle = NULL;
  169. psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_DETECTINSTALL);
  170. psp.pfnDlgProc = HdwDetectInstallDlgProc;
  171. PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp);
  172. //
  173. // Finish page
  174. //
  175. psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_HIDEHEADER;
  176. psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_DETECTREBOOT);
  177. psp.pfnDlgProc = HdwDetectRebootDlgProc;
  178. PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp);
  179. }
  180. //
  181. // These pages are always shown
  182. //
  183. psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
  184. psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ADDDEVICE_SELECTCLASS);
  185. psp.pszHeaderSubTitle = NULL;
  186. psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_SELECTCLASS);
  187. psp.pfnDlgProc = HdwPickClassDlgProc;
  188. PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp);
  189. psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
  190. psp.pszHeaderTitle = NULL;
  191. psp.pszHeaderSubTitle = NULL;
  192. psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_SELECTDEVICE);
  193. psp.pfnDlgProc = HdwSelectDeviceDlgProc;
  194. PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp);
  195. psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
  196. psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ADDDEVICE_ANALYZEDEV);
  197. psp.pszHeaderSubTitle = NULL;
  198. psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_ANALYZEDEV);
  199. psp.pfnDlgProc = HdwAnalyzeDlgProc;
  200. PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp);
  201. psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
  202. psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ADDDEVICE_INSTALLDEV);
  203. psp.pszHeaderSubTitle = NULL;
  204. psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_INSTALLDEV);
  205. psp.pfnDlgProc = HdwInstallDevDlgProc;
  206. PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp);
  207. //
  208. // Finish page
  209. //
  210. psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_HIDEHEADER;
  211. psp.pszTemplate = MAKEINTRESOURCE(IDD_ADDDEVICE_FINISH);
  212. psp.pfnDlgProc = HdwAddDeviceFinishDlgProc;
  213. PropSheetHeader->phpage[PropSheetHeader->nPages++] = CreatePropertySheetPage(&psp);
  214. //
  215. // check for failure on CreatePropertySheetPage.
  216. //
  217. Index = PropSheetHeader->nPages;
  218. while (Index--) {
  219. if (!PropSheetHeader->phpage[Index]) {
  220. break;
  221. }
  222. }
  223. if (Index >= 0) {
  224. Index = PropSheetHeader->nPages;
  225. while (Index--) {
  226. if (PropSheetHeader->phpage[Index]) {
  227. DestroyPropertySheetPage(PropSheetHeader->phpage[Index]);
  228. }
  229. }
  230. LocalFree(HdwPropertySheet);
  231. return NULL;
  232. }
  233. HardwareWiz->PrevPage = 0;
  234. LoadString(hHdwWiz,
  235. IDS_UNKNOWN,
  236. (PTCHAR)szUnknown,
  237. SIZECHARS(szUnknown)
  238. );
  239. LenUnknown = lstrlen(szUnknown) * sizeof(TCHAR) + sizeof(TCHAR);
  240. LoadString(hHdwWiz,
  241. IDS_UNKNOWNDEVICE,
  242. (PTCHAR)szUnknownDevice,
  243. SIZECHARS(szUnknownDevice)
  244. );
  245. LenUnknownDevice = lstrlen(szUnknownDevice) * sizeof(TCHAR) + sizeof(TCHAR);
  246. //
  247. // Get the Class Icon Image Lists.
  248. //
  249. HardwareWiz->ClassImageList.cbSize = sizeof(SP_CLASSIMAGELIST_DATA);
  250. if (SetupDiGetClassImageList(&HardwareWiz->ClassImageList)) {
  251. HICON hIcon;
  252. //
  253. // Add the blank icon for "None of the following devices"
  254. //
  255. if ((hIcon = LoadIcon(hHdwWiz, MAKEINTRESOURCE(IDI_BLANK))) != NULL) {
  256. g_BlankIconIndex = ImageList_AddIcon(HardwareWiz->ClassImageList.ImageList, hIcon);
  257. }
  258. } else {
  259. HardwareWiz->ClassImageList.cbSize = 0;
  260. }
  261. //
  262. // Load the cursors that the wizard will need
  263. //
  264. HardwareWiz->CurrCursor = NULL;
  265. HardwareWiz->IdcWait = LoadCursor(NULL, IDC_WAIT);
  266. HardwareWiz->IdcAppStarting = LoadCursor(NULL, IDC_APPSTARTING);
  267. HardwareWiz->IdcArrow = LoadCursor(NULL, IDC_ARROW);
  268. return HdwPropertySheet;
  269. }
  270. BOOL
  271. WINAPI
  272. InstallNewDevice(
  273. HWND hwndParent,
  274. LPGUID ClassGuid,
  275. PDWORD pReboot
  276. )
  277. /*++
  278. Routine Description:
  279. Exported Entry point from hdwwiz.cpl. Installs a new device. A new Devnode is
  280. created and the user is prompted to select the device. If the class guid
  281. is not specified then then the user begins at class selection.
  282. Arguments:
  283. hwndParent - Window handle of the top-level window to use for any UI related
  284. to installing the device.
  285. LPGUID ClassGuid - Optional class of the new device to install.
  286. If ClassGuid is NULL we start at detection choice page.
  287. If ClassGuid == GUID_NULL or GUID_DEVCLASS_UNKNOWN
  288. we start at class selection page.
  289. pReboot - Optional address of variable to receive reboot flags (DI_NEEDRESTART,DI_NEEDREBOOT)
  290. Return Value:
  291. BOOL TRUE for success (does not mean device was installed or updated),
  292. FALSE unexpected error. GetLastError returns the winerror code.
  293. --*/
  294. {
  295. HARDWAREWIZ HardwareWiz;
  296. PHDWPROPERTYSHEET HdwPropertySheet;
  297. int PropSheetResult;
  298. SEARCHTHREAD SearchThread;
  299. BOOL StartDetect;
  300. if (NoPrivilegeWarning(hwndParent)) {
  301. SetLastError(ERROR_ACCESS_DENIED);
  302. return FALSE;
  303. }
  304. //
  305. // Check to make sure another Device install is underway.
  306. // This entry point is primarily for manual legacy installs.
  307. // While Base PNP has queued found new hdw installs, we don't
  308. // allow the user to install anything manually, since we may get
  309. // duplicate entries.
  310. //
  311. //
  312. if (CMP_WaitNoPendingInstallEvents(5000) == WAIT_TIMEOUT) {
  313. HdwMessageBox(hwndParent,
  314. MAKEINTRESOURCE(IDS_HDW_RUNNING_MSG),
  315. MAKEINTRESOURCE(IDS_HDW_RUNNING_TITLE),
  316. MB_OK | MB_ICONINFORMATION
  317. );
  318. return FALSE;
  319. }
  320. memset(&HardwareWiz, 0, sizeof(HardwareWiz));
  321. HardwareWiz.PromptForReboot = pReboot == NULL;
  322. StartDetect = (ClassGuid == NULL);
  323. //
  324. // Create a DeviceInfoList, using the classers Class guid if any.
  325. //
  326. if (ClassGuid &&
  327. (IsEqualGUID(ClassGuid, &GUID_NULL) ||
  328. IsEqualGUID(ClassGuid, &GUID_DEVCLASS_UNKNOWN))) {
  329. ClassGuid = NULL;
  330. }
  331. HardwareWiz.hDeviceInfo = SetupDiCreateDeviceInfoList(ClassGuid, hwndParent);
  332. if (HardwareWiz.hDeviceInfo == INVALID_HANDLE_VALUE) {
  333. return FALSE;
  334. }
  335. try {
  336. //
  337. // If the caller specified a ClassGuid, retrieve the class information
  338. // and create a DeviceInfo for it.
  339. //
  340. if (ClassGuid) {
  341. HardwareWiz.ClassGuidSelected = ClassGuid;
  342. //
  343. // Add a new element to the DeviceInfo from the GUID and class name
  344. //
  345. HardwareWiz.DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  346. if (!SetupDiGetClassDescription(HardwareWiz.ClassGuidSelected,
  347. HardwareWiz.ClassDescription,
  348. sizeof(HardwareWiz.ClassDescription)/sizeof(TCHAR),
  349. NULL
  350. )
  351. ||
  352. !SetupDiClassNameFromGuid(HardwareWiz.ClassGuidSelected,
  353. HardwareWiz.ClassName,
  354. sizeof(HardwareWiz.ClassName)/sizeof(TCHAR),
  355. NULL
  356. ))
  357. {
  358. HardwareWiz.LastError = GetLastError();
  359. goto INDLeaveExcept;
  360. }
  361. if (!SetupDiCreateDeviceInfo(HardwareWiz.hDeviceInfo,
  362. HardwareWiz.ClassName,
  363. ClassGuid,
  364. NULL,
  365. hwndParent,
  366. DICD_GENERATE_ID,
  367. &HardwareWiz.DeviceInfoData
  368. )
  369. ||
  370. !SetupDiSetSelectedDevice(HardwareWiz.hDeviceInfo,
  371. &HardwareWiz.DeviceInfoData
  372. ))
  373. {
  374. HardwareWiz.LastError = GetLastError();
  375. goto INDLeaveExcept;
  376. }
  377. }
  378. memset(&SearchThread, 0, sizeof(SEARCHTHREAD));
  379. HardwareWiz.SearchThread = &SearchThread;
  380. HardwareWiz.LastError = CreateSearchThread(&HardwareWiz);
  381. if (HardwareWiz.LastError != ERROR_SUCCESS) {
  382. goto INDLeaveExcept;
  383. }
  384. //
  385. // Load the libraries that we will need
  386. //
  387. hDevMgr = LoadLibrary(TEXT("devmgr.dll"));
  388. hNewDev = LoadLibrary(TEXT("newdev.dll"));
  389. //
  390. // Create the property sheet
  391. //
  392. HdwPropertySheet = HdwWizard(hwndParent,
  393. &HardwareWiz,
  394. StartDetect ? IDD_ADDDEVICE_PNPENUM : IDD_INSTALLNEWDEVICE
  395. );
  396. if (HdwPropertySheet) {
  397. PropSheetResult = (int)PropertySheet(&HdwPropertySheet->PropSheetHeader);
  398. LocalFree(HdwPropertySheet);
  399. }
  400. //
  401. // See if we need to run a troubleshooter
  402. //
  403. if (HardwareWiz.RunTroubleShooter) {
  404. TCHAR DeviceID[MAX_DEVICE_ID_LEN];
  405. if (CM_Get_Device_ID_Ex(HardwareWiz.ProblemDevInst,
  406. DeviceID,
  407. SIZECHARS(DeviceID),
  408. 0,
  409. HardwareWiz.hMachine
  410. ) == CR_SUCCESS)
  411. {
  412. PDEVICEPROBLEMWIZARD pDeviceProblemWizard = NULL;
  413. pDeviceProblemWizard = (PVOID) GetProcAddress(hDevMgr, "DeviceProblemWizardW");
  414. if (pDeviceProblemWizard) {
  415. (pDeviceProblemWizard)(hwndParent,
  416. HardwareWiz.MachineName,
  417. DeviceID
  418. );
  419. }
  420. }
  421. }
  422. //
  423. // Final cleanup of DeviceInfoData and DeviceInfoList.
  424. //
  425. if (HardwareWiz.ClassGuidList) {
  426. LocalFree(HardwareWiz.ClassGuidList);
  427. HardwareWiz.ClassGuidList = NULL;
  428. HardwareWiz.ClassGuidSize = HardwareWiz.ClassGuidNum = 0;
  429. }
  430. if (HardwareWiz.ClassImageList.cbSize) {
  431. SetupDiDestroyClassImageList(&HardwareWiz.ClassImageList);
  432. HardwareWiz.ClassImageList.cbSize = 0;
  433. }
  434. if (HardwareWiz.Cancelled ||
  435. (HardwareWiz.Registered && !HardwareWiz.Installed)) {
  436. HdwRemoveDevice(&HardwareWiz);
  437. HardwareWiz.Reboot = 0;
  438. }
  439. SetupDiDestroyDeviceInfoList(HardwareWiz.hDeviceInfo);
  440. HardwareWiz.hDeviceInfo = NULL;
  441. INDLeaveExcept:;
  442. } except(HdwUnhandledExceptionFilter(GetExceptionInformation())) {
  443. HardwareWiz.LastError = RtlNtStatusToDosError(GetExceptionCode());
  444. }
  445. if (HardwareWiz.hDeviceInfo && HardwareWiz.hDeviceInfo != INVALID_HANDLE_VALUE) {
  446. SetupDiDestroyDeviceInfoList(HardwareWiz.hDeviceInfo);
  447. HardwareWiz.hDeviceInfo = NULL;
  448. }
  449. if (HardwareWiz.SearchThread) {
  450. DestroySearchThread(&SearchThread);
  451. }
  452. if (hDevMgr) {
  453. FreeLibrary(hDevMgr);
  454. }
  455. if (hNewDev) {
  456. FreeLibrary(hNewDev);
  457. }
  458. //
  459. // Copy out the reboot flags for the caller
  460. // or put up the restart dialog if caller didn't ask for the reboot flag
  461. //
  462. if (pReboot) {
  463. *pReboot = HardwareWiz.Reboot;
  464. } else if (HardwareWiz.Reboot) {
  465. RestartDialogEx(hwndParent, NULL, EWX_REBOOT, REASON_PLANNED_FLAG | REASON_HWINSTALL);
  466. }
  467. //
  468. // See if we need to shutdown the machine.
  469. //
  470. if (HardwareWiz.Shutdown) {
  471. ShutdownMachine(hwndParent);
  472. }
  473. SetLastError(HardwareWiz.LastError);
  474. return HardwareWiz.LastError == ERROR_SUCCESS;
  475. }
  476. void
  477. AddHardwareWizard(
  478. HWND hwnd,
  479. PTCHAR MachineName
  480. )
  481. /*++
  482. Routine Description:
  483. Arguments:
  484. hwnd - Window handle of the top-level window to use for any UI related
  485. to installing the device.
  486. Return Value:
  487. --*/
  488. {
  489. HARDWAREWIZ HardwareWiz;
  490. PHDWPROPERTYSHEET HdwPropertySheet;
  491. int PropSheetResult;
  492. SEARCHTHREAD SearchThread;
  493. CONFIGRET ConfigRet;
  494. //
  495. // If the user does not have SE_LOAD_DRIVER_NAME privileges then just display a warning
  496. // message and exit.
  497. //
  498. if (NoPrivilegeWarning(hwnd)) {
  499. SetLastError(ERROR_ACCESS_DENIED);
  500. return;
  501. }
  502. if (MachineName) {
  503. lstrcpy(HardwareWiz.MachineName, MachineName);
  504. ConfigRet = CM_Connect_Machine(MachineName, &HardwareWiz.hMachine);
  505. if (ConfigRet != CR_SUCCESS) {
  506. return;
  507. }
  508. }
  509. //
  510. // Check to make sure another Device install is underway.
  511. // This entry point is primarily for manual legacy installs.
  512. // While Base PNP has queued found new hdw installs, we don't
  513. // allow the user to install anything manually, since we may get
  514. // duplicate entries.
  515. //
  516. //
  517. if (CMP_WaitNoPendingInstallEvents(5000) == WAIT_TIMEOUT) {
  518. HdwMessageBox(hwnd,
  519. MAKEINTRESOURCE(IDS_HDW_RUNNING_MSG),
  520. MAKEINTRESOURCE(IDS_HDW_RUNNING_TITLE),
  521. MB_OK | MB_ICONINFORMATION
  522. );
  523. return;
  524. }
  525. memset(&HardwareWiz, 0, sizeof(HardwareWiz));
  526. //
  527. // Create a DeviceInfoList
  528. HardwareWiz.hDeviceInfo = SetupDiCreateDeviceInfoList(NULL, hwnd);
  529. if (HardwareWiz.hDeviceInfo == INVALID_HANDLE_VALUE) {
  530. return;
  531. }
  532. //
  533. // Create the Search thread to look for compatible drivers.
  534. // This thread will sit around waiting for requests until
  535. // told to go away.
  536. //
  537. memset(&SearchThread, 0, sizeof(SEARCHTHREAD));
  538. HardwareWiz.SearchThread = &SearchThread;
  539. if (CreateSearchThread(&HardwareWiz) != ERROR_SUCCESS) {
  540. SetupDiDestroyDeviceInfoList(HardwareWiz.hDeviceInfo);
  541. return;
  542. }
  543. //
  544. // Load the libraries that we will need
  545. //
  546. hDevMgr = LoadLibrary(TEXT("devmgr.dll"));
  547. hNewDev = LoadLibrary(TEXT("newdev.dll"));
  548. HdwPropertySheet = HdwWizard(hwnd, &HardwareWiz, 0);
  549. if (HdwPropertySheet) {
  550. PropSheetResult = (int)PropertySheet(&HdwPropertySheet->PropSheetHeader);
  551. LocalFree(HdwPropertySheet);
  552. }
  553. //
  554. // See if we need to run a troubleshooter
  555. //
  556. if (HardwareWiz.RunTroubleShooter) {
  557. TCHAR DeviceID[MAX_DEVICE_ID_LEN];
  558. if (CM_Get_Device_ID_Ex(HardwareWiz.ProblemDevInst,
  559. DeviceID,
  560. SIZECHARS(DeviceID),
  561. 0,
  562. HardwareWiz.hMachine
  563. ) == CR_SUCCESS)
  564. {
  565. PDEVICEPROBLEMWIZARD pDeviceProblemWizard = NULL;
  566. pDeviceProblemWizard = (PVOID) GetProcAddress(hDevMgr, "DeviceProblemWizardW");
  567. if (pDeviceProblemWizard) {
  568. (pDeviceProblemWizard)(hwnd,
  569. HardwareWiz.MachineName,
  570. DeviceID
  571. );
  572. }
  573. }
  574. }
  575. //
  576. // Final cleanup of DeviceInfoData and DeviceInfoList
  577. //
  578. if (HardwareWiz.ClassGuidList) {
  579. LocalFree(HardwareWiz.ClassGuidList);
  580. HardwareWiz.ClassGuidList = NULL;
  581. HardwareWiz.ClassGuidSize = HardwareWiz.ClassGuidNum = 0;
  582. }
  583. if (HardwareWiz.ClassImageList.cbSize) {
  584. SetupDiDestroyClassImageList(&HardwareWiz.ClassImageList);
  585. HardwareWiz.ClassImageList.cbSize = 0;
  586. }
  587. if (HardwareWiz.Cancelled ||
  588. (HardwareWiz.Registered && !HardwareWiz.Installed)) {
  589. HdwRemoveDevice(&HardwareWiz);
  590. HardwareWiz.Reboot = 0;
  591. }
  592. SetupDiDestroyDeviceInfoList(HardwareWiz.hDeviceInfo);
  593. HardwareWiz.hDeviceInfo = NULL;
  594. if (HardwareWiz.SearchThread) {
  595. DestroySearchThread(HardwareWiz.SearchThread);
  596. }
  597. if (hDevMgr) {
  598. FreeLibrary(hDevMgr);
  599. }
  600. if (hNewDev) {
  601. FreeLibrary(hNewDev);
  602. }
  603. //
  604. // Do we need to reboot?
  605. //
  606. if (HardwareWiz.Reboot) {
  607. RestartDialogEx(hwnd, NULL, EWX_REBOOT, REASON_PLANNED_FLAG | REASON_HWINSTALL);
  608. }
  609. //
  610. // Do we need to shutdown?
  611. //
  612. if (HardwareWiz.Shutdown) {
  613. ShutdownMachine(hwnd);
  614. }
  615. return;
  616. }
  617. LONG
  618. CPlApplet(
  619. HWND hWnd,
  620. WORD uMsg,
  621. DWORD_PTR lParam1,
  622. LPARAM lParam2
  623. )
  624. {
  625. LPNEWCPLINFO lpCPlInfo;
  626. LPCPLINFO lpOldCPlInfo;
  627. switch (uMsg) {
  628. case CPL_INIT:
  629. return TRUE;
  630. case CPL_GETCOUNT:
  631. return 1;
  632. case CPL_INQUIRE:
  633. lpOldCPlInfo = (LPCPLINFO)(LPARAM)lParam2;
  634. lpOldCPlInfo->lData = 0L;
  635. lpOldCPlInfo->idIcon = IDI_HDWWIZICON;
  636. lpOldCPlInfo->idName = IDS_HDWWIZ;
  637. lpOldCPlInfo->idInfo = IDS_HDWWIZINFO;
  638. return TRUE;
  639. case CPL_NEWINQUIRE:
  640. lpCPlInfo = (LPNEWCPLINFO)(LPARAM)lParam2;
  641. lpCPlInfo->hIcon = LoadIcon(hHdwWiz, MAKEINTRESOURCE(IDI_HDWWIZICON));
  642. LoadString(hHdwWiz, IDS_HDWWIZ, lpCPlInfo->szName, sizeof(lpCPlInfo->szName));
  643. LoadString(hHdwWiz, IDS_HDWWIZINFO, lpCPlInfo->szInfo, sizeof(lpCPlInfo->szInfo));
  644. lpCPlInfo->dwHelpContext = IDH_HDWWIZAPPLET;
  645. lpCPlInfo->dwSize = sizeof(NEWCPLINFO);
  646. lpCPlInfo->lData = 0;
  647. lpCPlInfo->szHelpFile[0] = '\0';
  648. return TRUE;
  649. case CPL_DBLCLK:
  650. AddHardwareWizard(hWnd, NULL);
  651. break;
  652. case CPL_STARTWPARMS:
  653. //
  654. // what does this mean ?
  655. //
  656. break;
  657. case CPL_EXIT:
  658. // Free up any allocations of resources made.
  659. break;
  660. default:
  661. break;
  662. }
  663. return 0L;
  664. }
  665. BOOL DllInitialize(
  666. IN PVOID hmod,
  667. IN ULONG ulReason,
  668. IN PCONTEXT pctx OPTIONAL
  669. )
  670. {
  671. hHdwWiz = hmod;
  672. if (ulReason == DLL_PROCESS_ATTACH) {
  673. DisableThreadLibraryCalls(hmod);
  674. SHFusionInitializeFromModule(hmod);
  675. } else if (ulReason == DLL_PROCESS_DETACH) {
  676. SHFusionUninitialize();
  677. }
  678. return TRUE;
  679. }