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.

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