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.

861 lines
27 KiB

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