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.

1329 lines
38 KiB

  1. /*++
  2. Copyright (c) 1998-1999 Microsoft Corporation
  3. Module Name:
  4. ocpage.cpp
  5. Abstract:
  6. This file implements the display page setup.
  7. Environment:
  8. WIN32 User Mode
  9. --*/
  10. #include "precomp.h"
  11. #pragma hdrstop
  12. #include <stdio.h>
  13. #include <devguid.h>
  14. //
  15. // Defines
  16. //
  17. #define DEFAULT_XRESOLUTION 640
  18. #define DEFAULT_YRESOLUTION 480
  19. #define DEFAULT_BPP 15
  20. #define DEFAULT_VREFRESH 60
  21. #define MIN_XRESOLUTION 800
  22. #define MIN_YRESOLUTION 600
  23. //
  24. // Global Data
  25. //
  26. BOOL g_IsSetupInitComponentInitialized = FALSE;
  27. SETUP_INIT_COMPONENT g_SetupInitComponent;
  28. //
  29. // Function prototypes
  30. //
  31. DWORD
  32. HandleOcInitComponent(
  33. PSETUP_INIT_COMPONENT SetupInitComponent
  34. );
  35. DWORD
  36. HandleOcCompleteInstallation(
  37. VOID
  38. );
  39. BOOL
  40. MigrateUnattendedSettings(
  41. HDEVINFO hDevInfo
  42. );
  43. VOID
  44. MigrateRegistrySettings(
  45. HDEVINFO hDevInfo
  46. );
  47. VOID
  48. MigrateRegistrySettingsBasedOnBusLocation(
  49. HDEVINFO hDevInfo,
  50. HKEY hPhysicalDeviceKey,
  51. DWORD LogicalDevicesCount,
  52. DWORD BusNumber,
  53. DWORD Address
  54. );
  55. VOID
  56. MigrateRegistrySettingsLegacy(
  57. HDEVINFO hDevInfo,
  58. HKEY hPhysicalDeviceKey
  59. );
  60. VOID
  61. MigrateRegistrySettingsHelper(
  62. HDEVINFO hDevInfo,
  63. PSP_DEVINFO_DATA pDevInfoData,
  64. HKEY hPhysicalDeviceKey,
  65. DWORD LogicalDevicesCount
  66. );
  67. VOID
  68. MigrateDeviceKeySettings(
  69. HDEVINFO hDevInfo,
  70. PSP_DEVINFO_DATA pDevInfoData,
  71. HKEY hLogicalDeviceKey,
  72. DWORD Index
  73. );
  74. //
  75. // Implementation
  76. //
  77. extern "C" {
  78. DWORD
  79. DisplayOcSetupProc(
  80. IN LPCVOID ComponentId,
  81. IN LPCVOID SubcomponentId,
  82. IN UINT Function,
  83. IN UINT_PTR Param1,
  84. IN OUT PVOID Param2
  85. )
  86. {
  87. switch (Function) {
  88. case OC_PREINITIALIZE:
  89. return OCFLAG_UNICODE;
  90. case OC_INIT_COMPONENT:
  91. return HandleOcInitComponent((PSETUP_INIT_COMPONENT)Param2);
  92. case OC_QUERY_STATE:
  93. return SubcompOn; // we are always installed
  94. case OC_COMPLETE_INSTALLATION:
  95. return HandleOcCompleteInstallation();
  96. default:
  97. break;
  98. }
  99. return ERROR_SUCCESS;
  100. }
  101. } // extern "C"
  102. DWORD
  103. HandleOcInitComponent(
  104. PSETUP_INIT_COMPONENT SetupInitComponent
  105. )
  106. {
  107. DWORD retValue = ERROR_SUCCESS;
  108. if (OCMANAGER_VERSION <= SetupInitComponent->OCManagerVersion) {
  109. SetupInitComponent->ComponentVersion = OCMANAGER_VERSION;
  110. g_IsSetupInitComponentInitialized = TRUE;
  111. CopyMemory(
  112. &g_SetupInitComponent,
  113. (LPVOID)SetupInitComponent,
  114. sizeof(SETUP_INIT_COMPONENT));
  115. } else {
  116. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_100);
  117. retValue = ERROR_CALL_NOT_IMPLEMENTED;
  118. }
  119. return retValue;
  120. }
  121. DWORD
  122. HandleOcCompleteInstallation(
  123. VOID
  124. )
  125. {
  126. BOOL bUnattended = FALSE;
  127. HDEVINFO hDevInfo = INVALID_HANDLE_VALUE;
  128. HKEY hKey;
  129. DeskOpenLog();
  130. hDevInfo = SetupDiGetClassDevs((LPGUID)&GUID_DEVCLASS_DISPLAY,
  131. NULL,
  132. NULL,
  133. DIGCF_PRESENT);
  134. if (hDevInfo == INVALID_HANDLE_VALUE) {
  135. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_101);
  136. goto Cleanup;
  137. }
  138. if ((g_SetupInitComponent.SetupData.OperationFlags & SETUPOP_BATCH) != 0) {
  139. //
  140. // Unattended settings
  141. //
  142. bUnattended = MigrateUnattendedSettings(hDevInfo);
  143. }
  144. if ((!bUnattended) &&
  145. ((g_SetupInitComponent.SetupData.OperationFlags & SETUPOP_NTUPGRADE) != 0)) {
  146. //
  147. // Registry settings
  148. //
  149. MigrateRegistrySettings(hDevInfo);
  150. }
  151. Cleanup:
  152. RegDeleteKey(HKEY_LOCAL_MACHINE, SZ_DETECT_DISPLAY);
  153. RegDeleteKey(HKEY_LOCAL_MACHINE, SZ_NEW_DISPLAY);
  154. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  155. SZ_UPDATE_SETTINGS_PATH,
  156. 0,
  157. KEY_WRITE,
  158. &hKey) == ERROR_SUCCESS) {
  159. SHDeleteKey(hKey, SZ_UPDATE_SETTINGS_KEY);
  160. RegCloseKey(hKey);
  161. } else {
  162. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_102);
  163. }
  164. if (hDevInfo != INVALID_HANDLE_VALUE) {
  165. SetupDiDestroyDeviceInfoList(hDevInfo);
  166. }
  167. DeskCloseLog();
  168. return ERROR_SUCCESS;
  169. }
  170. BOOL
  171. MigrateUnattendedSettings(
  172. HDEVINFO hDevInfo
  173. )
  174. {
  175. INFCONTEXT context;
  176. HINF hInf;
  177. TCHAR szName[128];
  178. DWORD value;
  179. DWORD cFields = 0;
  180. DWORD BitsPerPel = 0, XResolution = 0, YResolution = 0, VRefresh = 0;
  181. DWORD UsePreferredMode = 0;
  182. DWORD AttachedToDesktop = 0;
  183. SP_DEVINFO_DATA DevInfoData;
  184. SP_DEVICE_INTERFACE_DATA InterfaceData;
  185. HKEY hInterfaceKey = (HKEY)INVALID_HANDLE_VALUE;
  186. HKEY hInterfaceLogicalDeviceKey = (HKEY)INVALID_HANDLE_VALUE;
  187. DWORD DevInfoIndex = 0;
  188. //
  189. // Get the handle to the answer file
  190. //
  191. hInf = g_SetupInitComponent.HelperRoutines.GetInfHandle(
  192. INFINDEX_UNATTENDED,
  193. g_SetupInitComponent.HelperRoutines.OcManagerContext);
  194. if ((hInf == NULL) ||
  195. (hInf == (HINF)INVALID_HANDLE_VALUE)) {
  196. return FALSE;
  197. }
  198. //
  199. // Read the settings from the answer file
  200. //
  201. if (SetupFindFirstLine(hInf, TEXT("Display"), NULL, &context)) {
  202. do {
  203. if (SetupGetStringField(&context,
  204. 0,
  205. szName,
  206. ARRAYSIZE(szName),
  207. &value)) {
  208. if (lstrcmpi(szName, TEXT("BitsPerPel")) == 0) {
  209. if (SetupGetIntField(&context, 1, (PINT)&value)) {
  210. ++cFields;
  211. BitsPerPel = value;
  212. } else {
  213. SetupGetStringField(&context,
  214. 1,
  215. szName,
  216. ARRAYSIZE(szName),
  217. &value);
  218. DeskLogError(LogSevInformation,
  219. IDS_SETUPLOG_MSG_096,
  220. szName);
  221. }
  222. } else if (lstrcmpi(szName, TEXT("Xresolution")) == 0) {
  223. if (SetupGetIntField(&context, 1, (PINT)&value)) {
  224. ++cFields;
  225. XResolution = value;
  226. } else {
  227. SetupGetStringField(&context,
  228. 1,
  229. szName,
  230. ARRAYSIZE(szName),
  231. &value);
  232. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_060);
  233. }
  234. } else if (lstrcmpi(szName, TEXT("YResolution")) == 0) {
  235. if (SetupGetIntField(&context, 1, (PINT) &value)) {
  236. ++cFields;
  237. YResolution = value;
  238. } else {
  239. SetupGetStringField(&context,
  240. 1,
  241. szName,
  242. ARRAYSIZE(szName),
  243. &value);
  244. DeskLogError(LogSevInformation,
  245. IDS_SETUPLOG_MSG_062,
  246. szName);
  247. }
  248. } else if (lstrcmpi( szName, TEXT("VRefresh")) == 0) {
  249. if (SetupGetIntField(&context, 1, (PINT) &value)) {
  250. ++cFields;
  251. VRefresh = value;
  252. } else {
  253. SetupGetStringField(&context,
  254. 1,
  255. szName,
  256. ARRAYSIZE(szName),
  257. &value);
  258. DeskLogError(LogSevInformation,
  259. IDS_SETUPLOG_MSG_064,
  260. szName);
  261. }
  262. } else {
  263. DeskLogError(LogSevInformation,
  264. IDS_SETUPLOG_MSG_065,
  265. szName);
  266. }
  267. }
  268. } while (SetupFindNextLine(&context, &context));
  269. }
  270. if (cFields == 0) {
  271. //
  272. // The answer file doesn't contain any display settings
  273. //
  274. goto Fallout;
  275. }
  276. //
  277. // "Normalize" the display settings
  278. //
  279. AttachedToDesktop = 1;
  280. if (BitsPerPel == 0) {
  281. DeskLogError(LogSevInformation,
  282. IDS_SETUPLOG_MSG_069,
  283. DEFAULT_BPP);
  284. BitsPerPel = DEFAULT_BPP;
  285. }
  286. if ((XResolution == 0) || (YResolution == 0)) {
  287. DeskLogError(LogSevInformation,
  288. IDS_SETUPLOG_MSG_067,
  289. DEFAULT_XRESOLUTION,
  290. DEFAULT_YRESOLUTION);
  291. XResolution = DEFAULT_XRESOLUTION;
  292. YResolution = DEFAULT_YRESOLUTION;
  293. }
  294. if (VRefresh == 0) {
  295. DeskLogError(LogSevInformation,
  296. IDS_SETUPLOG_MSG_068,
  297. DEFAULT_VREFRESH);
  298. VRefresh = DEFAULT_VREFRESH;
  299. }
  300. //
  301. // Apply the display settings to all video cards
  302. //
  303. DevInfoIndex = 0;
  304. DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  305. while (SetupDiEnumDeviceInfo(hDevInfo, DevInfoIndex, &DevInfoData)) {
  306. InterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
  307. if (!SetupDiCreateDeviceInterface(hDevInfo,
  308. &DevInfoData,
  309. &GUID_DISPLAY_ADAPTER_INTERFACE,
  310. NULL,
  311. 0,
  312. &InterfaceData)) {
  313. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_103);
  314. goto NextDevice;
  315. }
  316. hInterfaceKey = SetupDiCreateDeviceInterfaceRegKey(hDevInfo,
  317. &InterfaceData,
  318. 0,
  319. KEY_SET_VALUE,
  320. NULL,
  321. NULL);
  322. if (hInterfaceKey == INVALID_HANDLE_VALUE) {
  323. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_104);
  324. goto NextDevice;
  325. }
  326. if (RegCreateKeyEx(hInterfaceKey,
  327. TEXT("0"),
  328. 0,
  329. NULL,
  330. REG_OPTION_NON_VOLATILE,
  331. KEY_WRITE,
  332. NULL,
  333. &hInterfaceLogicalDeviceKey,
  334. NULL) != ERROR_SUCCESS) {
  335. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_105, 0);
  336. hInterfaceLogicalDeviceKey = (HKEY)INVALID_HANDLE_VALUE;
  337. goto NextDevice;
  338. }
  339. //
  340. // Do not use the preferred mode for unattended installs
  341. //
  342. UsePreferredMode = 0;
  343. RegSetValueEx(hInterfaceLogicalDeviceKey,
  344. SZ_VU_PREFERRED_MODE,
  345. 0,
  346. REG_DWORD,
  347. (PBYTE)&UsePreferredMode,
  348. sizeof(UsePreferredMode));
  349. //
  350. // AttachedToDesktop
  351. //
  352. RegSetValueEx(hInterfaceLogicalDeviceKey,
  353. SZ_VU_ATTACHED_TO_DESKTOP,
  354. 0,
  355. REG_DWORD,
  356. (PBYTE)&AttachedToDesktop,
  357. sizeof(AttachedToDesktop));
  358. //
  359. // BitsPerPel
  360. //
  361. if (RegSetValueEx(hInterfaceLogicalDeviceKey,
  362. SZ_VU_BITS_PER_PEL,
  363. 0,
  364. REG_DWORD,
  365. (PBYTE)&BitsPerPel,
  366. sizeof(BitsPerPel)) == ERROR_SUCCESS) {
  367. DeskLogError(LogSevInformation,
  368. IDS_SETUPLOG_MSG_106,
  369. BitsPerPel);
  370. }
  371. //
  372. // XResolution
  373. //
  374. if (RegSetValueEx(hInterfaceLogicalDeviceKey,
  375. SZ_VU_X_RESOLUTION,
  376. 0,
  377. REG_DWORD,
  378. (PBYTE)&XResolution,
  379. sizeof(XResolution)) == ERROR_SUCCESS) {
  380. DeskLogError(LogSevInformation,
  381. IDS_SETUPLOG_MSG_107,
  382. XResolution);
  383. }
  384. //
  385. // dwYResolution
  386. //
  387. if (RegSetValueEx(hInterfaceLogicalDeviceKey,
  388. SZ_VU_Y_RESOLUTION,
  389. 0,
  390. REG_DWORD,
  391. (PBYTE)&YResolution,
  392. sizeof(YResolution)) == ERROR_SUCCESS) {
  393. DeskLogError(LogSevInformation,
  394. IDS_SETUPLOG_MSG_108,
  395. YResolution);
  396. }
  397. //
  398. // dwVRefresh
  399. //
  400. if (RegSetValueEx(hInterfaceLogicalDeviceKey,
  401. SZ_VU_VREFRESH,
  402. 0,
  403. REG_DWORD,
  404. (PBYTE)&VRefresh,
  405. sizeof(VRefresh)) == ERROR_SUCCESS) {
  406. DeskLogError(LogSevInformation,
  407. IDS_SETUPLOG_MSG_109,
  408. VRefresh);
  409. }
  410. NextDevice:
  411. if (hInterfaceLogicalDeviceKey != INVALID_HANDLE_VALUE) {
  412. RegCloseKey(hInterfaceLogicalDeviceKey);
  413. hInterfaceLogicalDeviceKey = (HKEY)INVALID_HANDLE_VALUE;
  414. }
  415. if (hInterfaceKey != INVALID_HANDLE_VALUE) {
  416. RegCloseKey(hInterfaceKey);
  417. hInterfaceKey = (HKEY)INVALID_HANDLE_VALUE;
  418. }
  419. DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  420. ++DevInfoIndex;
  421. }
  422. Fallout:
  423. return (cFields != 0);
  424. }
  425. VOID
  426. MigrateRegistrySettings(
  427. HDEVINFO hDevInfo
  428. )
  429. {
  430. HKEY hKey = 0, hPhysicalDeviceKey = 0;
  431. DWORD PhysicalDevicesCount = 0, LogicalDevicesCount = 0;
  432. DWORD cb = 0, PhysicalDevice = 0, Failed = 0;
  433. TCHAR Buffer[20];
  434. BOOL IsLegacy;
  435. DWORD BusNumber = 0, Address = 0;
  436. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  437. SZ_UPDATE_SETTINGS,
  438. 0,
  439. KEY_READ,
  440. &hKey) != ERROR_SUCCESS) {
  441. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_075);
  442. hKey = 0;
  443. goto Cleanup;
  444. }
  445. cb = sizeof(DWORD);
  446. if ((RegQueryValueEx(hKey,
  447. SZ_UPGRADE_FAILED_ALLOW_INSTALL,
  448. NULL,
  449. NULL,
  450. (LPBYTE)&Failed,
  451. &cb) == ERROR_SUCCESS) &&
  452. (Failed != 0)) {
  453. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_076);
  454. goto Cleanup;
  455. }
  456. cb = sizeof(PhysicalDevicesCount);
  457. if (RegQueryValueEx(hKey,
  458. SZ_VU_COUNT,
  459. 0,
  460. NULL,
  461. (PBYTE)&PhysicalDevicesCount,
  462. &cb) != ERROR_SUCCESS) {
  463. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_110);
  464. goto Cleanup;
  465. }
  466. for(PhysicalDevice = 0;
  467. PhysicalDevice < PhysicalDevicesCount;
  468. PhysicalDevice++) {
  469. StringCchCopy(Buffer, ARRAYSIZE(Buffer), SZ_VU_PHYSICAL);
  470. size_t cchBuf = lstrlen(Buffer);
  471. StringCchPrintf(Buffer + cchBuf, ARRAYSIZE(Buffer) - cchBuf, TEXT("%d"), PhysicalDevice);
  472. if (RegOpenKeyEx(hKey,
  473. Buffer,
  474. 0,
  475. KEY_READ,
  476. &hPhysicalDeviceKey) != ERROR_SUCCESS) {
  477. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_111);
  478. hPhysicalDeviceKey = 0;
  479. goto NextPhysicalDevice;
  480. }
  481. //
  482. // Get the count of logical devices
  483. //
  484. cb = sizeof(LogicalDevicesCount);
  485. if (RegQueryValueEx(hPhysicalDeviceKey,
  486. SZ_VU_COUNT,
  487. 0,
  488. NULL,
  489. (PBYTE)&LogicalDevicesCount,
  490. &cb) != ERROR_SUCCESS) {
  491. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_112);
  492. goto NextPhysicalDevice;
  493. }
  494. //
  495. // Get the bus number and address
  496. //
  497. IsLegacy = TRUE;
  498. cb = sizeof(BusNumber);
  499. if (RegQueryValueEx(hPhysicalDeviceKey,
  500. SZ_VU_BUS_NUMBER,
  501. 0,
  502. NULL,
  503. (PBYTE)&BusNumber,
  504. &cb) == ERROR_SUCCESS) {
  505. cb = sizeof(Address);
  506. if (RegQueryValueEx(hPhysicalDeviceKey,
  507. SZ_VU_ADDRESS,
  508. 0,
  509. NULL,
  510. (PBYTE)&Address,
  511. &cb) == ERROR_SUCCESS) {
  512. IsLegacy = FALSE;
  513. }
  514. }
  515. if (!IsLegacy) {
  516. MigrateRegistrySettingsBasedOnBusLocation(hDevInfo,
  517. hPhysicalDeviceKey,
  518. LogicalDevicesCount,
  519. BusNumber,
  520. Address);
  521. } else if ((PhysicalDevicesCount == 1) &&
  522. (LogicalDevicesCount == 1)) {
  523. //
  524. // If legacy, we support migration of a single device.
  525. //
  526. MigrateRegistrySettingsLegacy(hDevInfo,
  527. hPhysicalDeviceKey);
  528. }
  529. NextPhysicalDevice:
  530. if (hPhysicalDeviceKey != 0) {
  531. RegCloseKey(hPhysicalDeviceKey);
  532. hPhysicalDeviceKey = 0;
  533. }
  534. }
  535. Cleanup:
  536. if (hKey != 0) {
  537. RegCloseKey(hKey);
  538. }
  539. return;
  540. }
  541. VOID
  542. MigrateRegistrySettingsBasedOnBusLocation(
  543. HDEVINFO hDevInfo,
  544. HKEY hPhysicalDeviceKey,
  545. DWORD LogicalDevicesCount,
  546. DWORD BusNumber,
  547. DWORD Address
  548. )
  549. {
  550. SP_DEVINFO_DATA DevInfoData;
  551. DWORD CurrentBusNumber = 0, CurrentAddress = 0;
  552. DWORD DevInfoIndex = 0;
  553. BOOL bFound = FALSE;
  554. //
  555. // Let's find the device with the same bus number and address
  556. //
  557. DevInfoIndex = 0;
  558. DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  559. while (SetupDiEnumDeviceInfo(hDevInfo, DevInfoIndex, &DevInfoData)) {
  560. if (SetupDiGetDeviceRegistryProperty(hDevInfo,
  561. &DevInfoData,
  562. SPDRP_BUSNUMBER,
  563. NULL,
  564. (PBYTE)&CurrentBusNumber,
  565. sizeof(CurrentBusNumber),
  566. NULL) &&
  567. (CurrentBusNumber == BusNumber) &&
  568. SetupDiGetDeviceRegistryProperty(hDevInfo,
  569. &DevInfoData,
  570. SPDRP_ADDRESS,
  571. NULL,
  572. (PBYTE)&CurrentAddress,
  573. sizeof(CurrentAddress),
  574. NULL) &&
  575. (CurrentAddress == Address)) {
  576. //
  577. // We found the device with the same bus number and address
  578. // So ... migrate the settings
  579. //
  580. MigrateRegistrySettingsHelper(hDevInfo,
  581. &DevInfoData,
  582. hPhysicalDeviceKey,
  583. LogicalDevicesCount);
  584. //
  585. // We are done
  586. //
  587. bFound = TRUE;
  588. break;
  589. }
  590. //
  591. // Next device
  592. //
  593. DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  594. ++DevInfoIndex;
  595. }
  596. if (!bFound) {
  597. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_113);
  598. }
  599. return;
  600. }
  601. VOID
  602. MigrateRegistrySettingsLegacy(
  603. HDEVINFO hDevInfo,
  604. HKEY hPhysicalDeviceKey
  605. )
  606. {
  607. SP_DEVINFO_DATA DevInfoData0, DevInfoData1;
  608. DevInfoData0.cbSize = sizeof(SP_DEVINFO_DATA);
  609. if (!SetupDiEnumDeviceInfo(hDevInfo, 0, &DevInfoData0)) {
  610. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_115);
  611. return;
  612. }
  613. DevInfoData1.cbSize = sizeof(SP_DEVINFO_DATA);
  614. if (SetupDiEnumDeviceInfo(hDevInfo, 1, &DevInfoData1)) {
  615. //
  616. // There are at least 2 video devices in the system
  617. // We don't know which device to apply the settings to.
  618. // So, just ignore this case
  619. //
  620. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_114);
  621. return;
  622. }
  623. MigrateRegistrySettingsHelper(hDevInfo,
  624. &DevInfoData0,
  625. hPhysicalDeviceKey,
  626. 1); // there is only one logical device
  627. }
  628. VOID
  629. MigrateRegistrySettingsHelper(
  630. HDEVINFO hDevInfo,
  631. PSP_DEVINFO_DATA pDevInfoData,
  632. HKEY hPhysicalDeviceKey,
  633. DWORD LogicalDevicesCount
  634. )
  635. {
  636. SP_DEVICE_INTERFACE_DATA InterfaceData;
  637. HKEY hInterfaceKey = 0;
  638. HKEY hInterfaceLogicalDeviceKey = 0;
  639. HKEY hLogicalDeviceKey = 0;
  640. TCHAR Buffer[20];
  641. DWORD cb = 0, LogicalDevice = 0;
  642. DWORD UsePreferredMode = 0;
  643. DWORD AttachedToDesktop = 0;
  644. DWORD RelativeX = 0;
  645. DWORD RelativeY = 0;
  646. DWORD BitsPerPel = 0;
  647. DWORD XResolution = 0;
  648. DWORD YResolution = 0;
  649. DWORD VRefresh = 0;
  650. DWORD Flags = 0;
  651. InterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
  652. if (!SetupDiCreateDeviceInterface(hDevInfo,
  653. pDevInfoData,
  654. &GUID_DISPLAY_ADAPTER_INTERFACE,
  655. NULL,
  656. 0,
  657. &InterfaceData)) {
  658. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_103);
  659. return;
  660. }
  661. hInterfaceKey = SetupDiCreateDeviceInterfaceRegKey(hDevInfo,
  662. &InterfaceData,
  663. 0,
  664. KEY_SET_VALUE,
  665. NULL,
  666. NULL);
  667. if (hInterfaceKey == INVALID_HANDLE_VALUE) {
  668. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_104);
  669. return;
  670. }
  671. for (LogicalDevice = 0;
  672. LogicalDevice < LogicalDevicesCount;
  673. ++LogicalDevice) {
  674. StringCchCopy(Buffer, ARRAYSIZE(Buffer), SZ_VU_LOGICAL);
  675. size_t cchBuf = lstrlen(Buffer);
  676. StringCchPrintf(Buffer + cchBuf, ARRAYSIZE(Buffer) - cchBuf, TEXT("%d"), LogicalDevice);
  677. if (RegOpenKeyEx(hPhysicalDeviceKey,
  678. Buffer,
  679. 0,
  680. KEY_READ,
  681. &hLogicalDeviceKey) != ERROR_SUCCESS) {
  682. //
  683. // We can not go on with this physical device
  684. // The LogicalDevices order is important for DualView
  685. //
  686. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_116);
  687. break;
  688. }
  689. StringCchPrintf(Buffer, ARRAYSIZE(Buffer), TEXT("%d"), LogicalDevice);
  690. if (RegCreateKeyEx(hInterfaceKey,
  691. Buffer,
  692. 0,
  693. NULL,
  694. REG_OPTION_NON_VOLATILE,
  695. KEY_WRITE,
  696. NULL,
  697. &hInterfaceLogicalDeviceKey,
  698. NULL) != ERROR_SUCCESS) {
  699. //
  700. // We can not go on with this physical device
  701. // The LogicalDevices order is important for DualView
  702. //
  703. DeskLogError(LogSevInformation, IDS_SETUPLOG_MSG_105, LogicalDevice);
  704. RegCloseKey(hLogicalDeviceKey);
  705. break;
  706. }
  707. //
  708. // Use preferred mode?
  709. //
  710. cb = sizeof(XResolution);
  711. if (RegQueryValueEx(hLogicalDeviceKey,
  712. SZ_VU_X_RESOLUTION,
  713. 0,
  714. NULL,
  715. (PBYTE)&XResolution,
  716. &cb) != ERROR_SUCCESS) {
  717. XResolution = DEFAULT_XRESOLUTION;
  718. }
  719. cb = sizeof(YResolution);
  720. if (RegQueryValueEx(hLogicalDeviceKey,
  721. SZ_VU_Y_RESOLUTION,
  722. 0,
  723. NULL,
  724. (PBYTE)&YResolution,
  725. &cb) != ERROR_SUCCESS) {
  726. YResolution = DEFAULT_YRESOLUTION;
  727. }
  728. UsePreferredMode = ((XResolution < MIN_XRESOLUTION) ||
  729. (YResolution < MIN_YRESOLUTION));
  730. RegSetValueEx(hInterfaceLogicalDeviceKey,
  731. SZ_VU_PREFERRED_MODE,
  732. 0,
  733. REG_DWORD,
  734. (PBYTE)&UsePreferredMode,
  735. sizeof(UsePreferredMode));
  736. if (UsePreferredMode) {
  737. DeskLogError(LogSevInformation,
  738. IDS_SETUPLOG_MSG_130);
  739. } else {
  740. //
  741. // AttachedToDesktop
  742. //
  743. cb = sizeof(AttachedToDesktop);
  744. if (RegQueryValueEx(hLogicalDeviceKey,
  745. SZ_VU_ATTACHED_TO_DESKTOP,
  746. 0,
  747. NULL,
  748. (PBYTE)&AttachedToDesktop,
  749. &cb) == ERROR_SUCCESS) {
  750. if (RegSetValueEx(hInterfaceLogicalDeviceKey,
  751. SZ_VU_ATTACHED_TO_DESKTOP,
  752. 0,
  753. REG_DWORD,
  754. (PBYTE)&AttachedToDesktop,
  755. sizeof(AttachedToDesktop)) == ERROR_SUCCESS) {
  756. DeskLogError(LogSevInformation,
  757. IDS_SETUPLOG_MSG_117,
  758. AttachedToDesktop);
  759. }
  760. }
  761. //
  762. // RelativeX
  763. //
  764. cb = sizeof(RelativeX);
  765. if (RegQueryValueEx(hLogicalDeviceKey,
  766. SZ_VU_RELATIVE_X,
  767. 0,
  768. NULL,
  769. (PBYTE)&RelativeX,
  770. &cb) == ERROR_SUCCESS) {
  771. if (RegSetValueEx(hInterfaceLogicalDeviceKey,
  772. SZ_VU_RELATIVE_X,
  773. 0,
  774. REG_DWORD,
  775. (PBYTE)&RelativeX,
  776. sizeof(RelativeX)) == ERROR_SUCCESS) {
  777. DeskLogError(LogSevInformation,
  778. IDS_SETUPLOG_MSG_118,
  779. RelativeX);
  780. }
  781. }
  782. //
  783. // RelativeY
  784. //
  785. cb = sizeof(RelativeY);
  786. if (RegQueryValueEx(hLogicalDeviceKey,
  787. SZ_VU_RELATIVE_Y,
  788. 0,
  789. NULL,
  790. (PBYTE)&RelativeY,
  791. &cb) == ERROR_SUCCESS) {
  792. if (RegSetValueEx(hInterfaceLogicalDeviceKey,
  793. SZ_VU_RELATIVE_Y,
  794. 0,
  795. REG_DWORD,
  796. (PBYTE)&RelativeY,
  797. sizeof(RelativeY)) == ERROR_SUCCESS) {
  798. DeskLogError(LogSevInformation,
  799. IDS_SETUPLOG_MSG_119,
  800. RelativeY);
  801. }
  802. }
  803. //
  804. // BitsPerPel
  805. //
  806. cb = sizeof(BitsPerPel);
  807. if (RegQueryValueEx(hLogicalDeviceKey,
  808. SZ_VU_BITS_PER_PEL,
  809. 0,
  810. NULL,
  811. (PBYTE)&BitsPerPel,
  812. &cb) == ERROR_SUCCESS) {
  813. if (RegSetValueEx(hInterfaceLogicalDeviceKey,
  814. SZ_VU_BITS_PER_PEL,
  815. 0,
  816. REG_DWORD,
  817. (PBYTE)&BitsPerPel,
  818. sizeof(BitsPerPel)) == ERROR_SUCCESS) {
  819. DeskLogError(LogSevInformation,
  820. IDS_SETUPLOG_MSG_120,
  821. BitsPerPel);
  822. }
  823. }
  824. //
  825. // XResolution
  826. //
  827. if (RegSetValueEx(hInterfaceLogicalDeviceKey,
  828. SZ_VU_X_RESOLUTION,
  829. 0,
  830. REG_DWORD,
  831. (PBYTE)&XResolution,
  832. sizeof(XResolution)) == ERROR_SUCCESS) {
  833. DeskLogError(LogSevInformation,
  834. IDS_SETUPLOG_MSG_121,
  835. XResolution);
  836. }
  837. //
  838. // dwYResolution
  839. //
  840. if (RegSetValueEx(hInterfaceLogicalDeviceKey,
  841. SZ_VU_Y_RESOLUTION,
  842. 0,
  843. REG_DWORD,
  844. (PBYTE)&YResolution,
  845. sizeof(YResolution)) == ERROR_SUCCESS) {
  846. DeskLogError(LogSevInformation,
  847. IDS_SETUPLOG_MSG_122,
  848. YResolution);
  849. }
  850. //
  851. // dwVRefresh
  852. //
  853. cb = sizeof(VRefresh);
  854. if (RegQueryValueEx(hLogicalDeviceKey,
  855. SZ_VU_VREFRESH,
  856. 0,
  857. NULL,
  858. (PBYTE)&VRefresh,
  859. &cb) == ERROR_SUCCESS) {
  860. if (RegSetValueEx(hInterfaceLogicalDeviceKey,
  861. SZ_VU_VREFRESH,
  862. 0,
  863. REG_DWORD,
  864. (PBYTE)&VRefresh,
  865. sizeof(VRefresh)) == ERROR_SUCCESS) {
  866. DeskLogError(LogSevInformation,
  867. IDS_SETUPLOG_MSG_123,
  868. VRefresh);
  869. }
  870. }
  871. //
  872. // Flags
  873. //
  874. cb = sizeof(Flags);
  875. if (RegQueryValueEx(hLogicalDeviceKey,
  876. SZ_VU_FLAGS,
  877. 0,
  878. NULL,
  879. (PBYTE)&Flags,
  880. &cb) == ERROR_SUCCESS) {
  881. if (RegSetValueEx(hInterfaceLogicalDeviceKey,
  882. SZ_VU_FLAGS,
  883. 0,
  884. REG_DWORD,
  885. (PBYTE)&Flags,
  886. sizeof(Flags)) == ERROR_SUCCESS) {
  887. DeskLogError(LogSevInformation,
  888. IDS_SETUPLOG_MSG_124,
  889. Flags);
  890. }
  891. }
  892. }
  893. //
  894. // Migrate the hardware acceleration and the pruning mode
  895. //
  896. MigrateDeviceKeySettings(hDevInfo,
  897. pDevInfoData,
  898. hLogicalDeviceKey,
  899. LogicalDevice);
  900. RegCloseKey(hLogicalDeviceKey);
  901. RegCloseKey(hInterfaceLogicalDeviceKey);
  902. }
  903. RegCloseKey(hInterfaceKey);
  904. }
  905. VOID
  906. MigrateDeviceKeySettings(
  907. HDEVINFO hDevInfo,
  908. PSP_DEVINFO_DATA pDevInfoData,
  909. HKEY hLogicalDeviceKey,
  910. DWORD Index
  911. )
  912. {
  913. HKEY hkPnP = (HKEY)INVALID_HANDLE_VALUE;
  914. HKEY hkDevice = (HKEY)INVALID_HANDLE_VALUE;
  915. LPTSTR pBuffer = NULL;
  916. DWORD dwSize, len, cb;
  917. DWORD HwAcceleration, PruningMode;
  918. //
  919. // Open the PnP key
  920. //
  921. hkPnP = SetupDiOpenDevRegKey(hDevInfo,
  922. pDevInfoData,
  923. DICS_FLAG_GLOBAL,
  924. 0,
  925. DIREG_DEV,
  926. KEY_READ);
  927. if (hkPnP == INVALID_HANDLE_VALUE) {
  928. DeskLogError(LogSevInformation,
  929. IDS_SETUPLOG_MSG_127,
  930. TEXT("SetupDiOpenDevRegKey"));
  931. goto Fallout;
  932. }
  933. //
  934. // Try to get the GUID from the PnP key
  935. //
  936. dwSize = 0;
  937. if (RegQueryValueEx(hkPnP,
  938. SZ_GUID,
  939. 0,
  940. NULL,
  941. NULL,
  942. &dwSize) != ERROR_SUCCESS) {
  943. DeskLogError(LogSevInformation,
  944. IDS_SETUPLOG_MSG_127,
  945. TEXT("RegQueryValueEx"));
  946. goto Fallout;
  947. }
  948. len = lstrlen(SZ_VIDEO_DEVICES);
  949. DWORD cbBuf = dwSize + (len + 6) * sizeof(TCHAR);
  950. pBuffer = (LPTSTR)LocalAlloc(LPTR, cbBuf);
  951. if (pBuffer == NULL) {
  952. DeskLogError(LogSevInformation,
  953. IDS_SETUPLOG_MSG_127,
  954. TEXT("LocalAlloc"));
  955. goto Fallout;
  956. }
  957. StringCbCopy(pBuffer, cbBuf, SZ_VIDEO_DEVICES);
  958. if (RegQueryValueEx(hkPnP,
  959. SZ_GUID,
  960. 0,
  961. NULL,
  962. (PBYTE)(pBuffer + len),
  963. &dwSize) != ERROR_SUCCESS) {
  964. DeskLogError(LogSevInformation,
  965. IDS_SETUPLOG_MSG_127,
  966. TEXT("RegQueryValueEx"));
  967. goto Fallout;
  968. }
  969. DWORD cchGUID = lstrlen(pBuffer);
  970. StringCbPrintf(pBuffer + cchGUID, cbBuf - (cchGUID * sizeof(TCHAR)), L"\\%04d", Index);
  971. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  972. pBuffer,
  973. 0,
  974. KEY_WRITE,
  975. &hkDevice) != ERROR_SUCCESS) {
  976. DeskLogError(LogSevInformation,
  977. IDS_SETUPLOG_MSG_127,
  978. TEXT("RegOpenKeyEx"));
  979. hkDevice = (HKEY)INVALID_HANDLE_VALUE;
  980. goto Fallout;
  981. }
  982. //
  983. // Hardware acceleration
  984. //
  985. cb = sizeof(HwAcceleration);
  986. if (RegQueryValueEx(hLogicalDeviceKey,
  987. SZ_HW_ACCELERATION,
  988. 0,
  989. NULL,
  990. (PBYTE)&HwAcceleration,
  991. &cb) == ERROR_SUCCESS) {
  992. RegSetValueEx(hkDevice,
  993. SZ_HW_ACCELERATION,
  994. 0,
  995. REG_DWORD,
  996. (PBYTE)&HwAcceleration,
  997. sizeof(HwAcceleration));
  998. }
  999. //
  1000. // Pruning mode
  1001. //
  1002. cb = sizeof(PruningMode);
  1003. if (RegQueryValueEx(hLogicalDeviceKey,
  1004. SZ_PRUNNING_MODE,
  1005. 0,
  1006. NULL,
  1007. (PBYTE)&PruningMode,
  1008. &cb) == ERROR_SUCCESS) {
  1009. RegSetValueEx(hkDevice,
  1010. SZ_PRUNNING_MODE,
  1011. 0,
  1012. REG_DWORD,
  1013. (PBYTE)&PruningMode,
  1014. sizeof(PruningMode));
  1015. }
  1016. Fallout:
  1017. if (hkPnP != INVALID_HANDLE_VALUE) {
  1018. RegCloseKey(hkPnP);
  1019. }
  1020. if (pBuffer != NULL) {
  1021. LocalFree(pBuffer);
  1022. }
  1023. if (hkDevice != INVALID_HANDLE_VALUE) {
  1024. RegCloseKey(hkDevice);
  1025. }
  1026. }