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.

3797 lines
102 KiB

  1. /*++
  2. Copyright (c) 1997-1999 Microsoft Corporation
  3. Module Name:
  4. install2.cpp
  5. Abstract:
  6. This file implements the display class installer.
  7. Environment:
  8. WIN32 User Mode
  9. --*/
  10. #include <initguid.h>
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. #include <tchar.h>
  14. #include <devguid.h>
  15. //
  16. // Defines
  17. //
  18. #define INSETUP 1
  19. #define INSETUP_UPGRADE 2
  20. #define SZ_UPGRADE_DESCRIPTION TEXT("_RealDescription")
  21. #define SZ_UPGRADE_MFG TEXT("_RealMfg")
  22. #define SZ_DEFAULT_DESCRIPTION TEXT("Video Display Adapter")
  23. #define SZ_DEFAULT_MFG TEXT("Microsoft")
  24. #define SZ_LEGACY_UPGRADE TEXT("_LegacyUpgradeDevice")
  25. #define SZ_ROOT_LEGACY TEXT("ROOT\\LEGACY_")
  26. #define SZ_ROOT TEXT("ROOT\\")
  27. #define SZ_BINARY_LEN 32
  28. #define ByteCountOf(x) ((x) * sizeof(TCHAR))
  29. //
  30. // Data types
  31. //
  32. typedef struct _DEVDATA {
  33. SP_DEVINFO_DATA did;
  34. TCHAR szBinary[SZ_BINARY_LEN];
  35. TCHAR szService[SZ_BINARY_LEN];
  36. } DEVDATA, *PDEVDATA;
  37. //
  38. // Forward declarations
  39. //
  40. BOOL CDECL
  41. DeskLogError(
  42. LogSeverity Severity,
  43. UINT MsgId,
  44. ...
  45. );
  46. DWORD
  47. DeskGetSetupFlags(
  48. VOID
  49. );
  50. BOOL
  51. DeskIsLegacyDevNodeByPath(
  52. const PTCHAR szRegPath
  53. );
  54. BOOL
  55. DeskIsLegacyDevNodeByDevInfo(
  56. PSP_DEVINFO_DATA pDid
  57. );
  58. BOOL
  59. DeskIsRootDevNodeByDevInfo(
  60. PSP_DEVINFO_DATA pDid
  61. );
  62. BOOL
  63. DeskGetDevNodePath(
  64. IN PSP_DEVINFO_DATA pDid,
  65. IN OUT PTCHAR szPath,
  66. IN LONG len
  67. );
  68. VOID
  69. DeskSetServiceStartType(
  70. LPTSTR ServiceName,
  71. DWORD dwStartType
  72. );
  73. DWORD
  74. DeskInstallService(
  75. IN HDEVINFO hDevInfo,
  76. IN PSP_DEVINFO_DATA pDeviceInfoData OPTIONAL,
  77. IN LPTSTR pServiceName
  78. );
  79. DWORD
  80. DeskInstallServiceExtensions(
  81. IN HWND hwnd,
  82. IN HDEVINFO hDevInfo,
  83. IN PSP_DEVINFO_DATA pDeviceInfoData,
  84. IN PSP_DRVINFO_DATA DriverInfoData,
  85. IN PSP_DRVINFO_DETAIL_DATA DriverInfoDetailData,
  86. IN LPTSTR pServiceName
  87. );
  88. VOID
  89. DeskMarkUpNewDevNode(
  90. IN HDEVINFO hDevInfo,
  91. IN PSP_DEVINFO_DATA pDeviceInfoData
  92. );
  93. VOID
  94. DeskNukeDevNode(
  95. LPTSTR szService,
  96. HDEVINFO hDevInfo,
  97. PSP_DEVINFO_DATA pDeviceInfoData
  98. );
  99. PTCHAR
  100. DeskFindMatchingId(
  101. PTCHAR DeviceId,
  102. PTCHAR IdList
  103. );
  104. UINT
  105. DeskDisableLegacyDeviceNodes(
  106. VOID
  107. );
  108. VOID
  109. DeskDisableServices(
  110. );
  111. DWORD
  112. DeskPerformDatabaseUpgrade(
  113. HINF hInf,
  114. PINFCONTEXT pInfContext,
  115. BOOL bUpgrade,
  116. PTCHAR szDriverListSection,
  117. BOOL* pbForceDeleteAppletExt
  118. );
  119. DWORD
  120. DeskCheckDatabase(
  121. IN HDEVINFO hDevInfo,
  122. IN PSP_DEVINFO_DATA pDeviceInfoData,
  123. BOOL* pbDeleteAppletExt
  124. );
  125. VOID
  126. DeskGetUpgradeDeviceStrings(
  127. PTCHAR Description,
  128. PTCHAR MfgName,
  129. PTCHAR ProviderName
  130. );
  131. DWORD
  132. OnAllowInstall(
  133. IN HDEVINFO hDevInfo,
  134. IN PSP_DEVINFO_DATA pDeviceInfoData
  135. );
  136. DWORD
  137. OnSelectBestCompatDrv(
  138. IN HDEVINFO hDevInfo,
  139. IN PSP_DEVINFO_DATA pDeviceInfoData
  140. );
  141. DWORD
  142. OnSelectDevice(
  143. IN HDEVINFO hDevInfo,
  144. IN PSP_DEVINFO_DATA pDeviceInfoData OPTIONAL
  145. );
  146. DWORD
  147. OnInstallDevice(
  148. IN HDEVINFO hDevInfo,
  149. IN PSP_DEVINFO_DATA pDeviceInfoData
  150. );
  151. BOOL
  152. DeskGetVideoDeviceKey(
  153. IN HDEVINFO hDevInfo,
  154. IN PSP_DEVINFO_DATA pDeviceInfoData,
  155. IN LPTSTR pServiceName,
  156. IN DWORD DeviceX,
  157. OUT HKEY* phkDevice
  158. );
  159. BOOL
  160. DeskIsServiceDisableable(
  161. PTCHAR szService
  162. );
  163. VOID
  164. DeskDeleteAppletExtensions(
  165. IN HDEVINFO hDevInfo,
  166. IN PSP_DEVINFO_DATA pDeviceInfoData
  167. );
  168. VOID
  169. DeskAEDelete(
  170. PTCHAR szDeleteFrom,
  171. PTCHAR mszExtensionsToRemove
  172. );
  173. VOID
  174. DeskAEMove(
  175. HDEVINFO hDevInfo,
  176. PSP_DEVINFO_DATA pDeviceInfoData,
  177. HKEY hkMoveFrom,
  178. PAPPEXT pAppExtBefore,
  179. PAPPEXT pAppExtAfter
  180. );
  181. //
  182. // Display class installer
  183. //
  184. DWORD
  185. DisplayClassInstaller(
  186. IN DI_FUNCTION InstallFunction,
  187. IN HDEVINFO hDevInfo,
  188. IN PSP_DEVINFO_DATA pDeviceInfoData OPTIONAL
  189. )
  190. /*++
  191. Routine Description:
  192. This routine acts as the class installer for Display devices.
  193. Arguments:
  194. InstallFunction - Specifies the device installer function code indicating
  195. the action being performed.
  196. DeviceInfoSet - Supplies a handle to the device information set being
  197. acted upon by this install action.
  198. pDeviceInfoData - Optionally, supplies the address of a device information
  199. element being acted upon by this install action.
  200. Return Value:
  201. If this function successfully completed the requested action, the return
  202. value is NO_ERROR.
  203. If the default behavior is to be performed for the requested action, the
  204. return value is ERROR_DI_DO_DEFAULT.
  205. If an error occurred while attempting to perform the requested action, a
  206. Win32 error code is returned.
  207. --*/
  208. {
  209. DWORD retVal = ERROR_DI_DO_DEFAULT;
  210. BOOL bHandled = TRUE;
  211. TCHAR szDevNode[LINE_LEN];
  212. DeskOpenLog();
  213. switch(InstallFunction) {
  214. case DIF_SELECTDEVICE :
  215. retVal = OnSelectDevice(hDevInfo, pDeviceInfoData);
  216. break;
  217. case DIF_SELECTBESTCOMPATDRV :
  218. retVal = OnSelectBestCompatDrv(hDevInfo, pDeviceInfoData);
  219. break;
  220. case DIF_ALLOW_INSTALL :
  221. retVal = OnAllowInstall(hDevInfo, pDeviceInfoData);
  222. break;
  223. case DIF_INSTALLDEVICE :
  224. retVal = OnInstallDevice(hDevInfo, pDeviceInfoData);
  225. break;
  226. default:
  227. bHandled = FALSE;
  228. break;
  229. }
  230. if (bHandled &&
  231. (pDeviceInfoData != NULL) &&
  232. (DeskGetDevNodePath(pDeviceInfoData, szDevNode, LINE_LEN-1)))
  233. {
  234. DeskLogError(LogSevInformation,
  235. IDS_SETUPLOG_MSG_125,
  236. retVal,
  237. InstallFunction,
  238. szDevNode);
  239. }
  240. else
  241. {
  242. DeskLogError(LogSevInformation,
  243. IDS_SETUPLOG_MSG_057,
  244. retVal,
  245. InstallFunction);
  246. }
  247. DeskCloseLog();
  248. //
  249. // If we did not exit from the routine by handling the call,
  250. // tell the setup code to handle everything the default way.
  251. //
  252. return retVal;
  253. }
  254. /*
  255. void StrClearHighBits(LPTSTR pszString, DWORD cchSize)
  256. {
  257. // This string can not have any high bits set
  258. }
  259. */
  260. // Monitor class installer
  261. DWORD
  262. MonitorClassInstaller(
  263. IN DI_FUNCTION InstallFunction,
  264. IN HDEVINFO hDevInfo,
  265. IN PSP_DEVINFO_DATA pDeviceInfoData OPTIONAL
  266. )
  267. /*++
  268. Routine Description:
  269. This routine acts as the class installer for Display devices.
  270. Arguments:
  271. InstallFunction - Specifies the device installer function code indicating
  272. the action being performed.
  273. DeviceInfoSet - Supplies a handle to the device information set being
  274. acted upon by this install action.
  275. pDeviceInfoData - Optionally, supplies the address of a device information
  276. element being acted upon by this install action.
  277. Return Value:
  278. If this function successfully completed the requested action, the return
  279. value is NO_ERROR.
  280. If the default behavior is to be performed for the requested action, the
  281. return value is ERROR_DI_DO_DEFAULT.
  282. If an error occurred while attempting to perform the requested action, a
  283. Win32 error code is returned.
  284. --*/
  285. {
  286. return ERROR_DI_DO_DEFAULT;
  287. }
  288. //
  289. // Handler functions
  290. //
  291. DWORD
  292. OnAllowInstall(
  293. IN HDEVINFO hDevInfo,
  294. IN PSP_DEVINFO_DATA pDeviceInfoData
  295. )
  296. {
  297. SP_DRVINFO_DATA DriverInfoData;
  298. SP_DRVINFO_DETAIL_DATA DriverInfoDetailData;
  299. DWORD cbOutputSize;
  300. HINF hInf = INVALID_HANDLE_VALUE;
  301. TCHAR ActualInfSection[LINE_LEN];
  302. INFCONTEXT InfContext;
  303. ULONG DevStatus = 0, DevProblem = 0;
  304. CONFIGRET Result;
  305. DWORD dwRet = ERROR_DI_DO_DEFAULT;
  306. ASSERT (pDeviceInfoData != NULL);
  307. //
  308. // Do not allow install if the device is to be removed.
  309. //
  310. Result = CM_Get_DevNode_Status(&DevStatus,
  311. &DevProblem,
  312. pDeviceInfoData->DevInst,
  313. 0);
  314. if ((Result == CR_SUCCESS) &&
  315. ((DevStatus & DN_WILL_BE_REMOVED) != 0)) {
  316. //
  317. // Message Box?
  318. //
  319. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_099);
  320. dwRet = ERROR_DI_DONT_INSTALL;
  321. goto Fallout;
  322. }
  323. //
  324. // Check for a Win95 Driver
  325. //
  326. DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
  327. if (!SetupDiGetSelectedDriver(hDevInfo,
  328. pDeviceInfoData,
  329. &DriverInfoData))
  330. {
  331. DeskLogError(LogSevInformation,
  332. IDS_SETUPLOG_MSG_126,
  333. TEXT("OnAllowInstall: SetupDiGetSelectedDriver"),
  334. GetLastError());
  335. goto Fallout;
  336. }
  337. DriverInfoDetailData.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
  338. if (!(SetupDiGetDriverInfoDetail(hDevInfo,
  339. pDeviceInfoData,
  340. &DriverInfoData,
  341. &DriverInfoDetailData,
  342. DriverInfoDetailData.cbSize,
  343. &cbOutputSize)) &&
  344. (GetLastError() != ERROR_INSUFFICIENT_BUFFER))
  345. {
  346. DeskLogError(LogSevInformation,
  347. IDS_SETUPLOG_MSG_126,
  348. TEXT("OnAllowInstall: SetupDiGetDriverInfoDetail"),
  349. GetLastError());
  350. goto Fallout;
  351. }
  352. //
  353. // Open the INF that installs this driver node, so we can 'pre-run' the
  354. // AddService/DelService entries in its install service install section.
  355. //
  356. hInf = SetupOpenInfFile(DriverInfoDetailData.InfFileName,
  357. NULL,
  358. INF_STYLE_WIN4,
  359. NULL);
  360. if (hInf == INVALID_HANDLE_VALUE)
  361. {
  362. //
  363. // For some reason we couldn't open the INF--this should never happen.
  364. //
  365. DeskLogError(LogSevInformation,
  366. IDS_SETUPLOG_MSG_127,
  367. TEXT("OnAllowInstall: SetupOpenInfFile"));
  368. goto Fallout;
  369. }
  370. //
  371. // Now find the actual (potentially OS/platform-specific) install section name.
  372. //
  373. if (!SetupDiGetActualSectionToInstall(hInf,
  374. DriverInfoDetailData.SectionName,
  375. ActualInfSection,
  376. ARRAYSIZE(ActualInfSection),
  377. NULL,
  378. NULL))
  379. {
  380. DeskLogError(LogSevInformation,
  381. IDS_SETUPLOG_MSG_126,
  382. TEXT("OnAllowInstall: SetupDiGetActualSectionToInstall"),
  383. GetLastError());
  384. goto Fallout;
  385. }
  386. //
  387. // Append a ".Services" to get the service install section name.
  388. //
  389. lstrcat(ActualInfSection, TEXT(".Services"));
  390. //
  391. // See if the section exists.
  392. //
  393. if (!SetupFindFirstLine(hInf,
  394. ActualInfSection,
  395. NULL,
  396. &InfContext))
  397. {
  398. //
  399. // Message Box?
  400. //
  401. DeskLogError(LogSevError,
  402. IDS_SETUPLOG_MSG_041,
  403. DriverInfoDetailData.InfFileName);
  404. dwRet = ERROR_NON_WINDOWS_NT_DRIVER;
  405. }
  406. Fallout:
  407. if (hInf != INVALID_HANDLE_VALUE) {
  408. SetupCloseInfFile(hInf);
  409. }
  410. return dwRet;
  411. }
  412. VOID
  413. DeskModifyDriverRank(
  414. IN HDEVINFO hDevInfo,
  415. IN PSP_DEVINFO_DATA pDeviceInfoData
  416. )
  417. {
  418. //
  419. // Regardless of whether a driver is properly signed or not
  420. // we don't want any W2K drivers to be choosen by default. We have
  421. // simply found to many w2k drivers that don't work well on
  422. // windows XP. So instead lets treat all drivers signed or not
  423. // as unsigned if they were released before we started signing
  424. // windows xp drivers. [We have to do this because some w2k
  425. // drivers were incorrectly signed as winxp (5.x) drivers]
  426. //
  427. ULONG i=0;
  428. SP_DRVINFO_DATA_V2 DrvInfoData;
  429. SP_DRVINSTALL_PARAMS DrvInstallParams;
  430. SYSTEMTIME SystemTime;
  431. DrvInfoData.cbSize = sizeof(SP_DRVINFO_DATA_V2);
  432. while (SetupDiEnumDriverInfo(hDevInfo,
  433. pDeviceInfoData,
  434. SPDIT_COMPATDRIVER,
  435. i++,
  436. &DrvInfoData)) {
  437. if (FileTimeToSystemTime(&DrvInfoData.DriverDate, &SystemTime)) {
  438. if (((SystemTime.wYear < 2001) ||
  439. ((SystemTime.wYear == 2001) && (SystemTime.wMonth < 6)))) {
  440. //
  441. // If this was created before Jun. 2001 then we want to make it a
  442. // worse match than our in the box driver. We'll do this by
  443. // treating it as unsigned.
  444. //
  445. ZeroMemory(&DrvInstallParams, sizeof(SP_DRVINSTALL_PARAMS));
  446. DrvInstallParams.cbSize = sizeof(SP_DRVINSTALL_PARAMS);
  447. if (SetupDiGetDriverInstallParams(hDevInfo,
  448. pDeviceInfoData,
  449. &DrvInfoData,
  450. &DrvInstallParams)) {
  451. DrvInstallParams.Rank |= DRIVER_UNTRUSTED_RANK;
  452. SetupDiSetDriverInstallParams(hDevInfo,
  453. pDeviceInfoData,
  454. &DrvInfoData,
  455. &DrvInstallParams);
  456. }
  457. }
  458. }
  459. }
  460. }
  461. DWORD
  462. OnSelectBestCompatDrv(
  463. IN HDEVINFO hDevInfo,
  464. IN PSP_DEVINFO_DATA pDeviceInfoData
  465. )
  466. {
  467. SP_DEVINSTALL_PARAMS DevInstParam;
  468. SP_DRVINFO_DATA DrvInfoData;
  469. PTCHAR szDesc = NULL, szMfg = NULL;
  470. HKEY hKey;
  471. DWORD dwFailed;
  472. BOOL bDummy = FALSE;
  473. DWORD dwLegacyUpgrade = 1;
  474. DWORD dwRet = ERROR_DI_DO_DEFAULT;
  475. DeskModifyDriverRank(hDevInfo, pDeviceInfoData);
  476. if (DeskIsLegacyDevNodeByDevInfo(pDeviceInfoData)) {
  477. //
  478. // Always allow root devices in select
  479. //
  480. goto Fallout;
  481. }
  482. //
  483. // Check the database to see if this is an approved driver.
  484. // We need the test only during an upgrade.
  485. //
  486. if (((DeskGetSetupFlags() & INSETUP_UPGRADE) == 0) ||
  487. (DeskCheckDatabase(hDevInfo,
  488. pDeviceInfoData,
  489. &bDummy) == ERROR_SUCCESS)) {
  490. //
  491. // It is, no other work is necessary
  492. //
  493. goto Fallout;
  494. }
  495. //
  496. // This particular vid card is not allowed to run with drivers out
  497. // of the box. Note this event in the reg and save off other values.
  498. // Also, install a fake device onto the devnode so that the user doesn't
  499. // get PnP popus upon first (real) boot
  500. //
  501. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_046);
  502. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  503. SZ_UPDATE_SETTINGS,
  504. 0,
  505. KEY_ALL_ACCESS,
  506. &hKey) == ERROR_SUCCESS) {
  507. //
  508. // Save off the fact that upgrade was not allowed (used in migrated
  509. // display settings in the display OC
  510. //
  511. dwFailed = 1;
  512. RegSetValueEx(hKey,
  513. SZ_UPGRADE_FAILED_ALLOW_INSTALL,
  514. 0,
  515. REG_DWORD,
  516. (PBYTE) &dwFailed,
  517. sizeof(DWORD));
  518. RegCloseKey(hKey);
  519. }
  520. //
  521. // Grab the description of the device so we can give it to the devnode
  522. // after a succesfull install of the fake devnode
  523. //
  524. ZeroMemory(&DrvInfoData, sizeof(DrvInfoData));
  525. DrvInfoData.cbSize = sizeof(DrvInfoData);
  526. if (SetupDiEnumDriverInfo(hDevInfo,
  527. pDeviceInfoData,
  528. SPDIT_COMPATDRIVER,
  529. 0,
  530. &DrvInfoData)) {
  531. if (lstrlen(DrvInfoData.Description)) {
  532. szDesc = DrvInfoData.Description;
  533. }
  534. if (lstrlen(DrvInfoData.MfgName)) {
  535. szMfg = DrvInfoData.MfgName;
  536. }
  537. } else {
  538. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_047);
  539. }
  540. if (!szDesc) {
  541. szDesc = SZ_DEFAULT_DESCRIPTION;
  542. }
  543. if (!szMfg) {
  544. szMfg = SZ_DEFAULT_MFG;
  545. }
  546. //
  547. // Save the description of the device under the device registry key
  548. //
  549. if ((hKey = SetupDiCreateDevRegKey(hDevInfo,
  550. pDeviceInfoData,
  551. DICS_FLAG_GLOBAL,
  552. 0,
  553. DIREG_DEV,
  554. NULL,
  555. NULL)) != INVALID_HANDLE_VALUE) {
  556. RegSetValueEx(hKey,
  557. SZ_UPGRADE_DESCRIPTION,
  558. 0,
  559. REG_SZ,
  560. (PBYTE) szDesc,
  561. ByteCountOf(lstrlen(szDesc) + 1));
  562. RegSetValueEx(hKey,
  563. SZ_UPGRADE_MFG,
  564. 0,
  565. REG_SZ,
  566. (PBYTE) szMfg,
  567. ByteCountOf(lstrlen(szMfg) + 1));
  568. RegSetValueEx(hKey,
  569. SZ_LEGACY_UPGRADE,
  570. 0,
  571. REG_DWORD,
  572. (PBYTE)&dwLegacyUpgrade,
  573. sizeof(DWORD));
  574. RegCloseKey(hKey);
  575. } else {
  576. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_048);
  577. }
  578. //
  579. // Make sure there isn't already a class driver list built for this
  580. // device information element
  581. //
  582. if (!SetupDiDestroyDriverInfoList(hDevInfo, pDeviceInfoData, SPDIT_CLASSDRIVER)) {
  583. DeskLogError(LogSevInformation,
  584. IDS_SETUPLOG_MSG_127,
  585. TEXT("OnSelectBestCompatDrv: SetupDiDestroyDriverInfoList"));
  586. }
  587. //
  588. // Build a class driver list off of display.inf.
  589. //
  590. DevInstParam.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
  591. if (!SetupDiGetDeviceInstallParams(hDevInfo, pDeviceInfoData, &DevInstParam)) {
  592. DeskLogError(LogSevInformation,
  593. IDS_SETUPLOG_MSG_126,
  594. TEXT("OnSelectBestCompatDrv: SetupDiGetDeviceInstallParams"),
  595. GetLastError());
  596. goto Fallout;
  597. }
  598. DevInstParam.Flags |= DI_ENUMSINGLEINF;
  599. lstrcpy(DevInstParam.DriverPath, TEXT("display.inf"));
  600. if (!SetupDiSetDeviceInstallParams(hDevInfo, pDeviceInfoData, &DevInstParam)) {
  601. DeskLogError(LogSevInformation,
  602. IDS_SETUPLOG_MSG_126,
  603. TEXT("OnSelectBestCompatDrv: SetupDiSetDeviceInstallParams"),
  604. GetLastError());
  605. goto Fallout;
  606. }
  607. if (!SetupDiBuildDriverInfoList(hDevInfo, pDeviceInfoData, SPDIT_CLASSDRIVER)) {
  608. DeskLogError(LogSevInformation,
  609. IDS_SETUPLOG_MSG_126,
  610. TEXT("OnSelectBestCompatDrv: SetupDiBuildDriverInfoList"),
  611. GetLastError());
  612. goto Fallout;
  613. }
  614. //
  615. // Now select the fake node.
  616. // All strings here match the inf fake device entry section.
  617. // If the INF is modified in any way WRT to these strings,
  618. // these to be changed as well
  619. //
  620. ZeroMemory(&DrvInfoData, sizeof(SP_DRVINFO_DATA));
  621. DrvInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
  622. DrvInfoData.DriverType = SPDIT_CLASSDRIVER;
  623. DeskGetUpgradeDeviceStrings(DrvInfoData.Description,
  624. DrvInfoData.MfgName,
  625. DrvInfoData.ProviderName);
  626. if (!SetupDiSetSelectedDriver(hDevInfo, pDeviceInfoData, &DrvInfoData)) {
  627. DeskLogError(LogSevInformation,
  628. IDS_SETUPLOG_MSG_126,
  629. TEXT("OnSelectBestCompatDrv: SetupDiSetSelectedDriver"),
  630. GetLastError());
  631. goto Fallout;
  632. }
  633. dwRet = NO_ERROR;
  634. Fallout:
  635. return dwRet;
  636. }
  637. DWORD
  638. OnSelectDevice(
  639. IN HDEVINFO hDevInfo,
  640. IN PSP_DEVINFO_DATA pDeviceInfoData OPTIONAL
  641. )
  642. {
  643. DWORD retVal = ERROR_DI_DO_DEFAULT;
  644. DWORD index = 0, reqSize = 0, curSize = 0;
  645. PSP_DRVINFO_DETAIL_DATA pDrvInfoDetailData = NULL;
  646. SP_DRVINFO_DATA DrvInfoData;
  647. SP_DRVINSTALL_PARAMS DrvInstallParams;
  648. //
  649. // Build the list of drivers
  650. //
  651. if (!SetupDiBuildDriverInfoList(hDevInfo,
  652. pDeviceInfoData,
  653. SPDIT_CLASSDRIVER)) {
  654. DeskLogError(LogSevInformation,
  655. IDS_SETUPLOG_MSG_126,
  656. TEXT("OnSelectDevice: SetupDiBuildDriverInfoList"),
  657. GetLastError());
  658. goto Fallout;
  659. }
  660. ZeroMemory(&DrvInfoData, sizeof(SP_DRVINFO_DATA));
  661. DrvInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
  662. while (SetupDiEnumDriverInfo(hDevInfo,
  663. pDeviceInfoData,
  664. SPDIT_CLASSDRIVER,
  665. index,
  666. &DrvInfoData)) {
  667. //
  668. // Get the required size
  669. //
  670. reqSize = 0;
  671. SetupDiGetDriverInfoDetail(hDevInfo,
  672. pDeviceInfoData,
  673. &DrvInfoData,
  674. NULL,
  675. 0,
  676. &reqSize);
  677. if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
  678. DeskLogError(LogSevInformation,
  679. IDS_SETUPLOG_MSG_126,
  680. TEXT("OnSelectDevice: SetupDiGetDriverInfoDetail"),
  681. GetLastError());
  682. goto Fallout;
  683. }
  684. //
  685. // Allocate memory, if needed
  686. //
  687. if ((reqSize > curSize) || (pDrvInfoDetailData == NULL)) {
  688. curSize = reqSize;
  689. if (pDrvInfoDetailData != NULL) {
  690. LocalFree(pDrvInfoDetailData);
  691. }
  692. pDrvInfoDetailData = (PSP_DRVINFO_DETAIL_DATA)LocalAlloc(LPTR, curSize);
  693. if (pDrvInfoDetailData == NULL) {
  694. DeskLogError(LogSevInformation,
  695. IDS_SETUPLOG_MSG_127,
  696. TEXT("OnSelectDevice: LocalAlloc"));
  697. goto Fallout;
  698. }
  699. } else {
  700. ZeroMemory(pDrvInfoDetailData, reqSize);
  701. }
  702. //
  703. // Get the driver detail info
  704. //
  705. pDrvInfoDetailData->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
  706. if (!SetupDiGetDriverInfoDetail(hDevInfo,
  707. pDeviceInfoData,
  708. &DrvInfoData,
  709. pDrvInfoDetailData,
  710. reqSize,
  711. NULL)) {
  712. DeskLogError(LogSevInformation,
  713. IDS_SETUPLOG_MSG_126,
  714. TEXT("OnSelectDevice: SetupDiGetDriverInfoDetail"),
  715. GetLastError());
  716. goto Fallout;
  717. }
  718. if (lstrcmpi(pDrvInfoDetailData->HardwareID,
  719. TEXT("LEGACY_UPGRADE_ID")) == 0) {
  720. //
  721. // Mark the legacy upgrade drv. info as "bad" so that it is
  722. // not shown when the user is prompted to select the driver
  723. //
  724. ZeroMemory(&DrvInstallParams, sizeof(SP_DRVINSTALL_PARAMS));
  725. DrvInstallParams.cbSize = sizeof(SP_DRVINSTALL_PARAMS);
  726. if (SetupDiGetDriverInstallParams(hDevInfo,
  727. pDeviceInfoData,
  728. &DrvInfoData,
  729. &DrvInstallParams)) {
  730. DrvInstallParams.Flags |= DNF_BAD_DRIVER;
  731. SetupDiSetDriverInstallParams(hDevInfo,
  732. pDeviceInfoData,
  733. &DrvInfoData,
  734. &DrvInstallParams);
  735. }
  736. }
  737. //
  738. // Get the next driver info
  739. //
  740. ZeroMemory(&DrvInfoData, sizeof(SP_DRVINFO_DATA));
  741. DrvInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
  742. ++index;
  743. }
  744. Fallout:
  745. if (pDrvInfoDetailData) {
  746. LocalFree(pDrvInfoDetailData);
  747. }
  748. return retVal;
  749. }
  750. DWORD
  751. OnInstallDevice(
  752. IN HDEVINFO hDevInfo,
  753. IN PSP_DEVINFO_DATA pDeviceInfoData
  754. )
  755. {
  756. DWORD retVal = ERROR_DI_DO_DEFAULT;
  757. DWORD dwLegacyUpgrade, dwSize;
  758. DISPLAY_DEVICE displayDevice;
  759. TCHAR szBuffer[LINE_LEN];
  760. PTCHAR szHardwareIds = NULL;
  761. BOOL bDisableLegacyDevices = TRUE;
  762. ULONG len = 0;
  763. HKEY hkDevKey;
  764. //
  765. // Disable legacy devices if pDeviceInfoData is not:
  766. // - a root device or
  767. // - legacy upgrade device
  768. //
  769. if (DeskIsRootDevNodeByDevInfo(pDeviceInfoData)) {
  770. //
  771. // Root device
  772. //
  773. bDisableLegacyDevices = FALSE;
  774. } else {
  775. //
  776. // Is this the legacy upgrade device?
  777. //
  778. hkDevKey = SetupDiOpenDevRegKey(hDevInfo,
  779. pDeviceInfoData,
  780. DICS_FLAG_GLOBAL,
  781. 0,
  782. DIREG_DEV,
  783. KEY_ALL_ACCESS);
  784. if (hkDevKey != INVALID_HANDLE_VALUE) {
  785. dwSize = sizeof(DWORD);
  786. if (RegQueryValueEx(hkDevKey,
  787. SZ_LEGACY_UPGRADE,
  788. 0,
  789. NULL,
  790. (PBYTE)&dwLegacyUpgrade,
  791. &dwSize) == ERROR_SUCCESS) {
  792. if (dwLegacyUpgrade == 1) {
  793. //
  794. // Legacy upgrade device
  795. //
  796. bDisableLegacyDevices = FALSE;
  797. }
  798. RegDeleteValue(hkDevKey, SZ_LEGACY_UPGRADE);
  799. }
  800. RegCloseKey(hkDevKey);
  801. }
  802. }
  803. if (bDisableLegacyDevices) {
  804. if ((DeskGetSetupFlags() & INSETUP_UPGRADE) != 0) {
  805. //
  806. // Delete legacy applet extensions
  807. //
  808. DeskDeleteAppletExtensions(hDevInfo, pDeviceInfoData);
  809. }
  810. //
  811. // Disable legacy devices
  812. //
  813. DeskDisableLegacyDeviceNodes();
  814. }
  815. retVal = DeskInstallService(hDevInfo,
  816. pDeviceInfoData,
  817. szBuffer);
  818. if ((retVal == ERROR_NO_DRIVER_SELECTED) &&
  819. (DeskGetSetupFlags() & INSETUP_UPGRADE) &&
  820. DeskIsLegacyDevNodeByDevInfo(pDeviceInfoData)) {
  821. //
  822. // If this is a legacy device and no driver is selected,
  823. // let the default handler install a NULL driver.
  824. //
  825. retVal = ERROR_DI_DO_DEFAULT;
  826. }
  827. //
  828. // Calling EnumDisplayDevices will rescan the devices, and if a
  829. // new device is detected, we will disable and reenable the main
  830. // device. This reset of the display device will clear up any
  831. // mess caused by installing a new driver
  832. //
  833. displayDevice.cb = sizeof(DISPLAY_DEVICE);
  834. EnumDisplayDevices(NULL, 0, &displayDevice, 0);
  835. return retVal;
  836. }
  837. //
  838. // Logging function
  839. //
  840. BOOL CDECL
  841. DeskLogError(
  842. LogSeverity Severity,
  843. UINT MsgId,
  844. ...
  845. )
  846. /*++
  847. Outputs a message to the setup log. Prepends "desk.cpl " to the strings and
  848. appends the correct newline chars (\r\n)
  849. --*/
  850. {
  851. int cch;
  852. TCHAR ach[1024+40]; // Largest path plus extra
  853. TCHAR szMsg[1024]; // MsgId
  854. va_list vArgs;
  855. static int setupState = 0;
  856. if (setupState == 0) {
  857. if (DeskGetSetupFlags() & (INSETUP | INSETUP_UPGRADE)) {
  858. setupState = 1;
  859. } else {
  860. setupState = 2;
  861. }
  862. }
  863. if (setupState == 1) {
  864. *szMsg = 0;
  865. if (LoadString(hInstance,
  866. MsgId,
  867. szMsg,
  868. ARRAYSIZE(szMsg))) {
  869. *ach = 0;
  870. LoadString(hInstance,
  871. IDS_SETUPLOG_MSG_000,
  872. ach,
  873. ARRAYSIZE(ach));
  874. cch = lstrlen(ach);
  875. va_start(vArgs, MsgId);
  876. wvsprintf(&ach[cch], szMsg, vArgs);
  877. lstrcat(ach, TEXT("\r\n"));
  878. va_end(vArgs);
  879. return SetupLogError(ach, Severity);
  880. } else {
  881. return FALSE;
  882. }
  883. } else {
  884. va_start(vArgs, MsgId);
  885. va_end(vArgs);
  886. return TRUE;
  887. }
  888. }
  889. //
  890. // Service Controller stuff
  891. //
  892. VOID
  893. DeskSetServiceStartType(
  894. LPTSTR ServiceName,
  895. DWORD dwStartType
  896. )
  897. {
  898. SC_HANDLE SCMHandle;
  899. SC_HANDLE ServiceHandle;
  900. ULONG Attempts;
  901. SC_LOCK SCLock = NULL;
  902. ULONG ServiceConfigSize = 0;
  903. LPQUERY_SERVICE_CONFIG ServiceConfig;
  904. //
  905. // Open the service controller
  906. // Open the service
  907. // Change the service.
  908. //
  909. if (SCMHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS))
  910. {
  911. if (ServiceHandle = OpenService(SCMHandle, ServiceName, SERVICE_ALL_ACCESS))
  912. {
  913. QueryServiceConfig(ServiceHandle,
  914. NULL,
  915. 0,
  916. &ServiceConfigSize);
  917. ASSERT(GetLastError() == ERROR_INSUFFICIENT_BUFFER);
  918. if (ServiceConfig = (LPQUERY_SERVICE_CONFIG)
  919. LocalAlloc(LPTR, ServiceConfigSize))
  920. {
  921. if (QueryServiceConfig(ServiceHandle,
  922. ServiceConfig,
  923. ServiceConfigSize,
  924. &ServiceConfigSize))
  925. {
  926. //
  927. // Attempt to acquite the database lock.
  928. //
  929. for (Attempts = 20;
  930. ((SCLock = LockServiceDatabase(SCMHandle)) == NULL) && Attempts;
  931. Attempts--)
  932. {
  933. //
  934. // Lock SC database locked
  935. //
  936. Sleep(500);
  937. }
  938. //
  939. // Change the service to demand start
  940. //
  941. if (!ChangeServiceConfig(ServiceHandle,
  942. SERVICE_NO_CHANGE,
  943. dwStartType,
  944. SERVICE_NO_CHANGE,
  945. NULL,
  946. NULL,
  947. NULL,
  948. NULL,
  949. NULL,
  950. NULL,
  951. NULL))
  952. {
  953. DeskLogError(LogSevInformation,
  954. IDS_SETUPLOG_MSG_126,
  955. TEXT("DeskSetServiceStartType: ChangeServiceConfig"),
  956. GetLastError());
  957. }
  958. if (SCLock)
  959. {
  960. UnlockServiceDatabase(SCLock);
  961. }
  962. } else {
  963. DeskLogError(LogSevInformation,
  964. IDS_SETUPLOG_MSG_126,
  965. TEXT("DeskSetServiceStartType: QueryServiceConfig"),
  966. GetLastError());
  967. }
  968. LocalFree(ServiceConfig);
  969. } else {
  970. DeskLogError(LogSevInformation,
  971. IDS_SETUPLOG_MSG_127,
  972. TEXT("DeskSetServiceStartType: LocalAlloc"));
  973. }
  974. CloseServiceHandle(ServiceHandle);
  975. } else {
  976. DeskLogError(LogSevInformation,
  977. IDS_SETUPLOG_MSG_126,
  978. TEXT("DeskSetServiceStartType: OpenService"),
  979. GetLastError());
  980. }
  981. CloseServiceHandle(SCMHandle);
  982. } else {
  983. DeskLogError(LogSevInformation,
  984. IDS_SETUPLOG_MSG_126,
  985. TEXT("DeskSetServiceStartType: OpenSCManager"),
  986. GetLastError());
  987. }
  988. }
  989. //
  990. // Service Installation
  991. //
  992. DWORD
  993. DeskInstallServiceExtensions(
  994. IN HWND hwnd,
  995. IN HDEVINFO hDevInfo,
  996. IN PSP_DEVINFO_DATA pDeviceInfoData,
  997. IN PSP_DRVINFO_DATA DriverInfoData,
  998. IN PSP_DRVINFO_DETAIL_DATA DriverInfoDetailData,
  999. IN LPTSTR pServiceName
  1000. )
  1001. {
  1002. DWORD retVal = NO_ERROR;
  1003. HINF InfFileHandle;
  1004. INFCONTEXT tmpContext;
  1005. TCHAR szSoftwareSection[LINE_LEN];
  1006. INT maxmem;
  1007. INT numDev;
  1008. #ifndef _WIN64
  1009. SP_DEVINSTALL_PARAMS DeviceInstallParams;
  1010. #endif
  1011. TCHAR keyName[LINE_LEN];
  1012. DWORD disposition;
  1013. HKEY hkey;
  1014. //
  1015. // Open the inf so we can run the sections in the inf, more or less manually.
  1016. //
  1017. InfFileHandle = SetupOpenInfFile(DriverInfoDetailData->InfFileName,
  1018. NULL,
  1019. INF_STYLE_WIN4,
  1020. NULL);
  1021. if (InfFileHandle == INVALID_HANDLE_VALUE)
  1022. {
  1023. DeskLogError(LogSevInformation,
  1024. IDS_SETUPLOG_MSG_127,
  1025. TEXT("DeskInstallServiceExtensions: SetupOpenInfFile"));
  1026. return ERROR_INVALID_PARAMETER;
  1027. }
  1028. //
  1029. // Get any interesting configuration data for the inf file.
  1030. //
  1031. maxmem = 8;
  1032. numDev = 1;
  1033. wsprintf(szSoftwareSection,
  1034. TEXT("%ws.GeneralConfigData"),
  1035. DriverInfoDetailData->SectionName);
  1036. if (SetupFindFirstLine(InfFileHandle,
  1037. szSoftwareSection,
  1038. TEXT("MaximumNumberOfDevices"),
  1039. &tmpContext))
  1040. {
  1041. SetupGetIntField(&tmpContext,
  1042. 1,
  1043. &numDev);
  1044. }
  1045. if (SetupFindFirstLine(InfFileHandle,
  1046. szSoftwareSection,
  1047. TEXT("MaximumDeviceMemoryConfiguration"),
  1048. &tmpContext))
  1049. {
  1050. SetupGetIntField(&tmpContext,
  1051. 1,
  1052. &maxmem);
  1053. }
  1054. //
  1055. // Create the <Service> key.
  1056. //
  1057. wsprintf(keyName,
  1058. TEXT("System\\CurrentControlSet\\Services\\%ws"),
  1059. pServiceName);
  1060. RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  1061. keyName,
  1062. 0,
  1063. NULL,
  1064. REG_OPTION_NON_VOLATILE,
  1065. KEY_READ | KEY_WRITE,
  1066. NULL,
  1067. &hkey,
  1068. &disposition);
  1069. #ifndef _WIN64
  1070. //
  1071. // Increase the number of system PTEs if we have cards that will need
  1072. // more than 10 MB of PTE mapping space. This only needs to be done for
  1073. // 32-bit NT as virtual address space is limited. On 64-bit NT there is
  1074. // always enough PTE mapping address space so don't do anything as you're
  1075. // likely to get it wrong.
  1076. //
  1077. if ((maxmem = maxmem * numDev) > 10)
  1078. {
  1079. //
  1080. // On x86, 1K PTEs support 4 MB.
  1081. // Then add 50% for other devices this type of machine may have.
  1082. // NOTE - in the future, we may want to be smarter and try
  1083. // to merge with whatever someone else put in there.
  1084. //
  1085. maxmem = maxmem * 0x400 * 3/2 + 0x3000;
  1086. if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  1087. TEXT("System\\CurrentControlSet\\Control\\Session Manager\\Memory Management"),
  1088. 0,
  1089. NULL,
  1090. REG_OPTION_NON_VOLATILE,
  1091. KEY_READ | KEY_WRITE,
  1092. NULL,
  1093. &hkey,
  1094. &disposition) == ERROR_SUCCESS)
  1095. {
  1096. //
  1097. // Check if we already set maxmem in the registry.
  1098. //
  1099. DWORD data;
  1100. DWORD cb = sizeof(data);
  1101. if ((RegQueryValueEx(hkey,
  1102. TEXT("SystemPages"),
  1103. NULL,
  1104. NULL,
  1105. (LPBYTE)(&data),
  1106. &cb) != ERROR_SUCCESS) ||
  1107. (data < (DWORD) maxmem))
  1108. {
  1109. //
  1110. // Set the new value
  1111. //
  1112. RegSetValueEx(hkey,
  1113. TEXT("SystemPages"),
  1114. 0,
  1115. REG_DWORD,
  1116. (LPBYTE) &maxmem,
  1117. sizeof(DWORD));
  1118. //
  1119. // Tell the system we must reboot before running this driver
  1120. // in case the system has less than 128M.
  1121. //
  1122. MEMORYSTATUSEX MemStatus;
  1123. SYSTEM_INFO SystemInfo;
  1124. GetSystemInfo(&SystemInfo);
  1125. MemStatus.dwLength = sizeof(MemStatus);
  1126. if ((SystemInfo.dwPageSize == 0) ||
  1127. (!GlobalMemoryStatusEx(&MemStatus)) ||
  1128. ((MemStatus.ullTotalPhys / SystemInfo.dwPageSize) <= 0x7F00))
  1129. {
  1130. ZeroMemory(&DeviceInstallParams, sizeof(DeviceInstallParams));
  1131. DeviceInstallParams.cbSize = sizeof(DeviceInstallParams);
  1132. if (SetupDiGetDeviceInstallParams(hDevInfo,
  1133. pDeviceInfoData,
  1134. &DeviceInstallParams)) {
  1135. DeviceInstallParams.Flags |= DI_NEEDREBOOT;
  1136. if (!SetupDiSetDeviceInstallParams(hDevInfo,
  1137. pDeviceInfoData,
  1138. &DeviceInstallParams)) {
  1139. DeskLogError(LogSevInformation,
  1140. IDS_SETUPLOG_MSG_126,
  1141. TEXT("DeskInstallServiceExtensions: SetupDiSetDeviceInstallParams"),
  1142. GetLastError());
  1143. }
  1144. } else {
  1145. DeskLogError(LogSevInformation,
  1146. IDS_SETUPLOG_MSG_126,
  1147. TEXT("DeskInstallServiceExtensions: SetupDiGetDeviceInstallParams"),
  1148. GetLastError());
  1149. }
  1150. }
  1151. }
  1152. RegCloseKey(hkey);
  1153. }
  1154. }
  1155. #endif
  1156. //
  1157. // We may have to do this for multiple adapters at this point.
  1158. // So loop throught the number of devices, which has 1 as the default value.
  1159. // For dual view, videoprt.sys will create [GUID]\000X entries as needed
  1160. // and will copy all the entries from the "Settings" key to [GUID]\000X.
  1161. //
  1162. DWORD dwSoftwareSettings = 1;
  1163. DWORD dwDeviceX = 0;
  1164. do {
  1165. if (dwSoftwareSettings == 1)
  1166. {
  1167. //
  1168. // Install everything under the old video device key:
  1169. // HKLM\System\CCS\Services\[SrvName]\DeviceX
  1170. //
  1171. numDev--;
  1172. if (numDev == 0)
  1173. dwSoftwareSettings++;
  1174. //
  1175. // For all drivers, install the information under DeviceX
  1176. // We do this for legacy purposes since many drivers rely on
  1177. // information written to this key.
  1178. //
  1179. wsprintf(keyName,
  1180. TEXT("System\\CurrentControlSet\\Services\\%ws\\Device%d"),
  1181. pServiceName, numDev);
  1182. if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  1183. keyName,
  1184. 0,
  1185. NULL,
  1186. REG_OPTION_NON_VOLATILE,
  1187. KEY_READ | KEY_WRITE,
  1188. NULL,
  1189. &hkey,
  1190. &disposition) != ERROR_SUCCESS) {
  1191. hkey = (HKEY) INVALID_HANDLE_VALUE;
  1192. }
  1193. }
  1194. else if (dwSoftwareSettings == 2)
  1195. {
  1196. //
  1197. // Install everything under the new video device key:
  1198. // HKLM\System\CCS\Control\Video\[GUID]\000X
  1199. //
  1200. if (DeskGetVideoDeviceKey(hDevInfo,
  1201. pDeviceInfoData,
  1202. pServiceName,
  1203. dwDeviceX,
  1204. &hkey))
  1205. {
  1206. dwDeviceX++;
  1207. }
  1208. else
  1209. {
  1210. hkey = (HKEY) INVALID_HANDLE_VALUE;
  1211. dwSoftwareSettings++;
  1212. }
  1213. }
  1214. else if (dwSoftwareSettings == 3)
  1215. {
  1216. dwSoftwareSettings++;
  1217. //
  1218. // Install everything under the driver (aka software) key:
  1219. // HKLM\System\CCS\Control\Class\[Display class]\000X\Settings
  1220. //
  1221. hkey = (HKEY) INVALID_HANDLE_VALUE;
  1222. HKEY hKeyDriver = SetupDiOpenDevRegKey(hDevInfo,
  1223. pDeviceInfoData,
  1224. DICS_FLAG_GLOBAL,
  1225. 0,
  1226. DIREG_DRV,
  1227. KEY_ALL_ACCESS);
  1228. if (hKeyDriver != INVALID_HANDLE_VALUE) {
  1229. //
  1230. // Delete the old settings and applet extensions before
  1231. // installing the new driver
  1232. //
  1233. SHDeleteKey(hKeyDriver, TEXT("Settings"));
  1234. SHDeleteKey(hKeyDriver, TEXT("Display"));
  1235. //
  1236. // Create/open the settings key
  1237. //
  1238. if (RegCreateKeyEx(hKeyDriver,
  1239. TEXT("Settings"),
  1240. 0,
  1241. NULL,
  1242. REG_OPTION_NON_VOLATILE,
  1243. KEY_ALL_ACCESS,
  1244. NULL,
  1245. &hkey,
  1246. NULL) != ERROR_SUCCESS) {
  1247. hkey = (HKEY)INVALID_HANDLE_VALUE;
  1248. }
  1249. RegCloseKey(hKeyDriver);
  1250. }
  1251. }
  1252. if (hkey != INVALID_HANDLE_VALUE)
  1253. {
  1254. //
  1255. // Delete the CapabilityOverride key.
  1256. //
  1257. RegDeleteValue(hkey,
  1258. TEXT("CapabilityOverride"));
  1259. wsprintf(szSoftwareSection,
  1260. TEXT("%ws.SoftwareSettings"),
  1261. DriverInfoDetailData->SectionName);
  1262. if (!SetupInstallFromInfSection(hwnd,
  1263. InfFileHandle,
  1264. szSoftwareSection,
  1265. SPINST_REGISTRY,
  1266. hkey,
  1267. NULL,
  1268. 0,
  1269. NULL,
  1270. NULL,
  1271. NULL,
  1272. NULL))
  1273. {
  1274. DeskLogError(LogSevInformation,
  1275. IDS_SETUPLOG_MSG_126,
  1276. TEXT("DeskInstallServiceExtensions: SetupInstallFromInfSection"),
  1277. GetLastError());
  1278. RegCloseKey(hkey);
  1279. return ERROR_INVALID_PARAMETER;
  1280. }
  1281. //
  1282. // Write the description of the device
  1283. //
  1284. RegSetValueEx(hkey,
  1285. TEXT("Device Description"),
  1286. 0,
  1287. REG_SZ,
  1288. (LPBYTE) DriverInfoDetailData->DrvDescription,
  1289. ByteCountOf(lstrlen(DriverInfoDetailData->DrvDescription) + 1));
  1290. RegCloseKey(hkey);
  1291. }
  1292. } while (dwSoftwareSettings <= 3);
  1293. //
  1294. // Optionally run the OpenGl section in the inf.
  1295. // Ignore any errors at this point since this is an optional entry.
  1296. //
  1297. if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  1298. TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\OpenGLDrivers"),
  1299. 0,
  1300. NULL,
  1301. REG_OPTION_NON_VOLATILE,
  1302. KEY_READ | KEY_WRITE,
  1303. NULL,
  1304. &hkey,
  1305. &disposition) == ERROR_SUCCESS)
  1306. {
  1307. wsprintf(szSoftwareSection,
  1308. TEXT("%ws.OpenGLSoftwareSettings"),
  1309. DriverInfoDetailData->SectionName);
  1310. SetupInstallFromInfSection(hwnd,
  1311. InfFileHandle,
  1312. szSoftwareSection,
  1313. SPINST_REGISTRY,
  1314. hkey,
  1315. NULL,
  1316. 0,
  1317. NULL,
  1318. NULL,
  1319. NULL,
  1320. NULL);
  1321. RegCloseKey(hkey);
  1322. }
  1323. SetupCloseInfFile(InfFileHandle);
  1324. return retVal;
  1325. }
  1326. DWORD
  1327. DeskInstallService(
  1328. IN HDEVINFO hDevInfo,
  1329. IN PSP_DEVINFO_DATA pDeviceInfoData OPTIONAL,
  1330. IN LPTSTR pServiceName
  1331. )
  1332. {
  1333. SP_DEVINSTALL_PARAMS DeviceInstallParams;
  1334. SP_DRVINFO_DATA DriverInfoData;
  1335. SP_DRVINFO_DETAIL_DATA DriverInfoDetailData;
  1336. DWORD cbOutputSize;
  1337. HINF hInf = INVALID_HANDLE_VALUE;
  1338. TCHAR ActualInfSection[LINE_LEN];
  1339. INFCONTEXT infContext;
  1340. DWORD status = NO_ERROR;
  1341. PAPPEXT pAppExtDisplayBefore = NULL, pAppExtDisplayAfter = NULL;
  1342. PAPPEXT pAppExtDeviceBefore = NULL, pAppExtDeviceAfter = NULL;
  1343. HKEY hkDisplay = 0, hkDevice = 0;
  1344. //
  1345. // Get the params so we can get the window handle.
  1346. //
  1347. DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
  1348. SetupDiGetDeviceInstallParams(hDevInfo,
  1349. pDeviceInfoData,
  1350. &DeviceInstallParams);
  1351. //
  1352. // Retrieve information about the driver node selected for this device.
  1353. //
  1354. DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
  1355. if (!SetupDiGetSelectedDriver(hDevInfo,
  1356. pDeviceInfoData,
  1357. &DriverInfoData)) {
  1358. status = GetLastError();
  1359. DeskLogError(LogSevInformation,
  1360. IDS_SETUPLOG_MSG_126,
  1361. TEXT("DeskInstallService: SetupDiGetSelectedDriver"),
  1362. status);
  1363. goto Fallout;
  1364. }
  1365. DriverInfoDetailData.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
  1366. if (!(SetupDiGetDriverInfoDetail(hDevInfo,
  1367. pDeviceInfoData,
  1368. &DriverInfoData,
  1369. &DriverInfoDetailData,
  1370. DriverInfoDetailData.cbSize,
  1371. &cbOutputSize)) &&
  1372. (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) {
  1373. status = GetLastError();
  1374. DeskLogError(LogSevInformation,
  1375. IDS_SETUPLOG_MSG_126,
  1376. TEXT("DeskInstallService: SetupDiGetDriverInfoDetail"),
  1377. status);
  1378. goto Fallout;
  1379. }
  1380. //
  1381. // Open the INF that installs this driver node, so we can 'pre-run' the
  1382. // AddService/DelService entries in its install service install section.
  1383. //
  1384. hInf = SetupOpenInfFile(DriverInfoDetailData.InfFileName,
  1385. NULL,
  1386. INF_STYLE_WIN4,
  1387. NULL);
  1388. if (hInf == INVALID_HANDLE_VALUE) {
  1389. //
  1390. // For some reason we couldn't open the INF--this should never happen.
  1391. //
  1392. status = ERROR_INVALID_HANDLE;
  1393. DeskLogError(LogSevInformation,
  1394. IDS_SETUPLOG_MSG_127,
  1395. TEXT("DeskInstallService: SetupOpenInfFile"));
  1396. goto Fallout;
  1397. }
  1398. //
  1399. // Now find the actual (potentially OS/platform-specific) install section name.
  1400. //
  1401. if (!SetupDiGetActualSectionToInstall(hInf,
  1402. DriverInfoDetailData.SectionName,
  1403. ActualInfSection,
  1404. sizeof(ActualInfSection) / sizeof(TCHAR),
  1405. NULL,
  1406. NULL)) {
  1407. status = GetLastError();
  1408. DeskLogError(LogSevInformation,
  1409. IDS_SETUPLOG_MSG_126,
  1410. TEXT("DeskInstallService: SetupDiGetActualSectionToInstall"),
  1411. status);
  1412. goto Fallout;
  1413. }
  1414. //
  1415. // Append a ".Services" to get the service install section name.
  1416. //
  1417. lstrcat(ActualInfSection, TEXT(".Services"));
  1418. //
  1419. // Now run the service modification entries in this section...
  1420. //
  1421. if (!SetupInstallServicesFromInfSection(hInf,
  1422. ActualInfSection,
  1423. 0))
  1424. {
  1425. status = GetLastError();
  1426. DeskLogError(LogSevInformation,
  1427. IDS_SETUPLOG_MSG_126,
  1428. TEXT("DeskInstallService: SetupInstallServicesFromInfSection"),
  1429. status);
  1430. goto Fallout;
  1431. }
  1432. //
  1433. // Get the service Name if needed (detection)
  1434. //
  1435. if (SetupFindFirstLine(hInf,
  1436. ActualInfSection,
  1437. TEXT("AddService"),
  1438. &infContext))
  1439. {
  1440. SetupGetStringField(&infContext,
  1441. 1,
  1442. pServiceName,
  1443. LINE_LEN,
  1444. NULL);
  1445. }
  1446. //
  1447. // Get a snapshot of the applet extensions installed under generic
  1448. // Device and Display keys
  1449. //
  1450. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  1451. REGSTR_PATH_CONTROLSFOLDER_DISPLAY_SHEX_PROPSHEET,
  1452. 0,
  1453. KEY_ALL_ACCESS,
  1454. &hkDisplay) == ERROR_SUCCESS) {
  1455. DeskAESnapshot(hkDisplay, &pAppExtDisplayBefore);
  1456. } else {
  1457. hkDisplay = 0;
  1458. }
  1459. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  1460. REGSTR_PATH_CONTROLSFOLDER_DEVICE_SHEX_PROPSHEET,
  1461. 0,
  1462. KEY_ALL_ACCESS,
  1463. &hkDevice) == ERROR_SUCCESS) {
  1464. DeskAESnapshot(hkDevice, &pAppExtDeviceBefore);
  1465. } else {
  1466. hkDevice = 0;
  1467. }
  1468. //
  1469. // Now that the basic install has been performed (without starting the
  1470. // device), write the extra data to the registry.
  1471. //
  1472. status = DeskInstallServiceExtensions(DeviceInstallParams.hwndParent,
  1473. hDevInfo,
  1474. pDeviceInfoData,
  1475. &DriverInfoData,
  1476. &DriverInfoDetailData,
  1477. pServiceName);
  1478. if (status != NO_ERROR)
  1479. {
  1480. DeskLogError(LogSevInformation,
  1481. IDS_SETUPLOG_MSG_126,
  1482. TEXT("DeskInstallService: DeskInstallServiceExtensions"),
  1483. status);
  1484. goto Fallout;
  1485. }
  1486. //
  1487. // Do the full device install
  1488. // If some of the flags (like paged pool) needed to be changed,
  1489. // let's ask for a reboot right now.
  1490. // Otherwise, we can actually try to start the device at this point.
  1491. //
  1492. if (!SetupDiInstallDevice(hDevInfo, pDeviceInfoData))
  1493. {
  1494. //
  1495. // Remove the device !??
  1496. //
  1497. status = GetLastError();
  1498. DeskLogError(LogSevInformation,
  1499. IDS_SETUPLOG_MSG_126,
  1500. TEXT("DeskInstallService: SetupDiInstallDevice"),
  1501. status);
  1502. goto Fallout;
  1503. }
  1504. //
  1505. // Get a snapshot of the applet extensions after the device was installed
  1506. // Move the new added extensions under the driver key
  1507. //
  1508. if (hkDisplay != 0) {
  1509. DeskAESnapshot(hkDisplay, &pAppExtDisplayAfter);
  1510. DeskAEMove(hDevInfo,
  1511. pDeviceInfoData,
  1512. hkDisplay,
  1513. pAppExtDisplayBefore,
  1514. pAppExtDisplayAfter);
  1515. DeskAECleanup(pAppExtDisplayBefore);
  1516. DeskAECleanup(pAppExtDisplayAfter);
  1517. }
  1518. if (hkDevice != 0) {
  1519. DeskAESnapshot(hkDevice, &pAppExtDeviceAfter);
  1520. DeskAEMove(hDevInfo,
  1521. pDeviceInfoData,
  1522. hkDevice,
  1523. pAppExtDeviceBefore,
  1524. pAppExtDeviceAfter);
  1525. DeskAECleanup(pAppExtDeviceBefore);
  1526. DeskAECleanup(pAppExtDeviceAfter);
  1527. }
  1528. //
  1529. // For a PnP Device which will never do detection, we want to mark
  1530. // the device as DemandStart.
  1531. //
  1532. DeskSetServiceStartType(pServiceName, SERVICE_DEMAND_START);
  1533. //
  1534. // Make sure the device description and mfg are the original values
  1535. // and not the marked up ones we might have made during select bext
  1536. // compat drv
  1537. //
  1538. DeskMarkUpNewDevNode(hDevInfo, pDeviceInfoData);
  1539. status = NO_ERROR;
  1540. Fallout:
  1541. if (hInf != INVALID_HANDLE_VALUE) {
  1542. SetupCloseInfFile(hInf);
  1543. }
  1544. if (hkDisplay != 0) {
  1545. RegCloseKey(hkDisplay);
  1546. }
  1547. if (hkDevice != 0) {
  1548. RegCloseKey(hkDevice);
  1549. }
  1550. return status;
  1551. }
  1552. VOID
  1553. DeskMarkUpNewDevNode(
  1554. IN HDEVINFO hDevInfo,
  1555. IN PSP_DEVINFO_DATA pDeviceInfoData
  1556. )
  1557. {
  1558. HKEY hKey;
  1559. PTCHAR szProperty;
  1560. DWORD dwSize;
  1561. //
  1562. // Make sure the device desc is "good".
  1563. //
  1564. if (DeskIsLegacyDevNodeByDevInfo(pDeviceInfoData)) {
  1565. //
  1566. // Don't do this to legacy devnode.
  1567. //
  1568. return;
  1569. }
  1570. //
  1571. // Open the device registry key.
  1572. // The real manufacturer and description were stored here
  1573. // by the handler of DIF_SELECTBESTCOMPATDRV
  1574. //
  1575. hKey = SetupDiCreateDevRegKey(hDevInfo,
  1576. pDeviceInfoData,
  1577. DICS_FLAG_GLOBAL,
  1578. 0,
  1579. DIREG_DEV,
  1580. NULL,
  1581. NULL);
  1582. if (hKey == INVALID_HANDLE_VALUE) {
  1583. DeskLogError(LogSevInformation,
  1584. IDS_SETUPLOG_MSG_126,
  1585. TEXT("DeskMarkUpNewDevNode: SetupDiCreateDevRegKey"),
  1586. GetLastError());
  1587. return;
  1588. }
  1589. //
  1590. // Set Description
  1591. //
  1592. dwSize = 0;
  1593. if (RegQueryValueEx(hKey,
  1594. SZ_UPGRADE_DESCRIPTION,
  1595. 0,
  1596. NULL,
  1597. NULL,
  1598. &dwSize) != ERROR_SUCCESS) {
  1599. goto Fallout;
  1600. }
  1601. ASSERT(dwSize != 0);
  1602. dwSize *= sizeof(TCHAR);
  1603. szProperty = (PTCHAR) LocalAlloc(LPTR, dwSize);
  1604. if ((szProperty != NULL) &&
  1605. (RegQueryValueEx(hKey,
  1606. SZ_UPGRADE_DESCRIPTION,
  1607. 0,
  1608. NULL,
  1609. (PBYTE) szProperty,
  1610. &dwSize) == ERROR_SUCCESS))
  1611. {
  1612. SetupDiSetDeviceRegistryProperty(hDevInfo,
  1613. pDeviceInfoData,
  1614. SPDRP_DEVICEDESC,
  1615. (PBYTE) szProperty,
  1616. ByteCountOf(lstrlen(szProperty)+1));
  1617. RegDeleteValue(hKey, SZ_UPGRADE_DESCRIPTION);
  1618. DeskLogError(LogSevInformation,
  1619. IDS_SETUPLOG_MSG_004,
  1620. szProperty);
  1621. }
  1622. LocalFree(szProperty);
  1623. szProperty = NULL;
  1624. //
  1625. // Set Manufacturer
  1626. //
  1627. dwSize = 0;
  1628. if (RegQueryValueEx(hKey,
  1629. SZ_UPGRADE_MFG,
  1630. 0,
  1631. NULL,
  1632. NULL,
  1633. &dwSize) != ERROR_SUCCESS) {
  1634. goto Fallout;
  1635. }
  1636. ASSERT(dwSize != 0);
  1637. dwSize *= sizeof(TCHAR);
  1638. szProperty = (PTCHAR) LocalAlloc(LPTR, dwSize);
  1639. if ((szProperty != NULL) &&
  1640. (RegQueryValueEx(hKey,
  1641. SZ_UPGRADE_MFG,
  1642. 0,
  1643. NULL,
  1644. (PBYTE) szProperty,
  1645. &dwSize) == ERROR_SUCCESS))
  1646. {
  1647. SetupDiSetDeviceRegistryProperty(hDevInfo,
  1648. pDeviceInfoData,
  1649. SPDRP_MFG,
  1650. (PBYTE) szProperty,
  1651. ByteCountOf(lstrlen(szProperty)+1));
  1652. RegDeleteValue(hKey, SZ_UPGRADE_MFG);
  1653. DeskLogError(LogSevInformation,
  1654. IDS_SETUPLOG_MSG_006,
  1655. szProperty);
  1656. }
  1657. LocalFree(szProperty);
  1658. szProperty = NULL;
  1659. Fallout:
  1660. RegCloseKey(hKey);
  1661. }
  1662. //
  1663. // Helper functions
  1664. //
  1665. BOOL
  1666. DeskIsLegacyDevNodeByPath(
  1667. const PTCHAR szRegPath
  1668. )
  1669. {
  1670. return (_tcsncicmp(SZ_ROOT_LEGACY, szRegPath, _tcslen(SZ_ROOT_LEGACY)) == 0);
  1671. }
  1672. BOOL
  1673. DeskIsLegacyDevNodeByDevInfo(
  1674. PSP_DEVINFO_DATA pDevInfoData
  1675. )
  1676. {
  1677. TCHAR szBuf[LINE_LEN];
  1678. return (DeskGetDevNodePath(pDevInfoData, szBuf, LINE_LEN - 1) &&
  1679. DeskIsLegacyDevNodeByPath(szBuf));
  1680. }
  1681. BOOL
  1682. DeskIsRootDevNodeByDevInfo(
  1683. PSP_DEVINFO_DATA pDevInfoData
  1684. )
  1685. {
  1686. TCHAR szBuf[LINE_LEN];
  1687. return (DeskGetDevNodePath(pDevInfoData, szBuf, LINE_LEN - 1) &&
  1688. (_tcsncicmp(SZ_ROOT, szBuf, _tcslen(SZ_ROOT)) == 0));
  1689. }
  1690. BOOL
  1691. DeskGetDevNodePath(
  1692. PSP_DEVINFO_DATA pDid,
  1693. PTCHAR szPath,
  1694. LONG len
  1695. )
  1696. {
  1697. return (CR_SUCCESS == CM_Get_Device_ID(pDid->DevInst, szPath, len, 0));
  1698. }
  1699. VOID
  1700. DeskNukeDevNode(
  1701. LPTSTR szService,
  1702. HDEVINFO hDevInfo,
  1703. PSP_DEVINFO_DATA pDeviceInfoData
  1704. )
  1705. {
  1706. SP_REMOVEDEVICE_PARAMS rdParams;
  1707. TCHAR szPath[LINE_LEN];
  1708. // Disable the service
  1709. if (szService)
  1710. {
  1711. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_008, szService);
  1712. DeskSetServiceStartType(szService, SERVICE_DISABLED);
  1713. }
  1714. else
  1715. {
  1716. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_009);
  1717. }
  1718. // Remove the devnode
  1719. if (DeskGetDevNodePath(pDeviceInfoData, szPath, LINE_LEN))
  1720. {
  1721. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_010, szPath);
  1722. }
  1723. ZeroMemory(&rdParams, sizeof(SP_REMOVEDEVICE_PARAMS));
  1724. rdParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
  1725. rdParams.ClassInstallHeader.InstallFunction = DIF_REMOVE;
  1726. rdParams.Scope = DI_REMOVEDEVICE_GLOBAL;
  1727. if (SetupDiSetClassInstallParams(hDevInfo,
  1728. pDeviceInfoData,
  1729. &rdParams.ClassInstallHeader,
  1730. sizeof(SP_REMOVEDEVICE_PARAMS)))
  1731. {
  1732. if (!SetupDiCallClassInstaller(DIF_REMOVE, hDevInfo, pDeviceInfoData))
  1733. {
  1734. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_011, GetLastError());
  1735. }
  1736. }
  1737. else
  1738. {
  1739. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_012, GetLastError());
  1740. }
  1741. }
  1742. PTCHAR
  1743. DeskFindMatchingId(
  1744. PTCHAR DeviceId,
  1745. PTCHAR IdList // a multi sz
  1746. )
  1747. {
  1748. PTCHAR currentId;
  1749. if (!IdList) {
  1750. return NULL;
  1751. }
  1752. for (currentId = IdList; *currentId; ) {
  1753. if (lstrcmpi(currentId, DeviceId) == 0) {
  1754. //
  1755. // We have a match
  1756. //
  1757. return currentId;
  1758. } else {
  1759. //
  1760. // Get to the next string in the multi sz
  1761. //
  1762. while (*currentId) {
  1763. currentId++;
  1764. }
  1765. //
  1766. // Jump past the null
  1767. //
  1768. currentId++;
  1769. }
  1770. }
  1771. return NULL;
  1772. }
  1773. UINT
  1774. DeskDisableLegacyDeviceNodes(
  1775. VOID
  1776. )
  1777. {
  1778. DWORD index = 0, dwSize;
  1779. UINT count = 0;
  1780. HDEVINFO hDevInfo;
  1781. SP_DEVINFO_DATA did;
  1782. TCHAR szRegProperty[256];
  1783. PTCHAR szService;
  1784. //
  1785. // Let's find all the video drivers that are installed in the system
  1786. //
  1787. hDevInfo = SetupDiGetClassDevs((LPGUID) &GUID_DEVCLASS_DISPLAY,
  1788. NULL,
  1789. NULL,
  1790. 0);
  1791. if (hDevInfo == INVALID_HANDLE_VALUE)
  1792. {
  1793. DeskLogError(LogSevInformation,
  1794. IDS_SETUPLOG_MSG_126,
  1795. TEXT("DeskDisableLegacyDeviceNodes: SetupDiGetClassDevs"),
  1796. GetLastError());
  1797. goto Fallout;
  1798. }
  1799. ZeroMemory(&did, sizeof(SP_DEVINFO_DATA));
  1800. did.cbSize = sizeof(SP_DEVINFO_DATA);
  1801. while (SetupDiEnumDeviceInfo(hDevInfo, index, &did))
  1802. {
  1803. // If we have a root legacy device, then don't install any new
  1804. // devnode (until we get better at this).
  1805. if (CR_SUCCESS == CM_Get_Device_ID(did.DevInst,
  1806. szRegProperty,
  1807. ARRAYSIZE(szRegProperty),
  1808. 0))
  1809. {
  1810. if (DeskIsLegacyDevNodeByPath(szRegProperty))
  1811. {
  1812. // We have a legacy DevNode, lets disable its service and
  1813. // remove its devnode
  1814. szService = NULL;
  1815. dwSize = sizeof(szRegProperty);
  1816. if (CM_Get_DevNode_Registry_Property(did.DevInst,
  1817. CM_DRP_SERVICE,
  1818. NULL,
  1819. szRegProperty,
  1820. &dwSize,
  1821. 0) == CR_SUCCESS)
  1822. {
  1823. // Make sure we don't disable vga or VgaSave
  1824. if (!DeskIsServiceDisableable(szRegProperty))
  1825. {
  1826. goto NextDevice;
  1827. }
  1828. szService = szRegProperty;
  1829. }
  1830. DeskNukeDevNode(szService, hDevInfo, &did);
  1831. count++;
  1832. }
  1833. }
  1834. NextDevice:
  1835. ZeroMemory(&did, sizeof(SP_DEVINFO_DATA));
  1836. did.cbSize = sizeof(SP_DEVINFO_DATA);
  1837. index++;
  1838. }
  1839. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_013, count, index);
  1840. SetupDiDestroyDeviceInfoList(hDevInfo);
  1841. Fallout:
  1842. if ((DeskGetSetupFlags() & INSETUP_UPGRADE) != 0) {
  1843. DeskDisableServices();
  1844. }
  1845. return count;
  1846. }
  1847. VOID
  1848. DeskDisableServices(
  1849. )
  1850. {
  1851. HKEY hKey = 0;
  1852. PTCHAR mszBuffer = NULL, szService = NULL;
  1853. DWORD cbSize = 0;
  1854. //
  1855. // Retrieve the services we want to disable from the registry
  1856. //
  1857. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  1858. SZ_UPDATE_SETTINGS,
  1859. 0,
  1860. KEY_ALL_ACCESS,
  1861. &hKey) != ERROR_SUCCESS) {
  1862. hKey = 0;
  1863. goto Fallout;
  1864. }
  1865. //
  1866. // Get the size
  1867. //
  1868. if (RegQueryValueEx(hKey,
  1869. SZ_SERVICES_TO_DISABLE,
  1870. 0,
  1871. NULL,
  1872. NULL,
  1873. &cbSize) != ERROR_SUCCESS) {
  1874. goto Fallout;
  1875. }
  1876. //
  1877. // Allocate the memory
  1878. //
  1879. mszBuffer = (PTCHAR)LocalAlloc(LPTR, cbSize);
  1880. if (mszBuffer == NULL) {
  1881. goto Fallout;
  1882. }
  1883. //
  1884. // Get the services
  1885. //
  1886. if (RegQueryValueEx(hKey,
  1887. SZ_SERVICES_TO_DISABLE,
  1888. 0,
  1889. NULL,
  1890. (BYTE*)mszBuffer,
  1891. &cbSize) != ERROR_SUCCESS) {
  1892. goto Fallout;
  1893. }
  1894. //
  1895. // Scan through all the services
  1896. //
  1897. szService = mszBuffer;
  1898. while (*szService != TEXT('\0')) {
  1899. //
  1900. // Make sure this service is not vga
  1901. //
  1902. if (DeskIsServiceDisableable(szService)) {
  1903. //
  1904. // Disable the service
  1905. //
  1906. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_008, szService);
  1907. DeskSetServiceStartType(szService, SERVICE_DISABLED);
  1908. }
  1909. //
  1910. // Go to next service
  1911. //
  1912. while (*szService != TEXT('\0')) {
  1913. szService++;
  1914. }
  1915. szService++;
  1916. }
  1917. Fallout:
  1918. if (mszBuffer != NULL) {
  1919. LocalFree(mszBuffer);
  1920. }
  1921. if (hKey != 0) {
  1922. //
  1923. // Delete the SERVICES_TO_DISABLE value
  1924. //
  1925. RegDeleteValue(hKey, SZ_SERVICES_TO_DISABLE);
  1926. //
  1927. // Close the key
  1928. //
  1929. RegCloseKey(hKey);
  1930. }
  1931. }
  1932. DWORD
  1933. DeskPerformDatabaseUpgrade(
  1934. HINF hInf,
  1935. PINFCONTEXT pInfContext,
  1936. BOOL bUpgrade,
  1937. PTCHAR szDriverListSection,
  1938. BOOL* pbDeleteAppletExt
  1939. )
  1940. /*--
  1941. Remarks:
  1942. This function is called once the ID of the device in question matches an ID
  1943. contained in the upgrade database. We then compare the state of the system
  1944. with what is contained in the database. The following algorithm is followed.
  1945. If szDriverListSection is NULL or cannot be found, then bUpgrade is used
  1946. If szDriverListSection is not NUL, then following table is used
  1947. bUpgrade match found in DL return value
  1948. TRUE no upgrade
  1949. TRUE yes no upgrade
  1950. FALSE no no upgrade
  1951. FALSE yes upgrade
  1952. essentially, a match in the DL negates bUpgrade
  1953. ++*/
  1954. {
  1955. HKEY hKey;
  1956. DWORD dwRet = ERROR_SUCCESS, dwSize;
  1957. INFCONTEXT driverListContext;
  1958. TCHAR szService[32], szProperty[128];
  1959. TCHAR szRegPath[128];
  1960. HDEVINFO hDevInfo = INVALID_HANDLE_VALUE;
  1961. PDEVDATA rgDevData = NULL;
  1962. PSP_DEVINFO_DATA pDid;
  1963. UINT iData, numData, maxData = 5, iEnum;
  1964. BOOL foundMatch = FALSE;
  1965. INT DeleteAppletExt = 0;
  1966. UNREFERENCED_PARAMETER(pInfContext);
  1967. // If no Driver list is given, life is quite simple:
  1968. // just disable all legacy drivers and succeed
  1969. if (!szDriverListSection)
  1970. {
  1971. ASSERT (pbDeleteAppletExt == NULL);
  1972. DeskLogError(LogSevInformation, (bUpgrade ? IDS_SETUPLOG_MSG_014 : IDS_SETUPLOG_MSG_015));
  1973. return bUpgrade ? ERROR_SUCCESS : ERROR_DI_DONT_INSTALL;
  1974. }
  1975. // By default, do not disable applet extensions
  1976. ASSERT (pbDeleteAppletExt != NULL);
  1977. *pbDeleteAppletExt = FALSE;
  1978. // Find the specified section in the inf
  1979. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_016, szDriverListSection);
  1980. if (!SetupFindFirstLine(hInf,
  1981. szDriverListSection,
  1982. NULL,
  1983. &driverListContext))
  1984. {
  1985. // The section listed in the database doesn't exist!
  1986. // Behave as though it wasn't there
  1987. DeskLogError(LogSevInformation, (bUpgrade ? IDS_SETUPLOG_MSG_017
  1988. : IDS_SETUPLOG_MSG_018));
  1989. return bUpgrade ? ERROR_SUCCESS : ERROR_DI_DONT_INSTALL;
  1990. }
  1991. // Get all the video devices in the system
  1992. hDevInfo = SetupDiGetClassDevs((LPGUID) &GUID_DEVCLASS_DISPLAY,
  1993. NULL,
  1994. NULL,
  1995. 0);
  1996. if (hDevInfo == INVALID_HANDLE_VALUE)
  1997. {
  1998. // If no display devices are found, treat this as the case where
  1999. // no match was made
  2000. DeskLogError(LogSevInformation,
  2001. (bUpgrade ? IDS_SETUPLOG_MSG_019 : IDS_SETUPLOG_MSG_020));
  2002. return bUpgrade ? ERROR_SUCCESS : ERROR_DI_DONT_INSTALL;
  2003. }
  2004. rgDevData = (PDEVDATA) LocalAlloc(LPTR, maxData * sizeof(DEVDATA));
  2005. if (!rgDevData) {
  2006. SetupDiDestroyDeviceInfoList(hDevInfo);
  2007. return bUpgrade ? ERROR_SUCCESS : ERROR_DI_DONT_INSTALL;
  2008. }
  2009. iEnum = numData = 0;
  2010. do
  2011. {
  2012. pDid = &rgDevData[numData].did;
  2013. pDid->cbSize = sizeof(SP_DEVINFO_DATA);
  2014. if (!SetupDiEnumDeviceInfo(hDevInfo, ++iEnum, pDid))
  2015. {
  2016. break;
  2017. }
  2018. // If it isn't a legacy devnode, then ignore it
  2019. if (CM_Get_Device_ID(pDid->DevInst, szProperty, ARRAYSIZE(szProperty), 0)
  2020. == CR_SUCCESS && !DeskIsLegacyDevNodeByPath(szProperty))
  2021. {
  2022. continue;
  2023. }
  2024. // Initially grab the service name
  2025. dwSize = SZ_BINARY_LEN;
  2026. if (CM_Get_DevNode_Registry_Property(pDid->DevInst,
  2027. CM_DRP_SERVICE,
  2028. NULL,
  2029. rgDevData[numData].szService,
  2030. &dwSize,
  2031. 0) != CR_SUCCESS)
  2032. {
  2033. // couldn't get the service, ignore this device
  2034. continue;
  2035. }
  2036. szRegPath[0] = TEXT('\0');
  2037. lstrcat(szRegPath, TEXT("System\\CurrentControlSet\\Services\\"));
  2038. lstrcat(szRegPath, rgDevData[numData].szService);
  2039. // Try to grab the real binary name of the service
  2040. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  2041. szRegPath,
  2042. 0,
  2043. KEY_READ,
  2044. &hKey) == ERROR_SUCCESS)
  2045. {
  2046. // Parse the device map and open the registry.
  2047. dwSize = ARRAYSIZE(szProperty);
  2048. if (RegQueryValueEx(hKey,
  2049. TEXT("ImagePath"),
  2050. NULL,
  2051. NULL,
  2052. (LPBYTE) szProperty,
  2053. &dwSize) == ERROR_SUCCESS)
  2054. {
  2055. // The is a binary, extract the name, which will be of the form
  2056. // ...\driver.sys
  2057. LPTSTR pszDriver, pszDriverEnd;
  2058. pszDriver = szProperty;
  2059. pszDriverEnd = szProperty + lstrlen(szProperty);
  2060. while(pszDriverEnd != pszDriver &&
  2061. *pszDriverEnd != TEXT('.')) {
  2062. pszDriverEnd--;
  2063. }
  2064. *pszDriverEnd = UNICODE_NULL;
  2065. while(pszDriverEnd != pszDriver &&
  2066. *pszDriverEnd != TEXT('\\')) {
  2067. pszDriverEnd--;
  2068. }
  2069. pszDriverEnd++;
  2070. //
  2071. // If pszDriver and pszDriverEnd are different, we now
  2072. // have the driver name.
  2073. //
  2074. if (pszDriverEnd > pszDriver &&
  2075. lstrlen(pszDriverEnd) < SZ_BINARY_LEN) {
  2076. lstrcpy(rgDevData[numData].szBinary, pszDriverEnd);
  2077. }
  2078. }
  2079. RegCloseKey(hKey);
  2080. } else {
  2081. //
  2082. // no service at all, consider it bogus
  2083. //
  2084. continue;
  2085. }
  2086. if (++numData == maxData) {
  2087. DEVDATA *tmp;
  2088. UINT oldMax = maxData;
  2089. maxData <<= 1;
  2090. //
  2091. // Alloc twice as many, copy them over, zero out the new memory
  2092. // and free the old list
  2093. //
  2094. tmp = (PDEVDATA) LocalAlloc(LPTR, maxData * sizeof(DEVDATA));
  2095. memcpy(tmp, rgDevData, oldMax * sizeof(DEVDATA));
  2096. ZeroMemory(tmp + oldMax, sizeof(DEVDATA) * oldMax);
  2097. LocalFree(rgDevData);
  2098. rgDevData = tmp;
  2099. }
  2100. } while (1);
  2101. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_021, numData);
  2102. //
  2103. // Assume that no matches have been made
  2104. //
  2105. dwRet = (bUpgrade ? ERROR_SUCCESS : ERROR_DI_DONT_INSTALL);
  2106. if (numData != 0) {
  2107. //
  2108. // There are legacy devices to check against...
  2109. //
  2110. do {
  2111. LPTSTR szValue;
  2112. memset(szService, 0, sizeof(szService));
  2113. dwSize = sizeof(szService) / sizeof(TCHAR);
  2114. if ((SetupGetFieldCount(&driverListContext) < 1) ||
  2115. !SetupGetStringField(&driverListContext,
  2116. 1,
  2117. szService,
  2118. dwSize,
  2119. &dwSize)) {
  2120. continue;
  2121. }
  2122. if (szService[0] == TEXT('\0')) {
  2123. continue;
  2124. }
  2125. for (iData = 0; iData < numData; iData++) {
  2126. if (rgDevData[iData].szBinary[0] != TEXT('\0')) {
  2127. szValue = rgDevData[iData].szBinary;
  2128. } else {
  2129. szValue = rgDevData[iData].szService;
  2130. }
  2131. if (lstrcmpi(szService, szValue) == 0)
  2132. {
  2133. DeskLogError(LogSevInformation,
  2134. (bUpgrade ? IDS_SETUPLOG_MSG_022
  2135. : IDS_SETUPLOG_MSG_023));
  2136. dwRet = (bUpgrade ? ERROR_DI_DONT_INSTALL : ERROR_SUCCESS);
  2137. foundMatch = TRUE;
  2138. //
  2139. // In case we fail upgrade, do we want to disable applet
  2140. // extensions?
  2141. //
  2142. if ((dwRet == ERROR_DI_DONT_INSTALL) &&
  2143. (SetupGetFieldCount(&driverListContext) >= 2) &&
  2144. SetupGetIntField(&driverListContext, 2,
  2145. &DeleteAppletExt)) {
  2146. *pbDeleteAppletExt =
  2147. (DeleteAppletExt != 0);
  2148. }
  2149. break;
  2150. }
  2151. }
  2152. } while (SetupFindNextLine(&driverListContext, &driverListContext));
  2153. }
  2154. SetupDiDestroyDeviceInfoList(hDevInfo);
  2155. LocalFree(rgDevData);
  2156. if (!foundMatch)
  2157. {
  2158. DeskLogError(LogSevInformation,
  2159. (bUpgrade ? IDS_SETUPLOG_MSG_024 : IDS_SETUPLOG_MSG_025),
  2160. szDriverListSection);
  2161. }
  2162. return dwRet;
  2163. }
  2164. DWORD
  2165. DeskCheckDatabase(
  2166. IN HDEVINFO hDevInfo,
  2167. IN PSP_DEVINFO_DATA pDeviceInfoData,
  2168. BOOL* pbDeleteAppletExt
  2169. )
  2170. {
  2171. DWORD dwRet = ERROR_SUCCESS, dwSize, dwValue;
  2172. HINF hInf;
  2173. HKEY hKeyUpdate;
  2174. INFCONTEXT infContext;
  2175. BOOL foundMatch = FALSE;
  2176. TCHAR szDatabaseId[200];
  2177. TCHAR szDriverListSection[100];
  2178. PTCHAR szHardwareIds = NULL, szCompatIds = NULL;
  2179. CONFIGRET cr;
  2180. ULONG len;
  2181. PTCHAR szMatchedId = NULL;
  2182. int upgrade = FALSE;
  2183. BOOL IsNTUpgrade = FALSE;
  2184. TCHAR szDatabaseInf[] = TEXT("display.inf");
  2185. TCHAR szDatabaseSection[] = TEXT("VideoUpgradeDatabase");
  2186. ASSERT (pDeviceInfoData != NULL);
  2187. ASSERT (pbDeleteAppletExt != NULL);
  2188. ASSERT ((DeskGetSetupFlags() & INSETUP_UPGRADE) != 0);
  2189. *pbDeleteAppletExt = FALSE;
  2190. //
  2191. // All of the following values were placed here by our winnt32 migration dll
  2192. // Find out what version of windows we are upgrading from
  2193. //
  2194. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  2195. SZ_UPDATE_SETTINGS,
  2196. 0,
  2197. KEY_READ,
  2198. &hKeyUpdate) == ERROR_SUCCESS) {
  2199. dwSize = sizeof(DWORD);
  2200. if ((RegQueryValueEx(hKeyUpdate,
  2201. SZ_UPGRADE_FROM_PLATFORM, NULL, NULL,
  2202. (PBYTE)
  2203. &dwValue,
  2204. &dwSize) == ERROR_SUCCESS) &&
  2205. (dwValue == VER_PLATFORM_WIN32_NT)) {
  2206. IsNTUpgrade = TRUE;
  2207. }
  2208. RegCloseKey(hKeyUpdate);
  2209. }
  2210. if (!IsNTUpgrade) {
  2211. return ERROR_SUCCESS;
  2212. }
  2213. //
  2214. // Get the hardware ID
  2215. //
  2216. len = 0;
  2217. cr = CM_Get_DevNode_Registry_Property(pDeviceInfoData->DevInst,
  2218. CM_DRP_HARDWAREID,
  2219. NULL,
  2220. NULL,
  2221. &len,
  2222. 0);
  2223. if (cr == CR_BUFFER_SMALL) {
  2224. szHardwareIds = (PTCHAR) LocalAlloc(LPTR, len * sizeof(TCHAR));
  2225. if (szHardwareIds) {
  2226. CM_Get_DevNode_Registry_Property(pDeviceInfoData->DevInst,
  2227. CM_DRP_HARDWAREID,
  2228. NULL,
  2229. szHardwareIds,
  2230. &len,
  2231. 0);
  2232. if (DeskFindMatchingId(TEXT("LEGACY_UPGRADE_ID"), szHardwareIds)) {
  2233. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_031);
  2234. LocalFree(szHardwareIds);
  2235. return ERROR_SUCCESS;
  2236. }
  2237. }
  2238. }
  2239. //
  2240. // Get the compatible ID
  2241. //
  2242. len = 0;
  2243. cr = CM_Get_DevNode_Registry_Property(pDeviceInfoData->DevInst,
  2244. CM_DRP_COMPATIBLEIDS,
  2245. NULL,
  2246. NULL,
  2247. &len,
  2248. 0);
  2249. if (cr == CR_BUFFER_SMALL) {
  2250. szCompatIds = (PTCHAR) LocalAlloc(LPTR, len * sizeof(TCHAR));
  2251. if (szCompatIds) {
  2252. CM_Get_DevNode_Registry_Property(pDeviceInfoData->DevInst,
  2253. CM_DRP_COMPATIBLEIDS,
  2254. NULL,
  2255. szCompatIds,
  2256. &len,
  2257. 0);
  2258. }
  2259. }
  2260. if (!szHardwareIds && !szCompatIds)
  2261. {
  2262. // No IDs to look up! Assume success.
  2263. DeskLogError(LogSevWarning, IDS_SETUPLOG_MSG_032);
  2264. return ERROR_SUCCESS;
  2265. }
  2266. hInf = SetupOpenInfFile(szDatabaseInf,
  2267. NULL,
  2268. INF_STYLE_WIN4,
  2269. NULL);
  2270. if (hInf == INVALID_HANDLE_VALUE)
  2271. {
  2272. // Couldn't open the inf. This shouldn't happen.
  2273. // Use default upgrade logic
  2274. DeskLogError(LogSevWarning, IDS_SETUPLOG_MSG_033);
  2275. return ERROR_SUCCESS;
  2276. }
  2277. if (!SetupFindFirstLine(hInf,
  2278. szDatabaseSection,
  2279. NULL,
  2280. &infContext))
  2281. {
  2282. // Couldn't find the section or there are no entries in it.
  2283. // Use default upgrade logic
  2284. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_034, szDatabaseSection);
  2285. }
  2286. else
  2287. {
  2288. do
  2289. {
  2290. dwSize = ARRAYSIZE(szDatabaseId);
  2291. if (!SetupGetStringField(&infContext, 0, szDatabaseId, dwSize, &dwSize))
  2292. {
  2293. continue;
  2294. }
  2295. szMatchedId = DeskFindMatchingId(szDatabaseId, szHardwareIds);
  2296. if (!szMatchedId)
  2297. {
  2298. szMatchedId = DeskFindMatchingId(szDatabaseId, szCompatIds);
  2299. }
  2300. if (szMatchedId)
  2301. {
  2302. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_035, szMatchedId);
  2303. // Do something here and then get out of the loop
  2304. SetupGetIntField(&infContext, 1, &upgrade);
  2305. if (SetupGetFieldCount(&infContext) >= 2)
  2306. {
  2307. dwSize = ARRAYSIZE(szDriverListSection);
  2308. SetupGetStringField(&infContext, 2, szDriverListSection, dwSize, &dwSize);
  2309. dwRet = DeskPerformDatabaseUpgrade(hInf,
  2310. &infContext,
  2311. upgrade,
  2312. szDriverListSection,
  2313. pbDeleteAppletExt);
  2314. }
  2315. else
  2316. {
  2317. dwRet = DeskPerformDatabaseUpgrade(hInf,
  2318. &infContext,
  2319. upgrade,
  2320. NULL,
  2321. NULL);
  2322. }
  2323. break;
  2324. }
  2325. } while (SetupFindNextLine(&infContext, &infContext));
  2326. }
  2327. if (szHardwareIds) {
  2328. LocalFree(szHardwareIds);
  2329. }
  2330. if (szCompatIds) {
  2331. LocalFree(szCompatIds);
  2332. }
  2333. if (hInf != INVALID_HANDLE_VALUE) {
  2334. SetupCloseInfFile(hInf);
  2335. }
  2336. if (dwRet == ERROR_SUCCESS)
  2337. {
  2338. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_039);
  2339. }
  2340. else {
  2341. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_040);
  2342. }
  2343. return dwRet;
  2344. }
  2345. VOID
  2346. DeskGetUpgradeDeviceStrings(
  2347. PTCHAR Description,
  2348. PTCHAR MfgName,
  2349. PTCHAR ProviderName
  2350. )
  2351. {
  2352. TCHAR szDisplay[] = TEXT("display.inf");
  2353. TCHAR szDeviceStrings[] = TEXT("SystemUpgradeDeviceStrings");
  2354. TCHAR szValue[LINE_LEN];
  2355. HINF hInf;
  2356. INFCONTEXT infContext;
  2357. DWORD dwSize;
  2358. hInf = SetupOpenInfFile(szDisplay, NULL, INF_STYLE_WIN4, NULL);
  2359. if (hInf == INVALID_HANDLE_VALUE) {
  2360. goto GetStringsError;
  2361. }
  2362. if (!SetupFindFirstLine(hInf, szDeviceStrings, NULL, &infContext))
  2363. goto GetStringsError;
  2364. do {
  2365. dwSize = ARRAYSIZE(szValue);
  2366. if (!SetupGetStringField(&infContext, 0, szValue, dwSize, &dwSize)) {
  2367. continue;
  2368. }
  2369. dwSize = LINE_LEN;
  2370. if (lstrcmp(szValue, TEXT("Mfg")) ==0) {
  2371. SetupGetStringField(&infContext, 1, MfgName, dwSize, &dwSize);
  2372. }
  2373. else if (lstrcmp(szValue, TEXT("Provider")) == 0) {
  2374. SetupGetStringField(&infContext, 1, ProviderName, dwSize, &dwSize);
  2375. }
  2376. else if (lstrcmp(szValue, TEXT("Description")) == 0) {
  2377. SetupGetStringField(&infContext, 1, Description, dwSize, &dwSize);
  2378. }
  2379. } while (SetupFindNextLine(&infContext, &infContext));
  2380. SetupCloseInfFile(hInf);
  2381. return;
  2382. GetStringsError:
  2383. if (hInf != INVALID_HANDLE_VALUE) {
  2384. SetupCloseInfFile(hInf);
  2385. }
  2386. lstrcpy(Description, TEXT("Video Upgrade Device"));
  2387. lstrcpy(MfgName, TEXT("(Standard display types)"));
  2388. lstrcpy(ProviderName, TEXT("Microsoft"));
  2389. }
  2390. DWORD
  2391. DeskGetSetupFlags(
  2392. VOID
  2393. )
  2394. {
  2395. HKEY hkey;
  2396. DWORD retval = 0;
  2397. TCHAR data[256];
  2398. DWORD cb;
  2399. LPTSTR regstring;
  2400. hkey = NULL;
  2401. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  2402. TEXT("System\\Setup"),
  2403. 0,
  2404. KEY_READ | KEY_WRITE,
  2405. &hkey) == ERROR_SUCCESS) {
  2406. cb = 256;
  2407. if (RegQueryValueEx(hkey,
  2408. TEXT("SystemSetupInProgress"),
  2409. NULL,
  2410. NULL,
  2411. (LPBYTE)(data),
  2412. &cb) == ERROR_SUCCESS) {
  2413. retval |= *((LPDWORD)(data)) ? INSETUP : 0;
  2414. regstring = TEXT("System\\Video_Setup");
  2415. } else {
  2416. regstring = TEXT("System\\Video_NO_Setup");
  2417. }
  2418. cb = 256;
  2419. if (RegQueryValueEx(hkey,
  2420. TEXT("UpgradeInProgress"),
  2421. NULL,
  2422. NULL,
  2423. (LPBYTE)(data),
  2424. &cb) == ERROR_SUCCESS) {
  2425. retval |= *((LPDWORD)(data)) ? INSETUP_UPGRADE : 0;
  2426. regstring = TEXT("System\\Video_Setup_Upgrade");
  2427. } else {
  2428. regstring = TEXT("System\\Video_Setup_Clean");
  2429. }
  2430. if (hkey) {
  2431. RegCloseKey(hkey);
  2432. }
  2433. }
  2434. return retval;
  2435. }
  2436. BOOL
  2437. DeskGetVideoDeviceKey(
  2438. IN HDEVINFO hDevInfo,
  2439. IN PSP_DEVINFO_DATA pDeviceInfoData,
  2440. IN LPTSTR pServiceName,
  2441. IN DWORD DeviceX,
  2442. OUT HKEY* phkDevice
  2443. )
  2444. {
  2445. BOOL retVal = FALSE;
  2446. HKEY hkPnP = (HKEY)INVALID_HANDLE_VALUE;
  2447. HKEY hkCommonSubkey = (HKEY)INVALID_HANDLE_VALUE;
  2448. GUID DeviceKeyGUID;
  2449. LPWSTR pwstrGUID= NULL;
  2450. LPTSTR ptstrGUID= NULL;
  2451. LPTSTR pBuffer = NULL;
  2452. DWORD dwSize, len;
  2453. //
  2454. // Open the PnP key
  2455. //
  2456. hkPnP = SetupDiCreateDevRegKey(hDevInfo,
  2457. pDeviceInfoData,
  2458. DICS_FLAG_GLOBAL,
  2459. 0,
  2460. DIREG_DEV,
  2461. NULL,
  2462. NULL);
  2463. if (hkPnP == INVALID_HANDLE_VALUE) {
  2464. //
  2465. // Videoprt.sys handles the legacy device case.
  2466. //
  2467. goto Fallout;
  2468. }
  2469. //
  2470. // Try to get the GUID from the PnP key
  2471. //
  2472. dwSize = 0;
  2473. if (RegQueryValueEx(hkPnP,
  2474. SZ_GUID,
  2475. 0,
  2476. NULL,
  2477. NULL,
  2478. &dwSize) == ERROR_SUCCESS) {
  2479. //
  2480. // The GUID is there so use it.
  2481. //
  2482. len = lstrlen(SZ_VIDEO_DEVICES);
  2483. pBuffer = (LPTSTR)LocalAlloc(LPTR,
  2484. dwSize + (len + 6) * sizeof(TCHAR));
  2485. if (pBuffer == NULL)
  2486. {
  2487. DeskLogError(LogSevInformation,
  2488. IDS_SETUPLOG_MSG_128,
  2489. TEXT("LocalAlloc"));
  2490. goto Fallout;
  2491. }
  2492. lstrcpy(pBuffer, SZ_VIDEO_DEVICES);
  2493. if (RegQueryValueEx(hkPnP,
  2494. SZ_GUID,
  2495. 0,
  2496. NULL,
  2497. (PBYTE)(pBuffer + len),
  2498. &dwSize) != ERROR_SUCCESS) {
  2499. DeskLogError(LogSevInformation,
  2500. IDS_SETUPLOG_MSG_128,
  2501. TEXT("RegQueryValueEx"));
  2502. goto Fallout;
  2503. }
  2504. _stprintf(pBuffer + lstrlen(pBuffer),
  2505. TEXT("\\%04d"),
  2506. DeviceX);
  2507. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  2508. pBuffer,
  2509. 0,
  2510. KEY_ALL_ACCESS,
  2511. phkDevice) != ERROR_SUCCESS) {
  2512. if (DeviceX == 0) {
  2513. DeskLogError(LogSevInformation,
  2514. IDS_SETUPLOG_MSG_128,
  2515. TEXT("RegOpenKeyEx"));
  2516. }
  2517. goto Fallout;
  2518. }
  2519. retVal = TRUE;
  2520. } else {
  2521. if (DeviceX > 0) {
  2522. //
  2523. // For dual-view, the class installer handles only the primary view.
  2524. // Secondary views are handled by videoprt.sys
  2525. //
  2526. goto Fallout;
  2527. }
  2528. //
  2529. // The GUID is not there so create a new one.
  2530. //
  2531. if (CoCreateGuid(&DeviceKeyGUID) != S_OK) {
  2532. DeskLogError(LogSevInformation,
  2533. IDS_SETUPLOG_MSG_128,
  2534. TEXT("CoCreateGuid"));
  2535. goto Fallout;
  2536. }
  2537. if (StringFromIID(DeviceKeyGUID, &pwstrGUID) != S_OK) {
  2538. DeskLogError(LogSevInformation,
  2539. IDS_SETUPLOG_MSG_128,
  2540. TEXT("StringFromIID"));
  2541. pwstrGUID = NULL;
  2542. goto Fallout;
  2543. }
  2544. //
  2545. // Convert the string if necessary
  2546. //
  2547. #ifdef UNICODE
  2548. ptstrGUID = pwstrGUID;
  2549. #else
  2550. SIZE_T cch = wcslen(pwstrGUID) + 1;
  2551. ptstrGUID = LocalAlloc(LPTR, cch);
  2552. if (ptstrGUID == NULL)
  2553. goto Fallout;
  2554. WideCharToMultiByte(CP_ACP, 0, pwstrGUID, -1, ptstrGUID, cch, NULL, NULL);
  2555. #endif
  2556. //
  2557. // Upcase the string
  2558. //
  2559. CharUpper(ptstrGUID);
  2560. //
  2561. // Allocate the memory
  2562. //
  2563. len = max((lstrlen(SZ_VIDEO_DEVICES) +
  2564. lstrlen(ptstrGUID) +
  2565. max(6, lstrlen(SZ_COMMON_SUBKEY) + 1)),
  2566. (lstrlen(SZ_SERVICES_PATH) +
  2567. lstrlen(pServiceName) +
  2568. lstrlen(SZ_COMMON_SUBKEY) + 1));
  2569. pBuffer = (LPTSTR)LocalAlloc(LPTR, len * sizeof(TCHAR));
  2570. if (pBuffer == NULL) {
  2571. DeskLogError(LogSevInformation,
  2572. IDS_SETUPLOG_MSG_128,
  2573. TEXT("LocalAlloc"));
  2574. goto Fallout;
  2575. }
  2576. //
  2577. // Save the service name
  2578. //
  2579. lstrcpy(pBuffer, SZ_VIDEO_DEVICES);
  2580. lstrcat(pBuffer, ptstrGUID);
  2581. lstrcat(pBuffer, SZ_COMMON_SUBKEY);
  2582. if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  2583. pBuffer,
  2584. 0,
  2585. NULL,
  2586. REG_OPTION_NON_VOLATILE,
  2587. KEY_READ | KEY_WRITE,
  2588. NULL,
  2589. &hkCommonSubkey,
  2590. NULL) != ERROR_SUCCESS) {
  2591. DeskLogError(LogSevInformation,
  2592. IDS_SETUPLOG_MSG_128,
  2593. TEXT("RegCreateKeyEx"));
  2594. hkCommonSubkey = (HKEY)INVALID_HANDLE_VALUE;
  2595. goto Fallout;
  2596. }
  2597. if (RegSetValueEx(hkCommonSubkey,
  2598. SZ_SERVICE,
  2599. 0,
  2600. REG_SZ,
  2601. (LPBYTE)pServiceName,
  2602. (lstrlen(pServiceName) + 1) * sizeof(TCHAR)) != ERROR_SUCCESS) {
  2603. DeskLogError(LogSevInformation,
  2604. IDS_SETUPLOG_MSG_128,
  2605. TEXT("RegSetValueEx"));
  2606. goto Fallout;
  2607. }
  2608. RegCloseKey(hkCommonSubkey);
  2609. hkCommonSubkey = (HKEY)INVALID_HANDLE_VALUE;
  2610. lstrcpy(pBuffer, SZ_SERVICES_PATH);
  2611. lstrcat(pBuffer, pServiceName);
  2612. lstrcat(pBuffer, SZ_COMMON_SUBKEY);
  2613. if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  2614. pBuffer,
  2615. 0,
  2616. NULL,
  2617. REG_OPTION_NON_VOLATILE,
  2618. KEY_READ | KEY_WRITE,
  2619. NULL,
  2620. &hkCommonSubkey,
  2621. NULL) != ERROR_SUCCESS) {
  2622. DeskLogError(LogSevInformation,
  2623. IDS_SETUPLOG_MSG_128,
  2624. TEXT("RegCreateKeyEx"));
  2625. hkCommonSubkey = (HKEY)INVALID_HANDLE_VALUE;
  2626. goto Fallout;
  2627. }
  2628. if (RegSetValueEx(hkCommonSubkey,
  2629. SZ_SERVICE,
  2630. 0,
  2631. REG_SZ,
  2632. (LPBYTE)pServiceName,
  2633. (lstrlen(pServiceName) + 1) * sizeof(TCHAR)) != ERROR_SUCCESS) {
  2634. DeskLogError(LogSevInformation,
  2635. IDS_SETUPLOG_MSG_128,
  2636. TEXT("RegSetValueEx"));
  2637. goto Fallout;
  2638. }
  2639. //
  2640. // Build the new registry key
  2641. //
  2642. lstrcpy(pBuffer, SZ_VIDEO_DEVICES);
  2643. lstrcat(pBuffer, ptstrGUID);
  2644. lstrcat(pBuffer, TEXT("\\0000"));
  2645. //
  2646. // Create the key
  2647. //
  2648. if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  2649. pBuffer,
  2650. 0,
  2651. NULL,
  2652. REG_OPTION_NON_VOLATILE,
  2653. KEY_READ | KEY_WRITE,
  2654. NULL,
  2655. phkDevice,
  2656. NULL) != ERROR_SUCCESS) {
  2657. DeskLogError(LogSevInformation,
  2658. IDS_SETUPLOG_MSG_128,
  2659. TEXT("RegCreateKeyEx"));
  2660. goto Fallout;
  2661. }
  2662. //
  2663. // Store the GUID under the PnP key
  2664. //
  2665. if (RegSetValueEx(hkPnP,
  2666. SZ_GUID,
  2667. 0,
  2668. REG_SZ,
  2669. (LPBYTE)ptstrGUID,
  2670. (lstrlen(ptstrGUID) + 1) * sizeof(TCHAR)) != ERROR_SUCCESS) {
  2671. DeskLogError(LogSevInformation,
  2672. IDS_SETUPLOG_MSG_128,
  2673. TEXT("RegSetValueEx"));
  2674. RegCloseKey(*phkDevice);
  2675. *phkDevice = (HKEY)INVALID_HANDLE_VALUE;
  2676. goto Fallout;
  2677. }
  2678. retVal = TRUE;
  2679. }
  2680. Fallout:
  2681. //
  2682. // Clean-up
  2683. //
  2684. if (hkCommonSubkey != INVALID_HANDLE_VALUE) {
  2685. RegCloseKey(hkCommonSubkey);
  2686. }
  2687. if (pBuffer != NULL) {
  2688. LocalFree(pBuffer);
  2689. }
  2690. #ifndef UNICODE
  2691. if (ptstrGUID != NULL) {
  2692. LocalFree(ptstrGUID);
  2693. }
  2694. #endif
  2695. if (pwstrGUID != NULL) {
  2696. CoTaskMemFree(pwstrGUID);
  2697. }
  2698. if (hkPnP != INVALID_HANDLE_VALUE) {
  2699. RegCloseKey(hkPnP);
  2700. }
  2701. return retVal;
  2702. } // DeskGetVideoDeviceKey
  2703. BOOL
  2704. DeskIsServiceDisableable(
  2705. PTCHAR szService
  2706. )
  2707. {
  2708. return ((lstrcmp(szService, TEXT("vga")) != 0) &&
  2709. (lstrcmp(szService, TEXT("VgaSave")) != 0));
  2710. }
  2711. VOID
  2712. DeskDeleteAppletExtensions(
  2713. IN HDEVINFO hDevInfo,
  2714. IN PSP_DEVINFO_DATA pDeviceInfoData
  2715. )
  2716. {
  2717. PTCHAR mszBuffer = NULL;
  2718. HKEY hKeyUpdate;
  2719. DWORD dwSize, dwPlatform = VER_PLATFORM_WIN32_NT, dwMajorVer = 5;
  2720. BOOL bDeleteAppletExt = FALSE;
  2721. DWORD cbSize = 0;
  2722. //
  2723. // Open the upgrade registry key
  2724. //
  2725. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  2726. SZ_UPDATE_SETTINGS,
  2727. 0,
  2728. KEY_READ,
  2729. &hKeyUpdate) != ERROR_SUCCESS) {
  2730. //
  2731. // No big deal
  2732. //
  2733. return;
  2734. }
  2735. //
  2736. // Retrieve the applet extensions we want to delete from the registry
  2737. // Get the size first.
  2738. //
  2739. if (RegQueryValueEx(hKeyUpdate,
  2740. SZ_APPEXT_TO_DELETE,
  2741. 0,
  2742. NULL,
  2743. NULL,
  2744. &cbSize) != ERROR_SUCCESS) {
  2745. goto Fallout;
  2746. }
  2747. //
  2748. // Allocate the memory
  2749. //
  2750. mszBuffer = (PTCHAR)LocalAlloc(LPTR, cbSize);
  2751. if (mszBuffer == NULL) {
  2752. goto Fallout;
  2753. }
  2754. //
  2755. // Get the extensions
  2756. //
  2757. if ((RegQueryValueEx(hKeyUpdate,
  2758. SZ_APPEXT_TO_DELETE,
  2759. 0,
  2760. NULL,
  2761. (BYTE*)mszBuffer,
  2762. &cbSize) != ERROR_SUCCESS) ||
  2763. (*mszBuffer == TEXT('\0'))) {
  2764. goto Fallout;
  2765. }
  2766. //
  2767. // Read the OS version we are upgrading from from the registry
  2768. //
  2769. dwSize = sizeof(DWORD);
  2770. RegQueryValueEx(hKeyUpdate,
  2771. SZ_UPGRADE_FROM_PLATFORM,
  2772. NULL,
  2773. NULL,
  2774. (PBYTE) &dwPlatform, &dwSize);
  2775. dwSize = sizeof(DWORD);
  2776. RegQueryValueEx(hKeyUpdate,
  2777. SZ_UPGRADE_FROM_MAJOR_VERSION,
  2778. NULL,
  2779. NULL,
  2780. (PBYTE) &dwMajorVer, &dwSize);
  2781. //
  2782. // Don't do anything for Win3x or Win9x
  2783. //
  2784. if (dwPlatform != VER_PLATFORM_WIN32_NT) {
  2785. goto Fallout;
  2786. }
  2787. if ((dwMajorVer < 5) &&
  2788. (DeskCheckDatabase(hDevInfo,
  2789. pDeviceInfoData,
  2790. &bDeleteAppletExt) != ERROR_SUCCESS) &&
  2791. (!bDeleteAppletExt)) {
  2792. goto Fallout;
  2793. }
  2794. DeskAEDelete(REGSTR_PATH_CONTROLSFOLDER_DISPLAY_SHEX_PROPSHEET,
  2795. mszBuffer);
  2796. Fallout:
  2797. RegCloseKey(hKeyUpdate);
  2798. if (mszBuffer != NULL) {
  2799. LocalFree(mszBuffer);
  2800. }
  2801. }
  2802. VOID
  2803. DeskAEDelete(
  2804. PTCHAR szDeleteFrom,
  2805. PTCHAR mszExtensionsToRemove
  2806. )
  2807. {
  2808. TCHAR szKeyName[MAX_PATH];
  2809. HKEY hkDeleteFrom, hkExt;
  2810. DWORD cSubKeys = 0, cbSize = 0;
  2811. TCHAR szDefaultValue[MAX_PATH];
  2812. PTCHAR szValue;
  2813. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  2814. szDeleteFrom,
  2815. 0,
  2816. KEY_ALL_ACCESS,
  2817. &hkDeleteFrom) == ERROR_SUCCESS) {
  2818. if (RegQueryInfoKey(hkDeleteFrom,
  2819. NULL,
  2820. NULL,
  2821. NULL,
  2822. &cSubKeys,
  2823. NULL,
  2824. NULL,
  2825. NULL,
  2826. NULL,
  2827. NULL,
  2828. NULL,
  2829. NULL) == ERROR_SUCCESS) {
  2830. while (cSubKeys--) {
  2831. if (RegEnumKey(hkDeleteFrom,
  2832. cSubKeys,
  2833. szKeyName,
  2834. ARRAYSIZE(szKeyName)) == ERROR_SUCCESS) {
  2835. int iComp = -1;
  2836. if (RegOpenKeyEx(hkDeleteFrom,
  2837. szKeyName,
  2838. 0,
  2839. KEY_READ,
  2840. &hkExt) == ERROR_SUCCESS) {
  2841. cbSize = sizeof(szDefaultValue);
  2842. if ((RegQueryValueEx(hkExt,
  2843. NULL,
  2844. 0,
  2845. NULL,
  2846. (PBYTE)szDefaultValue,
  2847. &cbSize) == ERROR_SUCCESS) &&
  2848. (szDefaultValue[0] != TEXT('\0'))) {
  2849. szValue = mszExtensionsToRemove;
  2850. while (*szValue != TEXT('\0')) {
  2851. iComp = lstrcmpi(szDefaultValue, szValue);
  2852. if (iComp <= 0) {
  2853. break;
  2854. }
  2855. while (*szValue != TEXT('\0'))
  2856. szValue++;
  2857. szValue++;
  2858. }
  2859. }
  2860. RegCloseKey(hkExt);
  2861. }
  2862. if (iComp == 0) {
  2863. if (SHDeleteKey(hkDeleteFrom, szKeyName) == ERROR_SUCCESS) {
  2864. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_098, szKeyName);
  2865. } else {
  2866. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_097);
  2867. }
  2868. }
  2869. }
  2870. }
  2871. }
  2872. RegCloseKey(hkDeleteFrom);
  2873. }
  2874. }
  2875. VOID
  2876. DeskAEMove(
  2877. HDEVINFO hDevInfo,
  2878. PSP_DEVINFO_DATA pDeviceInfoData,
  2879. HKEY hkMoveFrom,
  2880. PAPPEXT pAppExtBefore,
  2881. PAPPEXT pAppExtAfter
  2882. )
  2883. {
  2884. HKEY hkDrvKey = (HKEY)INVALID_HANDLE_VALUE;
  2885. HKEY hkMoveTo = 0, hkMovedKey;
  2886. PAPPEXT pAppExtMove = NULL;
  2887. hkDrvKey = SetupDiOpenDevRegKey(hDevInfo,
  2888. pDeviceInfoData,
  2889. DICS_FLAG_GLOBAL,
  2890. 0,
  2891. DIREG_DRV,
  2892. KEY_ALL_ACCESS);
  2893. if (hkDrvKey == INVALID_HANDLE_VALUE) {
  2894. goto Fallout;
  2895. }
  2896. while (pAppExtAfter != NULL) {
  2897. BOOL bMove = FALSE;
  2898. pAppExtMove = pAppExtAfter;
  2899. if (pAppExtBefore != NULL) {
  2900. int iComp = lstrcmpi(pAppExtBefore->szDefaultValue, pAppExtAfter->szDefaultValue);
  2901. if (iComp < 0) {
  2902. pAppExtBefore = pAppExtBefore->pNext;
  2903. } else if (iComp == 0) {
  2904. pAppExtBefore = pAppExtBefore->pNext;
  2905. pAppExtAfter = pAppExtAfter->pNext;
  2906. } else {
  2907. bMove = TRUE;
  2908. pAppExtAfter = pAppExtAfter->pNext;
  2909. }
  2910. } else {
  2911. bMove = TRUE;
  2912. pAppExtAfter = pAppExtAfter->pNext;
  2913. }
  2914. if (bMove) {
  2915. SHDeleteKey(hkMoveFrom, pAppExtMove->szKeyName);
  2916. if (hkMoveTo == 0) {
  2917. if (RegCreateKeyEx(hkDrvKey,
  2918. TEXT("Display\\") STRREG_SHEX_PROPSHEET,
  2919. 0,
  2920. NULL,
  2921. REG_OPTION_NON_VOLATILE,
  2922. KEY_ALL_ACCESS,
  2923. NULL,
  2924. &hkMoveTo,
  2925. NULL) != ERROR_SUCCESS) {
  2926. hkMoveTo = 0;
  2927. goto Fallout;
  2928. }
  2929. }
  2930. if (RegCreateKeyEx(hkMoveTo,
  2931. pAppExtMove->szKeyName,
  2932. 0,
  2933. NULL,
  2934. REG_OPTION_NON_VOLATILE,
  2935. KEY_ALL_ACCESS,
  2936. NULL,
  2937. &hkMovedKey,
  2938. NULL) == ERROR_SUCCESS) {
  2939. RegSetValueEx(hkMovedKey,
  2940. NULL,
  2941. 0,
  2942. REG_SZ,
  2943. (PBYTE)(pAppExtMove->szDefaultValue),
  2944. (lstrlen(pAppExtMove->szDefaultValue) + 1) * sizeof(TCHAR));
  2945. //
  2946. // Make sure we check for duplicate applet extension when
  2947. // the advanced page is opened for the first time
  2948. //
  2949. DWORD CheckForDuplicates = 1;
  2950. RegSetValueEx(hkDrvKey,
  2951. TEXT("DeskCheckForDuplicates"),
  2952. 0,
  2953. REG_DWORD,
  2954. (LPBYTE)&CheckForDuplicates,
  2955. sizeof(DWORD));
  2956. RegCloseKey(hkMovedKey);
  2957. }
  2958. }
  2959. }
  2960. Fallout:
  2961. if (hkMoveTo != 0) {
  2962. RegCloseKey(hkMoveTo);
  2963. }
  2964. if (hkDrvKey != INVALID_HANDLE_VALUE) {
  2965. RegCloseKey(hkDrvKey);
  2966. }
  2967. }