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.

2024 lines
54 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. #ifdef UNICODE
  4. #define DRIVER_VALUE_ENTRY TEXT("Driver");
  5. BOOL
  6. IsServiceToBeDisabled(
  7. IN PVOID NtCompatInfHandle,
  8. IN LPTSTR ServiceName
  9. )
  10. {
  11. PLIST_ENTRY Next;
  12. PCOMPATIBILITY_DATA CompData;
  13. BOOL serviceDisabled = FALSE;
  14. //
  15. // iterate through all compdata structures
  16. //
  17. Next = CompatibilityData.Flink;
  18. if (Next) {
  19. while ((ULONG_PTR)Next != (ULONG_PTR)&CompatibilityData) {
  20. CompData = CONTAINING_RECORD(Next, COMPATIBILITY_DATA, ListEntry);
  21. Next = CompData->ListEntry.Flink;
  22. //
  23. // now look for services that match our service name
  24. //
  25. if (CompData->Type == TEXT('s') && lstrcmpi (CompData->ServiceName, ServiceName) == 0) {
  26. //
  27. // make sure the service is marked to be disabled
  28. //
  29. if ((CompData->RegValDataSize == sizeof (DWORD)) &&
  30. (*(PDWORD)CompData->RegValData == SERVICE_DISABLED)
  31. ) {
  32. //
  33. // we found it!
  34. //
  35. serviceDisabled = TRUE;
  36. break;
  37. }
  38. }
  39. }
  40. }
  41. return serviceDisabled;
  42. }
  43. BOOL
  44. IsDriverCopyToBeSkipped(
  45. IN PVOID NtCompatInfHandle,
  46. IN LPTSTR ServiceName,
  47. IN LPTSTR FilePath
  48. )
  49. {
  50. LONG LineCount;
  51. LONG i;
  52. LPTSTR SectionName = TEXT("DriversToSkipCopy");
  53. LPTSTR FileName;
  54. BOOL DisableCopy;
  55. if ((!NtCompatInfHandle) || (!FilePath)) {
  56. MYASSERT(FALSE);
  57. return TRUE;
  58. }
  59. FileName = _tcsrchr( FilePath, TEXT('\\') );
  60. if (!FileName) {
  61. FileName = FilePath;
  62. }
  63. else {
  64. FileName++;
  65. }
  66. //
  67. // Check if the driver is listed under [DriversToSkipCopy] in ntcompat.inf.
  68. //
  69. if( (LineCount = InfGetSectionLineCount( NtCompatInfHandle,
  70. SectionName )) == -1 ) {
  71. //
  72. // section doesn't exist.
  73. //
  74. return( FALSE );
  75. }
  76. DisableCopy = FALSE;
  77. for( i = 0; i < LineCount; i++ ) {
  78. LPTSTR p;
  79. p = (LPTSTR)InfGetFieldByIndex( NtCompatInfHandle,
  80. SectionName,
  81. i,
  82. 0 );
  83. if( p && !lstrcmpi( p, FileName ) ) {
  84. DisableCopy = TRUE;
  85. break;
  86. }
  87. }
  88. return( DisableCopy );
  89. }
  90. BOOL
  91. LoadHwdbLib (
  92. OUT HMODULE* HwdbLib,
  93. OUT PHWDB_ENTRY_POINTS HwdbEntries
  94. )
  95. {
  96. TCHAR pathSupportLib[MAX_PATH];
  97. HMODULE hwdbLib;
  98. DWORD rc;
  99. if (!FindPathToWinnt32File (S_HWDB_DLL, pathSupportLib, MAX_PATH)) {
  100. return FALSE;
  101. }
  102. hwdbLib = LoadLibraryEx (pathSupportLib, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
  103. if (!hwdbLib) {
  104. return FALSE;
  105. }
  106. HwdbEntries->HwdbInitialize = (PHWDBINITIALIZE) GetProcAddress (hwdbLib, S_HWDBAPI_HWDBINITIALIZE);
  107. HwdbEntries->HwdbTerminate = (PHWDBTERMINATE) GetProcAddress (hwdbLib, S_HWDBAPI_HWDBTERMINATE);
  108. HwdbEntries->HwdbOpen = (PHWDBOPEN) GetProcAddress (hwdbLib, S_HWDBAPI_HWDBOPEN);
  109. HwdbEntries->HwdbClose = (PHWDBCLOSE) GetProcAddress (hwdbLib, S_HWDBAPI_HWDBCLOSE);
  110. HwdbEntries->HwdbHasAnyDriver = (PHWDBHASANYDRIVER) GetProcAddress (hwdbLib, S_HWDBAPI_HWDBHASANYDRIVER);
  111. if (!HwdbEntries->HwdbInitialize ||
  112. !HwdbEntries->HwdbTerminate ||
  113. !HwdbEntries->HwdbOpen ||
  114. !HwdbEntries->HwdbClose ||
  115. !HwdbEntries->HwdbHasAnyDriver
  116. ) {
  117. ZeroMemory (HwdbEntries, sizeof (*HwdbEntries));
  118. rc = GetLastError ();
  119. FreeLibrary (hwdbLib);
  120. SetLastError (rc);
  121. return FALSE;
  122. }
  123. *HwdbLib = hwdbLib;
  124. return TRUE;
  125. }
  126. BOOL
  127. pAnyPnpIdSupported (
  128. IN PCTSTR PnpIDs
  129. )
  130. {
  131. HMODULE hwdbLib;
  132. HANDLE hwdbDatabase;
  133. HWDB_ENTRY_POINTS hwdbEntries;
  134. TCHAR hwdbPath[MAX_PATH];
  135. BOOL unsupported;
  136. BOOL b = TRUE;
  137. if (!FindPathToWinnt32File (S_HWCOMP_DAT, hwdbPath, MAX_PATH)) {
  138. DynUpdtDebugLog (Winnt32LogWarning, TEXT("%1 not found"), 0, S_HWCOMP_DAT);
  139. return b;
  140. }
  141. if (!LoadHwdbLib (&hwdbLib, &hwdbEntries)) {
  142. DebugLog (
  143. Winnt32LogWarning,
  144. TEXT("LoadHwdbLib failed (rc=%u)"),
  145. 0,
  146. GetLastError ()
  147. );
  148. return b;
  149. }
  150. if (hwdbEntries.HwdbInitialize (NULL)) {
  151. hwdbDatabase = hwdbEntries.HwdbOpen (hwdbPath);
  152. if (hwdbDatabase) {
  153. b = hwdbEntries.HwdbHasAnyDriver (hwdbDatabase, PnpIDs, &unsupported);
  154. hwdbEntries.HwdbClose (hwdbDatabase);
  155. }
  156. hwdbEntries.HwdbTerminate ();
  157. }
  158. FreeLibrary (hwdbLib);
  159. return b;
  160. }
  161. PTSTR
  162. pGetDevicePnpIDs (
  163. IN PCTSTR DeviceRegKey
  164. )
  165. {
  166. LONG rc;
  167. HKEY deviceKey;
  168. DWORD type;
  169. DWORD size1, size2;
  170. PTSTR pnpIds;
  171. PTSTR p = NULL;
  172. rc = RegOpenKeyEx (
  173. HKEY_LOCAL_MACHINE,
  174. DeviceRegKey,
  175. 0,
  176. KEY_QUERY_VALUE,
  177. &deviceKey
  178. );
  179. if (rc != ERROR_SUCCESS) {
  180. DebugLog (
  181. Winnt32LogWarning,
  182. TEXT("Failed to open device key %s (rc=%u)"),
  183. 0,
  184. DeviceRegKey,
  185. rc
  186. );
  187. return p;
  188. }
  189. __try {
  190. size1 = 0;
  191. rc = RegQueryValueEx (
  192. deviceKey,
  193. TEXT("HardwareID"),
  194. NULL,
  195. &type,
  196. NULL,
  197. &size1
  198. );
  199. if (rc == ERROR_SUCCESS) {
  200. if (type != REG_MULTI_SZ && type != REG_BINARY) {
  201. size1 = 0;
  202. DebugLog (
  203. Winnt32LogWarning,
  204. TEXT("Unexpected type of %s of %s (type=%u)"),
  205. 0,
  206. TEXT("HardwareID"),
  207. DeviceRegKey,
  208. type
  209. );
  210. }
  211. } else {
  212. DebugLog (
  213. Winnt32LogWarning,
  214. TEXT("Couldn't find value %s of %s (rc=%u)"),
  215. 0,
  216. TEXT("HardwareID"),
  217. DeviceRegKey,
  218. rc
  219. );
  220. }
  221. size2 = 0;
  222. rc = RegQueryValueEx (
  223. deviceKey,
  224. TEXT("CompatibleIDs"),
  225. NULL,
  226. &type,
  227. NULL,
  228. &size2
  229. );
  230. if (rc == ERROR_SUCCESS) {
  231. if (type != REG_MULTI_SZ && type != REG_BINARY) {
  232. size2 = 0;
  233. DebugLog (
  234. Winnt32LogWarning,
  235. TEXT("Unexpected type of %s of %s (type=%u)"),
  236. 0,
  237. TEXT("CompatibleIDs"),
  238. DeviceRegKey,
  239. type
  240. );
  241. }
  242. } else {
  243. DebugLog (
  244. Winnt32LogWarning,
  245. TEXT("Couldn't find value %s of %s (rc=%u)"),
  246. 0,
  247. TEXT("CompatibleIDs"),
  248. DeviceRegKey,
  249. rc
  250. );
  251. }
  252. if (size1 + size2 < sizeof (TCHAR)) {
  253. DebugLog (
  254. Winnt32LogWarning,
  255. TEXT("Couldn't get list of PnpIDs for %s"),
  256. 0,
  257. DeviceRegKey
  258. );
  259. __leave;
  260. }
  261. pnpIds = MALLOC (size1 + size2);
  262. if (!pnpIds) {
  263. __leave;
  264. }
  265. pnpIds[0] = 0;
  266. p = pnpIds;
  267. if (size1 >= sizeof (TCHAR)) {
  268. rc = RegQueryValueEx (
  269. deviceKey,
  270. TEXT("HardwareID"),
  271. NULL,
  272. NULL,
  273. (LPBYTE)pnpIds,
  274. &size1
  275. );
  276. if (rc == ERROR_SUCCESS) {
  277. pnpIds += size1 / sizeof (TCHAR) - 1;
  278. }
  279. }
  280. if (size2 >= sizeof (TCHAR)) {
  281. rc = RegQueryValueEx (
  282. deviceKey,
  283. TEXT("CompatibleIDs"),
  284. NULL,
  285. NULL,
  286. (LPBYTE)pnpIds,
  287. &size2
  288. );
  289. }
  290. }
  291. __finally {
  292. RegCloseKey (deviceKey);
  293. }
  294. return p;
  295. }
  296. BOOL
  297. pAllServicedDevicesSupported (
  298. IN HKEY ServiceKey
  299. )
  300. {
  301. LONG rc;
  302. HKEY enumSubKey;
  303. DWORD nextInstance;
  304. DWORD instance;
  305. TCHAR buf[20];
  306. DWORD type;
  307. DWORD size;
  308. PTSTR enumSuffixStr;
  309. HKEY deviceKey;
  310. PTSTR deviceKeyStr;
  311. PTSTR pnpIds;
  312. BOOL unsupported;
  313. BOOL b = TRUE;
  314. rc = RegOpenKeyEx (
  315. ServiceKey,
  316. TEXT("Enum"),
  317. 0,
  318. KEY_QUERY_VALUE,
  319. &enumSubKey
  320. );
  321. if (rc != ERROR_SUCCESS) {
  322. DebugLog (
  323. Winnt32LogWarning,
  324. TEXT("Failed to open Enum subkey (rc=%u)"),
  325. 0,
  326. rc
  327. );
  328. return b;
  329. }
  330. __try {
  331. size = sizeof (nextInstance);
  332. rc = RegQueryValueEx (
  333. enumSubKey,
  334. TEXT("NextInstance"),
  335. NULL,
  336. &type,
  337. (LPBYTE)&nextInstance,
  338. &size
  339. );
  340. if (rc != ERROR_SUCCESS) {
  341. DebugLog (
  342. Winnt32LogWarning,
  343. TEXT("Failed to open %s value (rc=%u)"),
  344. 0,
  345. TEXT("NextInstance"),
  346. rc
  347. );
  348. __leave;
  349. }
  350. if (type != REG_DWORD) {
  351. DebugLog (
  352. Winnt32LogWarning,
  353. TEXT("Unexpected value type for %s (type=%u)"),
  354. 0,
  355. TEXT("NextInstance"),
  356. type
  357. );
  358. __leave;
  359. }
  360. for (instance = 0; b && instance < nextInstance; instance++) {
  361. wsprintf (buf, TEXT("%lu"), instance);
  362. rc = RegQueryValueEx (
  363. enumSubKey,
  364. buf,
  365. NULL,
  366. &type,
  367. NULL,
  368. &size
  369. );
  370. if (rc != ERROR_SUCCESS || type != REG_SZ) {
  371. continue;
  372. }
  373. enumSuffixStr = MALLOC (size);
  374. if (!enumSuffixStr) {
  375. __leave;
  376. }
  377. rc = RegQueryValueEx (
  378. enumSubKey,
  379. buf,
  380. NULL,
  381. NULL,
  382. (LPBYTE)enumSuffixStr,
  383. &size
  384. );
  385. if (rc == ERROR_SUCCESS) {
  386. size = sizeof ("SYSTEM\\CurrentControlSet\\Enum") + lstrlen (enumSuffixStr) + 1;
  387. deviceKeyStr = MALLOC (size * sizeof (TCHAR));
  388. if (!deviceKeyStr) {
  389. __leave;
  390. }
  391. BuildPathEx (deviceKeyStr, size, TEXT("SYSTEM\\CurrentControlSet\\Enum"), enumSuffixStr);
  392. pnpIds = pGetDevicePnpIDs (deviceKeyStr);
  393. FREE (deviceKeyStr);
  394. if (!pAnyPnpIdSupported (pnpIds)) {
  395. b = FALSE;
  396. }
  397. FREE (pnpIds);
  398. }
  399. FREE (enumSuffixStr);
  400. }
  401. }
  402. __finally {
  403. RegCloseKey (enumSubKey);
  404. }
  405. return b;
  406. }
  407. BOOL
  408. IsInfInLayoutInf(
  409. IN PCTSTR InfPath
  410. )
  411. /*++
  412. Routine Description:
  413. Determine if an INF file is shiped in-box with the operating system.
  414. This is acomplished by looking up the INF name in the [SourceDisksFiles]
  415. section of layout.inf
  416. Arguments:
  417. InfPath - supplies name (may include path) of INF. No checking is done
  418. to ensure INF lives in %windir%\Inf--this is caller's responsibility.
  419. Return Value:
  420. If TRUE, this is an in-box INF. If FALSE, it's not an in-box INF, this
  421. could be an OEM<n>.INF or an inf illegaly copied into the INF directory.
  422. --*/
  423. {
  424. BOOL bInBoxInf = FALSE;
  425. HINF hInf = INVALID_HANDLE_VALUE;
  426. UINT SourceId;
  427. PCTSTR infFileName;
  428. if (SetupapiGetSourceFileLocation) {
  429. hInf = SetupapiOpenInfFile(TEXT("layout.inf"), NULL, INF_STYLE_WIN4, NULL);
  430. if (hInf != INVALID_HANDLE_VALUE) {
  431. infFileName = _tcsrchr(InfPath, TEXT('\\') );
  432. if (infFileName) {
  433. infFileName++;
  434. } else {
  435. infFileName = InfPath;
  436. }
  437. if(SetupapiGetSourceFileLocation(hInf,
  438. NULL,
  439. infFileName,
  440. &SourceId,
  441. NULL,
  442. 0,
  443. NULL)) {
  444. bInBoxInf = TRUE;
  445. }
  446. SetupapiCloseInfFile(hInf);
  447. }
  448. }
  449. return bInBoxInf;
  450. }
  451. BOOL
  452. pIsOEMService (
  453. IN PCTSTR ServiceKeyName,
  454. OUT PTSTR OemInfPath, OPTIONAL
  455. IN INT BufferSize OPTIONAL
  456. )
  457. {
  458. ULONG BufferLen = 0;
  459. PTSTR Buffer = NULL;
  460. PTSTR p;
  461. DEVNODE DevNode;
  462. CONFIGRET cr;
  463. HKEY hKey;
  464. TCHAR InfPath[MAX_PATH];
  465. DWORD dwType, dwSize;
  466. BOOL IsOemService = FALSE;
  467. //
  468. // See how larger of a buffer we need to hold the list of device
  469. // instance Ids for this service.
  470. //
  471. cr = CM_Get_Device_ID_List_Size(&BufferLen,
  472. ServiceKeyName,
  473. CM_GETIDLIST_FILTER_SERVICE);
  474. if (cr != CR_SUCCESS) {
  475. //
  476. // Encountered an error so just bail out.
  477. //
  478. goto clean0;
  479. }
  480. if (BufferLen == 0) {
  481. //
  482. // No devices are using this service, so just bail out.
  483. //
  484. goto clean0;
  485. }
  486. Buffer = MALLOC(BufferLen*sizeof(TCHAR));
  487. if (Buffer == NULL) {
  488. goto clean0;
  489. }
  490. //
  491. // Get the list of device instance Ids for this service.
  492. //
  493. cr = CM_Get_Device_ID_List(ServiceKeyName,
  494. Buffer,
  495. BufferLen,
  496. CM_GETIDLIST_FILTER_SERVICE | CM_GETIDLIST_DONOTGENERATE);
  497. if (cr != CR_SUCCESS) {
  498. //
  499. // failed to get the list of devices for this service.
  500. //
  501. goto clean0;
  502. }
  503. //
  504. // Enumerate through the list of devices using this service.
  505. //
  506. for (p = Buffer; !IsOemService && *p; p += (lstrlen(p) + 1)) {
  507. //
  508. // Get a DevNode from the device instance Id.
  509. //
  510. cr = CM_Locate_DevNode(&DevNode, p, 0);
  511. if (cr != CR_SUCCESS) {
  512. continue;
  513. }
  514. //
  515. // Open the device's SOFTWARE key so we can get it's INF path.
  516. //
  517. cr = CM_Open_DevNode_Key(DevNode,
  518. KEY_READ,
  519. 0,
  520. RegDisposition_OpenExisting,
  521. &hKey,
  522. CM_REGISTRY_SOFTWARE);
  523. if (cr != CR_SUCCESS) {
  524. //
  525. // Software key doesn't exist?
  526. //
  527. continue;
  528. }
  529. dwType = REG_SZ;
  530. dwSize = sizeof(InfPath);
  531. if (RegQueryValueEx(hKey,
  532. REGSTR_VAL_INFPATH,
  533. NULL,
  534. &dwType,
  535. (LPBYTE)InfPath,
  536. &dwSize) != ERROR_SUCCESS) {
  537. //
  538. // If there is no InfPath in the SOFTWARE key then we don't know
  539. // what INF this device is using.
  540. //
  541. RegCloseKey(hKey);
  542. continue;
  543. }
  544. if (!IsInfInLayoutInf(InfPath)) {
  545. IsOemService = TRUE;
  546. if (OemInfPath) {
  547. StringCchCopy (OemInfPath, BufferSize, InfPath);
  548. }
  549. }
  550. RegCloseKey(hKey);
  551. }
  552. clean0:
  553. if (Buffer) {
  554. FREE(Buffer);
  555. }
  556. return IsOemService;
  557. }
  558. BOOL
  559. IsDeviceSupported(
  560. IN PVOID TxtsetupSifHandle,
  561. IN HKEY ServiceKey,
  562. IN LPTSTR ServiceKeyName,
  563. OUT LPTSTR FileName,
  564. IN INT CchFileName
  565. )
  566. {
  567. ULONG Error;
  568. ULONG Type;
  569. BYTE Buffer[ (MAX_PATH + 1)*sizeof(TCHAR) ];
  570. PBYTE Data;
  571. ULONG cbData;
  572. BOOL b = TRUE;
  573. LPTSTR DriverPath;
  574. LPTSTR DriverName;
  575. LONG LineCount;
  576. LONG i;
  577. BOOL DeviceSupported;
  578. Data = Buffer;
  579. cbData = sizeof( Buffer );
  580. Error = RegQueryValueEx( ServiceKey,
  581. TEXT("ImagePath"),
  582. NULL,
  583. &Type,
  584. Data,
  585. &cbData );
  586. if( (Error == ERROR_PATH_NOT_FOUND) ||
  587. (Error == ERROR_FILE_NOT_FOUND) ) {
  588. //
  589. // ImagePath does not exist.
  590. // In this case the driver name is <service name>.sys
  591. //
  592. StringCbCopy((PTSTR)Buffer, sizeof(Buffer), ServiceKeyName );
  593. StringCbCat((PTSTR)Buffer, sizeof(Buffer), TEXT(".sys") );
  594. Error = ERROR_SUCCESS;
  595. }
  596. if( Error == ERROR_MORE_DATA ) {
  597. Data = (PBYTE)MALLOC( cbData );
  598. if( Data == NULL ) {
  599. //
  600. // We failed the malloc. Just assume the device
  601. // isn't supported.
  602. //
  603. return( FALSE );
  604. }
  605. Error = RegQueryValueEx( ServiceKey,
  606. TEXT("ImagePath"),
  607. NULL,
  608. &Type,
  609. Data,
  610. &cbData );
  611. }
  612. if( Error != ERROR_SUCCESS ) {
  613. //
  614. // We can' retrieve the drivers information.
  615. // Assume that the device is supported
  616. //
  617. if( Data != Buffer ) {
  618. FREE( Data );
  619. }
  620. return( TRUE );
  621. }
  622. DriverPath = (LPTSTR)Data;
  623. DriverName = _tcsrchr( DriverPath, TEXT('\\') );
  624. if( DriverName != NULL ) {
  625. DriverName++;
  626. } else {
  627. DriverName = DriverPath;
  628. }
  629. //
  630. // Search for the driver name on the following sections of txtsetup.sif:
  631. // [SCSI.load]
  632. //
  633. if( (LineCount = InfGetSectionLineCount( TxtsetupSifHandle,
  634. TEXT("SCSI.load") )) == -1 ) {
  635. //
  636. // We can't retrieve the drivers information.
  637. // Assume that the device is supported
  638. //
  639. if( Data != Buffer ) {
  640. FREE( Data );
  641. }
  642. return( TRUE );
  643. }
  644. DeviceSupported = FALSE;
  645. for( i = 0; i < LineCount; i++ ) {
  646. LPTSTR p;
  647. p = (LPTSTR)InfGetFieldByIndex( TxtsetupSifHandle,
  648. TEXT("SCSI.load"),
  649. i,
  650. 0 );
  651. if( p == NULL ) {
  652. continue;
  653. }
  654. if( !lstrcmpi( p, DriverName ) ) {
  655. DeviceSupported = TRUE;
  656. break;
  657. }
  658. }
  659. //
  660. // NTBUG9: 505624
  661. // verify if there is inbox support for ALL devices
  662. // currently supported by this driver
  663. // If there's any that doesn't have support,
  664. // then the OEM driver must be migrated
  665. //
  666. if (DeviceSupported) {
  667. if (pIsOEMService (ServiceKeyName, NULL, 0)) {
  668. if (!pAllServicedDevicesSupported (ServiceKey)) {
  669. DeviceSupported = FALSE;
  670. }
  671. }
  672. }
  673. #if defined(_AMD64_) || defined(_X86_)
  674. //
  675. // one more thing: check if this device is supplied by OEMs via answer file (NTBUG9: 306041)
  676. //
  677. if (!DeviceSupported) {
  678. POEM_BOOT_FILE p;
  679. for (p = OemBootFiles; p; p = p->Next) {
  680. if (!lstrcmpi (p->Filename, DriverName)) {
  681. DeviceSupported = TRUE;
  682. break;
  683. }
  684. }
  685. }
  686. #endif
  687. if( !DeviceSupported ) {
  688. LPTSTR q;
  689. CharLower( DriverPath );
  690. q = _tcsstr( DriverPath, TEXT("system32") );
  691. //Note, since this entire function (IsDeviceSupported) is only called in
  692. //one place, we assume the FileName pointer points to a buffer of size MAX_PATH
  693. if( q == NULL ) {
  694. StringCchCopy( FileName, CchFileName, TEXT("system32\\drivers\\") );
  695. StringCchCat( FileName, CchFileName, DriverName );
  696. } else {
  697. StringCchCopy( FileName, CchFileName, q );
  698. }
  699. }
  700. if( Data != Buffer ) {
  701. FREE( Data );
  702. }
  703. return( DeviceSupported );
  704. }
  705. VOID
  706. FreeHardwareIdList(
  707. IN PUNSUPORTED_PNP_HARDWARE_ID HardwareIdList
  708. )
  709. {
  710. PUNSUPORTED_PNP_HARDWARE_ID p, q;
  711. p = HardwareIdList;
  712. while( p != NULL ) {
  713. FREE( p->Id );
  714. FREE( p->Service );
  715. FREE( p->ClassGuid );
  716. q = p->Next;
  717. FREE( p );
  718. p = q;
  719. }
  720. }
  721. VOID
  722. FreeFileInfoList(
  723. IN PUNSUPORTED_DRIVER_FILE_INFO FileInfoList
  724. )
  725. {
  726. PUNSUPORTED_DRIVER_FILE_INFO p, q;
  727. p = FileInfoList;
  728. while( p != NULL ) {
  729. FREE( p->FileName );
  730. FREE( p->TargetDirectory );
  731. q = p->Next;
  732. FREE( p );
  733. p = q;
  734. }
  735. }
  736. VOID
  737. FreeInstallInfoList(
  738. IN PUNSUPORTED_DRIVER_INSTALL_INFO InstallInfoList
  739. )
  740. {
  741. PUNSUPORTED_DRIVER_INSTALL_INFO p, q;
  742. p = InstallInfoList;
  743. while( p != NULL ) {
  744. FREE( p->InfRelPath );
  745. FREE( p->InfFileName );
  746. FREE( p->InfOriginalFileName );
  747. if (p->CatalogRelPath) {
  748. FREE(p->CatalogRelPath);
  749. }
  750. if (p->CatalogFileName) {
  751. FREE(p->CatalogFileName);
  752. }
  753. if (p->CatalogOriginalFileName) {
  754. FREE(p->CatalogOriginalFileName);
  755. }
  756. q = p->Next;
  757. FREE( p );
  758. p = q;
  759. }
  760. }
  761. VOID
  762. FreeRegistryInfoList(
  763. IN PUNSUPORTED_DRIVER_REGKEY_INFO RegistryInfoList
  764. )
  765. {
  766. PUNSUPORTED_DRIVER_REGKEY_INFO p, q;
  767. p = RegistryInfoList;
  768. while( p != NULL ) {
  769. FREE( p->KeyPath );
  770. q = p->Next;
  771. FREE( p );
  772. p = q;
  773. }
  774. }
  775. BOOL
  776. BuildHardwareIdInfo(
  777. IN LPTSTR ServiceName,
  778. OUT PUNSUPORTED_PNP_HARDWARE_ID* HardwareIdList
  779. )
  780. {
  781. ULONG BufferLen;
  782. DEVNODE DevNode;
  783. PTSTR Buffer, Service, Id, HwId, DevId;
  784. PBYTE Value;
  785. ULONG ValueSize;
  786. PUNSUPORTED_PNP_HARDWARE_ID TempList, Entry;
  787. BOOL Result;
  788. DWORD Type;
  789. if (CM_Get_Device_ID_List_Size(&BufferLen,
  790. ServiceName,
  791. CM_GETIDLIST_FILTER_SERVICE
  792. ) != CR_SUCCESS ||
  793. (BufferLen == 0)) {
  794. return ( FALSE );
  795. }
  796. Result = TRUE;
  797. Value = NULL;
  798. TempList = NULL;
  799. Buffer = MALLOC(BufferLen * sizeof(TCHAR));
  800. if (Buffer == NULL) {
  801. Result = FALSE;
  802. goto Clean;
  803. }
  804. ValueSize = REGSTR_VAL_MAX_HCID_LEN * sizeof(TCHAR);
  805. Value = MALLOC(ValueSize);
  806. if (Value == NULL) {
  807. Result = FALSE;
  808. goto Clean;
  809. }
  810. if (CM_Get_Device_ID_List(ServiceName,
  811. Buffer,
  812. BufferLen,
  813. CM_GETIDLIST_FILTER_SERVICE | CM_GETIDLIST_DONOTGENERATE
  814. ) != CR_SUCCESS) {
  815. Result = FALSE;
  816. goto Clean;
  817. }
  818. for (DevId = Buffer; *DevId; DevId += lstrlen(DevId) + 1) {
  819. if (CM_Locate_DevNode(&DevNode, DevId, 0) == CR_SUCCESS) {
  820. ValueSize = REGSTR_VAL_MAX_HCID_LEN * sizeof(TCHAR);
  821. if (CM_Get_DevNode_Registry_Property(DevNode, CM_DRP_HARDWAREID, &Type, Value, &ValueSize, 0) == CR_SUCCESS &&
  822. Type == REG_MULTI_SZ) {
  823. for( HwId = (PTSTR)Value;
  824. ( (ULONG_PTR)HwId < (ULONG_PTR)(Value + ValueSize) ) && ( lstrlen( HwId ) );
  825. HwId += lstrlen( HwId ) + 1 ) {
  826. Entry = MALLOC( sizeof( UNSUPORTED_PNP_HARDWARE_ID ) );
  827. Id = DupString( HwId );
  828. Service = DupString( ServiceName );
  829. if( (Entry == NULL) || (Id == NULL) || (Service == NULL) ) {
  830. if( Entry != NULL ) {
  831. FREE( Entry );
  832. }
  833. if( Id != NULL ) {
  834. FREE( Id );
  835. }
  836. if( Service != NULL ) {
  837. FREE( Service );
  838. }
  839. Result = FALSE;
  840. goto Clean;
  841. }
  842. //
  843. // Add the new entry to the front of the list.
  844. //
  845. Entry->Id = Id;
  846. Entry->Service = Service;
  847. Entry->ClassGuid = NULL;
  848. Entry->Next = TempList;
  849. TempList = Entry;
  850. }
  851. }
  852. }
  853. }
  854. Clean:
  855. if ( Buffer ) {
  856. FREE( Buffer );
  857. }
  858. if ( Value ) {
  859. FREE( Value );
  860. }
  861. if (Result == TRUE) {
  862. *HardwareIdList = TempList;
  863. } else if ( TempList ) {
  864. FreeHardwareIdList( TempList );
  865. }
  866. return ( Result );
  867. }
  868. BOOL
  869. BuildDriverFileInformation(
  870. IN LPTSTR FilePath,
  871. OUT PUNSUPORTED_DRIVER_FILE_INFO* FileInfo
  872. )
  873. {
  874. TCHAR FullPath[ MAX_PATH + 1 ];
  875. LPTSTR p, q, r;
  876. PUNSUPORTED_DRIVER_FILE_INFO TempFileInfo = NULL;
  877. *FileInfo = NULL;
  878. StringCchCopy( FullPath, ARRAYSIZE(FullPath), FilePath );
  879. p = _tcsrchr( FullPath, TEXT('\\') );
  880. if(!p)
  881. return FALSE;
  882. *p = TEXT('\0');
  883. p++;
  884. q = DupString( FullPath );
  885. r = DupString( p );
  886. TempFileInfo = MALLOC( sizeof( UNSUPORTED_DRIVER_FILE_INFO ) );
  887. if( ( q == NULL ) || ( r == NULL ) || ( TempFileInfo == NULL ) ) {
  888. goto clean0;
  889. }
  890. TempFileInfo->Next = NULL;
  891. TempFileInfo->FileName = r;
  892. TempFileInfo->TargetDirectory = q;
  893. *FileInfo = TempFileInfo;
  894. return( TRUE );
  895. clean0:
  896. if( q != NULL ) {
  897. FREE( q );
  898. }
  899. if( r != NULL ) {
  900. FREE( r );
  901. }
  902. if( TempFileInfo != NULL ) {
  903. FREE( TempFileInfo );
  904. }
  905. return( FALSE );
  906. }
  907. BOOL
  908. pDoesCatalogExist (
  909. IN PTSTR CatalogPath,
  910. IN PTSTR CatName
  911. )
  912. {
  913. TCHAR path[MAX_PATH];
  914. return BuildPath(path, CatalogPath, CatName) && FileExists (path, NULL);
  915. }
  916. BOOL
  917. BuildDriverInstallInformation(
  918. IN LPTSTR ServiceKeyName,
  919. OUT PUNSUPORTED_DRIVER_INSTALL_INFO* InstallInfo
  920. )
  921. {
  922. TCHAR infName[MAX_PATH];
  923. TCHAR catName[MAX_PATH];
  924. TCHAR infPath[MAX_PATH];
  925. TCHAR catalogPath[MAX_PATH];
  926. LPTSTR p, q, r, s, t, u;
  927. PUNSUPORTED_DRIVER_INSTALL_INFO TempInstallInfo = NULL;
  928. DWORD size;
  929. PSP_INF_INFORMATION info;
  930. SP_ORIGINAL_FILE_INFO ofi;
  931. BOOL b = FALSE;
  932. if (BUILDNUM() >= NT51) {
  933. return TRUE;
  934. }
  935. if (!pIsOEMService (ServiceKeyName, infName, ARRAYSIZE(infName))) {
  936. return TRUE;
  937. }
  938. if (!SetupapiGetInfInformation (infName, INFINFO_DEFAULT_SEARCH, NULL, 0, &size)) {
  939. return FALSE;
  940. }
  941. info = (PSP_INF_INFORMATION) MALLOC(size);
  942. if (!info) {
  943. return FALSE;
  944. }
  945. __try {
  946. if (!SetupapiGetInfInformation (infName, INFINFO_DEFAULT_SEARCH, info, size, NULL)) {
  947. __leave;
  948. }
  949. if (!SetupapiQueryInfFileInformation (info, 0, infPath, ARRAYSIZE(infPath), NULL)) {
  950. __leave;
  951. }
  952. //
  953. // the INF is supposed to be under %windir%
  954. // reuse a buffer
  955. //
  956. size = MyGetWindowsDirectory (catalogPath, ARRAYSIZE(catalogPath));
  957. if (!size || size >= ARRAYSIZE(catalogPath)) {
  958. __leave;
  959. }
  960. if (_tcsnicmp (infPath, catalogPath, size) || infPath[size] != TEXT('\\')) {
  961. __leave;
  962. }
  963. //
  964. // then cut the %windir% part and the filename
  965. //
  966. p = _tcsrchr (infPath, TEXT('\\'));
  967. if (!p) {
  968. __leave;
  969. }
  970. *p = 0;
  971. MoveMemory (infPath, infPath + size + 1, (p + 1 - (infPath + size + 1)) * sizeof (TCHAR));
  972. ofi.cbSize = sizeof(ofi);
  973. if (!SetupapiQueryInfOriginalFileInformation ||
  974. !SetupapiQueryInfOriginalFileInformation (info, 0, NULL, &ofi)) {
  975. //
  976. // use the current INF name
  977. //
  978. StringCchCopy (ofi.OriginalInfName, ARRAYSIZE(ofi.OriginalInfName), infName);
  979. ofi.OriginalCatalogName[0] = 0;
  980. }
  981. b = TRUE;
  982. }
  983. __finally {
  984. FREE(info);
  985. }
  986. if (!b) {
  987. return b;
  988. }
  989. if (ofi.OriginalCatalogName[0]) {
  990. //
  991. // get actual catalog name
  992. //
  993. lstrcpy (catName, infName);
  994. p = _tcsrchr (catName, TEXT('.'));
  995. if (!p) {
  996. p = _tcsrchr (catName, 0);
  997. }
  998. if (FAILED(StringCchCopy (p, catName + ARRAYSIZE(catName) - p, TEXT(".cat")))) {
  999. return FALSE;
  1000. }
  1001. //
  1002. // get actual catalog location under %systemroot%
  1003. //
  1004. lstrcpy (catalogPath, TEXT("system32\\CatRoot\\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}"));
  1005. //
  1006. // check if the catalog actually exists
  1007. //
  1008. if (!pDoesCatalogExist (catalogPath, catName)) {
  1009. //
  1010. // just ignore it; driver will be treated as unsigned
  1011. //
  1012. ofi.OriginalCatalogName[0] = 0;
  1013. }
  1014. }
  1015. if (!ofi.OriginalCatalogName[0]) {
  1016. catName[0] = 0;
  1017. catalogPath[0] = 0;
  1018. }
  1019. //
  1020. // add the OEM .INF and .CAT files to the list
  1021. //
  1022. *InstallInfo = NULL;
  1023. p = DupString(infPath);
  1024. q = DupString(infName);
  1025. r = DupString(ofi.OriginalInfName);
  1026. s = catalogPath[0] ? DupString(catalogPath) : NULL;
  1027. t = catName[0] ? DupString(catName) : NULL;
  1028. u = ofi.OriginalCatalogName[0] ? DupString(ofi.OriginalCatalogName) : NULL;
  1029. TempInstallInfo = MALLOC( sizeof( UNSUPORTED_DRIVER_INSTALL_INFO ) );
  1030. if(!(p && q && r &&
  1031. (!catalogPath[0] || s) && (!catName[0] || t) && (!ofi.OriginalCatalogName[0] || u) && TempInstallInfo)) {
  1032. goto clean0;
  1033. }
  1034. TempInstallInfo->Next = NULL;
  1035. TempInstallInfo->InfRelPath = p;
  1036. TempInstallInfo->InfFileName = q;
  1037. TempInstallInfo->InfOriginalFileName = r;
  1038. TempInstallInfo->CatalogRelPath = s;
  1039. TempInstallInfo->CatalogFileName = t;
  1040. TempInstallInfo->CatalogOriginalFileName = u;
  1041. *InstallInfo = TempInstallInfo;
  1042. return( TRUE );
  1043. clean0:
  1044. if( q != NULL ) {
  1045. FREE( q );
  1046. }
  1047. if( r != NULL ) {
  1048. FREE( r );
  1049. }
  1050. if( s != NULL ) {
  1051. FREE( s );
  1052. }
  1053. if( t != NULL ) {
  1054. FREE( t );
  1055. }
  1056. if( u != NULL ) {
  1057. FREE( u );
  1058. }
  1059. if( TempInstallInfo != NULL ) {
  1060. FREE( TempInstallInfo );
  1061. }
  1062. return( FALSE );
  1063. }
  1064. BOOL
  1065. BuildDriverRegistryInformation(
  1066. IN LPTSTR ServiceName,
  1067. OUT PUNSUPORTED_DRIVER_REGKEY_INFO* RegInfo
  1068. )
  1069. {
  1070. TCHAR KeyPath[ MAX_PATH + 1 ];
  1071. LPTSTR p=NULL;
  1072. PUNSUPORTED_DRIVER_REGKEY_INFO TempRegInfo = NULL;
  1073. *RegInfo = NULL;
  1074. StringCchCopy( KeyPath, ARRAYSIZE(KeyPath), TEXT( "SYSTEM\\CurrentControlSet\\Services\\" ) );
  1075. if (FAILED(StringCchCat( KeyPath, ARRAYSIZE(KeyPath), ServiceName ))) {
  1076. goto clean0;
  1077. }
  1078. p = DupString( KeyPath );
  1079. TempRegInfo = MALLOC( sizeof( UNSUPORTED_DRIVER_REGKEY_INFO ) );
  1080. if( ( p == NULL ) || ( TempRegInfo == NULL ) ) {
  1081. goto clean0;
  1082. }
  1083. TempRegInfo->Next = NULL;
  1084. TempRegInfo->PredefinedKey = HKEY_LOCAL_MACHINE;
  1085. TempRegInfo->KeyPath = p;
  1086. TempRegInfo->MigrateVolatileKeys = FALSE;
  1087. *RegInfo = TempRegInfo;
  1088. return( TRUE );
  1089. clean0:
  1090. if( p != NULL ) {
  1091. FREE( p );
  1092. }
  1093. if( TempRegInfo != NULL ) {
  1094. FREE( TempRegInfo );
  1095. }
  1096. return( FALSE );
  1097. }
  1098. VOID
  1099. FreeDriverInformationList(
  1100. IN OUT PUNSUPORTED_DRIVER_INFO* DriverInfo
  1101. )
  1102. {
  1103. while( *DriverInfo != NULL ) {
  1104. PUNSUPORTED_DRIVER_INFO p;
  1105. p = *DriverInfo;
  1106. *DriverInfo = p->Next;
  1107. if( p->DriverId != NULL ) {
  1108. FREE( p->DriverId );
  1109. }
  1110. if( p->KeyList != NULL ) {
  1111. FreeRegistryInfoList( p->KeyList );
  1112. }
  1113. if( p->FileList != NULL ) {
  1114. FreeFileInfoList( p->FileList );
  1115. }
  1116. if (p->InstallList) {
  1117. FreeInstallInfoList (p->InstallList);
  1118. }
  1119. if( p-> HardwareIdsList != NULL ) {
  1120. FreeHardwareIdList( p-> HardwareIdsList );
  1121. }
  1122. FREE( p );
  1123. }
  1124. *DriverInfo = NULL;
  1125. }
  1126. BOOL
  1127. BuildDriverInformation(
  1128. IN HKEY ServiceKey,
  1129. IN LPTSTR ServiceName,
  1130. IN LPTSTR FilePath,
  1131. OUT PUNSUPORTED_DRIVER_INFO* DriverInfo
  1132. )
  1133. {
  1134. ULONG Error;
  1135. BOOL b1, b2, b3, b4;
  1136. PUNSUPORTED_PNP_HARDWARE_ID TempIdInfo = NULL;
  1137. PUNSUPORTED_DRIVER_INFO TempFiltersInfo = NULL;
  1138. PUNSUPORTED_DRIVER_FILE_INFO TempFileInfo = NULL;
  1139. PUNSUPORTED_DRIVER_INSTALL_INFO TempInstallInfo = NULL;
  1140. PUNSUPORTED_DRIVER_REGKEY_INFO TempRegInfo = NULL;
  1141. PUNSUPORTED_DRIVER_INFO TempDriverInfo = NULL;
  1142. *DriverInfo = NULL;
  1143. //
  1144. // Get hardware id info
  1145. //
  1146. b1 = BuildHardwareIdInfo( ServiceName,
  1147. &TempIdInfo );
  1148. //
  1149. // Then get the file information
  1150. //
  1151. b2 = BuildDriverFileInformation( FilePath,
  1152. &TempFileInfo );
  1153. //
  1154. // Then get the install (INF&CAT) information
  1155. //
  1156. b3 = BuildDriverInstallInformation(ServiceName,
  1157. &TempInstallInfo );
  1158. //
  1159. // Then get the registry information
  1160. //
  1161. b4 = BuildDriverRegistryInformation( ServiceName,
  1162. &TempRegInfo );
  1163. if( !b1 || !b2 || !b3 || !b4) {
  1164. goto cleanup1;
  1165. }
  1166. TempDriverInfo = MALLOC( sizeof( UNSUPORTED_DRIVER_INFO ) );
  1167. if( TempDriverInfo == NULL ) {
  1168. goto cleanup1;
  1169. }
  1170. TempDriverInfo->Next = NULL;
  1171. TempDriverInfo->DriverId = DupString( ServiceName );
  1172. TempDriverInfo->KeyList = TempRegInfo;
  1173. TempDriverInfo->FileList = TempFileInfo;
  1174. TempDriverInfo->InstallList = TempInstallInfo;
  1175. TempDriverInfo->HardwareIdsList = TempIdInfo;
  1176. TempDriverInfo->Next = *DriverInfo;
  1177. *DriverInfo = TempDriverInfo;
  1178. return( TRUE );
  1179. cleanup1:
  1180. if( TempIdInfo != NULL ) {
  1181. FreeHardwareIdList( TempIdInfo );
  1182. }
  1183. if( TempFileInfo != NULL ) {
  1184. FreeFileInfoList( TempFileInfo );
  1185. }
  1186. if( TempInstallInfo != NULL ) {
  1187. FreeInstallInfoList( TempInstallInfo );
  1188. }
  1189. if( TempRegInfo != NULL ) {
  1190. FreeRegistryInfoList( TempRegInfo );
  1191. }
  1192. return( FALSE );
  1193. }
  1194. BOOL
  1195. BuildUnsupportedDriverList(
  1196. IN PVOID TxtsetupSifHandle,
  1197. OUT PUNSUPORTED_DRIVER_INFO* DriverList
  1198. )
  1199. {
  1200. ULONG Error;
  1201. HKEY ScsiKey;
  1202. ULONG SubKeys;
  1203. ULONG i;
  1204. LPTSTR szScsiPath = TEXT("HARDWARE\\DEVICEMAP\\Scsi");
  1205. *DriverList = NULL;
  1206. //
  1207. // Find out if there is a SCSI miniport driver on this machine.
  1208. //
  1209. Error = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  1210. szScsiPath,
  1211. 0,
  1212. KEY_READ,
  1213. &ScsiKey );
  1214. if( Error != ERROR_SUCCESS ) {
  1215. //
  1216. // Nothing to migrate
  1217. //
  1218. return( TRUE );
  1219. }
  1220. //
  1221. // Find out the number of subkeys under HKLM\HARDWARE\DEVICEMAP\Scsi.
  1222. //
  1223. Error = RegQueryInfoKey ( ScsiKey,
  1224. NULL,
  1225. NULL,
  1226. NULL,
  1227. &SubKeys,
  1228. NULL,
  1229. NULL,
  1230. NULL,
  1231. NULL,
  1232. NULL,
  1233. NULL,
  1234. NULL );
  1235. if( (Error != ERROR_SUCCESS) || (SubKeys == 0) ) {
  1236. //
  1237. // If we can't determine the number of subkeys, or if there is no
  1238. // subkey, then there is nothing to migrate, and we assume that all
  1239. // SCSI drivers are supported on NT.
  1240. //
  1241. RegCloseKey( ScsiKey );
  1242. return( TRUE );
  1243. }
  1244. //
  1245. // Each subkey of HKLM\HARDWARE\DEVICEMAP\Scsi points to a service that controls
  1246. // a SCSI device. We check each one of them to find out the ones that are controlled
  1247. // by a driver that is not on the NT product.
  1248. //
  1249. for( i = 0; i < SubKeys; i++ ) {
  1250. TCHAR SubKeyName[ MAX_PATH + 1 ];
  1251. TCHAR ServiceKeyPath[ MAX_PATH + 1 ];
  1252. ULONG Length;
  1253. FILETIME LastWriteTime;
  1254. HKEY Key;
  1255. BYTE Data[ 512 ];
  1256. ULONG DataSize;
  1257. ULONG Type;
  1258. PUNSUPORTED_DRIVER_INFO DriverInfo, p;
  1259. BOOL DeviceAlreadyFound;
  1260. TCHAR FilePath[ MAX_PATH + 1 ];
  1261. Length = sizeof( SubKeyName ) / sizeof( TCHAR );
  1262. Error = RegEnumKeyEx( ScsiKey,
  1263. i,
  1264. SubKeyName,
  1265. &Length,
  1266. NULL,
  1267. NULL,
  1268. NULL,
  1269. &LastWriteTime );
  1270. if( Error != ERROR_SUCCESS ) {
  1271. //
  1272. // Ignore this device and assume it is supported.
  1273. //
  1274. continue;
  1275. }
  1276. Error = RegOpenKeyEx( ScsiKey,
  1277. SubKeyName,
  1278. 0,
  1279. KEY_READ,
  1280. &Key );
  1281. if( Error != ERROR_SUCCESS ) {
  1282. //
  1283. // Ignore this device and assume it is supported.
  1284. //
  1285. continue;
  1286. }
  1287. DataSize = sizeof( Data );
  1288. Error = RegQueryValueEx( Key,
  1289. TEXT("Driver"),
  1290. NULL,
  1291. &Type,
  1292. Data,
  1293. &DataSize );
  1294. if( Error != ERROR_SUCCESS ) {
  1295. //
  1296. // Ignore this device and assume it is supported.
  1297. //
  1298. RegCloseKey( Key );
  1299. continue;
  1300. }
  1301. RegCloseKey( Key );
  1302. //
  1303. // Find out if this device is supported on NT 5.0
  1304. //
  1305. StringCchCopy( ServiceKeyPath, ARRAYSIZE(ServiceKeyPath), TEXT("SYSTEM\\CurrentControlSet\\Services\\" ) );
  1306. if (FAILED(StringCchCat( ServiceKeyPath, ARRAYSIZE(ServiceKeyPath), (LPTSTR)Data )))
  1307. {
  1308. //
  1309. // Assume it is supported, since there is nothing else we can do here.
  1310. //
  1311. continue;
  1312. }
  1313. Error = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  1314. ServiceKeyPath,
  1315. 0,
  1316. KEY_READ,
  1317. &Key );
  1318. if( Error != ERROR_SUCCESS ) {
  1319. //
  1320. // Assume it is supported, since there is nothing else we can do here.
  1321. //
  1322. continue;
  1323. }
  1324. if( IsDeviceSupported( TxtsetupSifHandle,
  1325. Key,
  1326. (LPTSTR)Data,
  1327. FilePath,
  1328. ARRAYSIZE(FilePath)
  1329. ) ) {
  1330. RegCloseKey( Key );
  1331. continue;
  1332. }
  1333. //
  1334. // Find out if this device is already in our list
  1335. //
  1336. DeviceAlreadyFound = FALSE;
  1337. for( p = (PUNSUPORTED_DRIVER_INFO)*DriverList; p && !DeviceAlreadyFound; p = p->Next ) {
  1338. if( !lstrcmpi( p->DriverId, (LPTSTR)Data ) ) {
  1339. DeviceAlreadyFound = TRUE;
  1340. }
  1341. }
  1342. if( DeviceAlreadyFound ) {
  1343. RegCloseKey( Key );
  1344. continue;
  1345. }
  1346. //
  1347. // Find out if the device is listed in the section [ServicesToDisable] in dosnet.inf
  1348. //
  1349. if( IsServiceToBeDisabled( NtcompatInf,
  1350. (LPTSTR)Data ) ) {
  1351. RegCloseKey( Key );
  1352. continue;
  1353. }
  1354. //
  1355. // Find out if the file is listed in the [DriversToSkipCopy] section in
  1356. // ntcompat.inf.
  1357. //
  1358. if( IsDriverCopyToBeSkipped( NtcompatInf,
  1359. (LPTSTR)Data,
  1360. FilePath ) ) {
  1361. RegCloseKey( Key );
  1362. continue;
  1363. }
  1364. //
  1365. // The driver for this device is not supported and needs to be migrated.
  1366. //
  1367. DriverInfo = NULL;
  1368. if( !BuildDriverInformation( Key,
  1369. (LPTSTR)Data,
  1370. FilePath,
  1371. &DriverInfo ) ) {
  1372. //
  1373. // If we cannot build the driver information for this device, then
  1374. // we inform the user that we detected an unsupported device, but that
  1375. // we cannot migrate it. The user will have to provide the OEM disk
  1376. // for this device during setupldr or textmode setup phases.
  1377. //
  1378. RegCloseKey( Key );
  1379. FreeDriverInformationList( DriverList );
  1380. return( FALSE );
  1381. }
  1382. DriverInfo->Next = (PUNSUPORTED_DRIVER_INFO)*DriverList;
  1383. (PUNSUPORTED_DRIVER_INFO)*DriverList = DriverInfo;
  1384. RegCloseKey( Key );
  1385. }
  1386. RegCloseKey( ScsiKey );
  1387. return( TRUE );
  1388. }
  1389. DWORD
  1390. DumpRegInfoToInf(
  1391. IN PUNSUPORTED_DRIVER_REGKEY_INFO RegList,
  1392. IN LPTSTR DriverId,
  1393. IN PINFFILEGEN Context
  1394. )
  1395. {
  1396. LPTSTR SectionName;
  1397. DWORD Error;
  1398. LPTSTR szAddReg = TEXT("AddReg.");
  1399. PUNSUPORTED_DRIVER_REGKEY_INFO p;
  1400. Error = ERROR_SUCCESS;
  1401. SectionName = MALLOC( (lstrlen( szAddReg ) + lstrlen( DriverId ) + 1)*sizeof(TCHAR) );
  1402. if( SectionName == NULL ) {
  1403. Error = ERROR_NOT_ENOUGH_MEMORY;
  1404. goto c0;
  1405. }
  1406. lstrcpy( SectionName, szAddReg );
  1407. lstrcat( SectionName, DriverId );
  1408. Error = InfCreateSection( SectionName, &Context );
  1409. for( p = RegList; p != NULL; p = p->Next ) {
  1410. #if 0
  1411. Error = DumpRegInfoToInfWorker( p->PredefinedKey,
  1412. p->KeyPath,
  1413. Context );
  1414. #endif
  1415. Error = DumpRegKeyToInf( Context,
  1416. p->PredefinedKey,
  1417. p->KeyPath,
  1418. TRUE,
  1419. TRUE,
  1420. TRUE,
  1421. p->MigrateVolatileKeys );
  1422. if( Error != ERROR_SUCCESS ) {
  1423. goto c0;
  1424. }
  1425. }
  1426. c0:
  1427. if( SectionName != NULL ) {
  1428. FREE( SectionName );
  1429. }
  1430. return( Error );
  1431. }
  1432. DWORD
  1433. DumpFileInfoToInf(
  1434. IN PUNSUPORTED_DRIVER_FILE_INFO FileList,
  1435. IN LPTSTR DriverId,
  1436. IN PINFFILEGEN Context
  1437. )
  1438. {
  1439. LPTSTR SectionName;
  1440. DWORD Error;
  1441. LPTSTR szFiles = TEXT("Files.");
  1442. PUNSUPORTED_DRIVER_FILE_INFO p;
  1443. TCHAR Line[ MAX_PATH ];
  1444. Error = ERROR_SUCCESS;
  1445. SectionName = MALLOC( (lstrlen( szFiles ) + lstrlen( DriverId ) + 1)*sizeof(TCHAR) );
  1446. if( SectionName == NULL ) {
  1447. Error = ERROR_NOT_ENOUGH_MEMORY;
  1448. goto c0;
  1449. }
  1450. lstrcpy( SectionName, szFiles );
  1451. lstrcat( SectionName, DriverId );
  1452. Error = InfCreateSection( SectionName, &Context );
  1453. for( p = FileList; p != NULL; p = p->Next ) {
  1454. StringCchCopy(Line, ARRAYSIZE(Line), p->FileName );
  1455. StringCchCat(Line, ARRAYSIZE(Line), TEXT(",") );
  1456. StringCchCat(Line, ARRAYSIZE(Line), p->TargetDirectory );
  1457. Error = WriteText(Context->FileHandle,MSG_INF_SINGLELINE,Line);
  1458. if( Error != ERROR_SUCCESS ) {
  1459. goto c0;
  1460. }
  1461. }
  1462. c0:
  1463. if( SectionName != NULL ) {
  1464. FREE( SectionName );
  1465. }
  1466. return( Error );
  1467. }
  1468. DWORD
  1469. DumpInstallInfoToAnswerFile (
  1470. IN PUNSUPORTED_DRIVER_INSTALL_INFO InstallInfo,
  1471. IN PCTSTR DriverId
  1472. )
  1473. {
  1474. PUNSUPORTED_DRIVER_INSTALL_INFO p;
  1475. DWORD d;
  1476. INT len;
  1477. PTSTR buffer, append;
  1478. TCHAR number[12];
  1479. if (!ActualParamFile[0] || !FileExists (ActualParamFile, NULL)) {
  1480. MYASSERT(FALSE);
  1481. return ERROR_FILE_NOT_FOUND;
  1482. }
  1483. //
  1484. // start by writing the list of driver sections as
  1485. // [Data]
  1486. // OEMDrivers=<driver-section-1>,<driver-section-2>,...
  1487. //
  1488. len = 0;
  1489. for (p = InstallInfo; p; p = p->Next) {
  1490. if (len) {
  1491. len++; // for the comma
  1492. }
  1493. len += LENGTHOF("MigDrv.") + lstrlen (DriverId);
  1494. }
  1495. buffer = MALLOC((len + 1) * sizeof (TCHAR));
  1496. if (!buffer) {
  1497. return ERROR_NOT_ENOUGH_MEMORY;
  1498. }
  1499. append = buffer;
  1500. for (p = InstallInfo; p; p = p->Next) {
  1501. if (append > buffer) {
  1502. *append++ = TEXT(',');
  1503. }
  1504. append += _sntprintf (append, len + 1 - (append - buffer), TEXT("MigDrv.%s"), DriverId);
  1505. }
  1506. d = ERROR_SUCCESS;
  1507. if (!WritePrivateProfileString (
  1508. WINNT_DATA,
  1509. WINNT_OEMDRIVERS,
  1510. buffer,
  1511. ActualParamFile
  1512. )) {
  1513. d = GetLastError ();
  1514. }
  1515. if (d == ERROR_SUCCESS) {
  1516. //
  1517. // then for each section, write the mig info as in
  1518. // [driver-section]
  1519. // OemDriverPathName=<path> (path to the driver (may use environment variables)
  1520. // OemInfName=<inf name> name of the inf to be installed from the above
  1521. // directory (there can be one or more infs in this directory, so
  1522. // this is a comma separated list)
  1523. // OemDriverFlags=<flags>
  1524. //
  1525. for (p = InstallInfo; p; p = p->Next) {
  1526. _sntprintf (buffer, len + 1, TEXT("MigDrv.%s"), DriverId);
  1527. _sntprintf (number, ARRAYSIZE(number), TEXT("%u"), SETUP_OEM_MIGRATED_DRIVER);
  1528. if (!WritePrivateProfileString (
  1529. buffer,
  1530. WINNT_OEMDRIVERS_PATHNAME,
  1531. IsArc() ? LocalSourceWithPlatform : LocalBootDirectory,
  1532. ActualParamFile
  1533. ) ||
  1534. !WritePrivateProfileString (
  1535. buffer,
  1536. WINNT_OEMDRIVERS_INFNAME,
  1537. p->InfOriginalFileName ? p->InfOriginalFileName : p->InfFileName,
  1538. ActualParamFile
  1539. ) ||
  1540. !WritePrivateProfileString (
  1541. buffer,
  1542. WINNT_OEMDRIVERS_FLAGS,
  1543. number,
  1544. ActualParamFile
  1545. )) {
  1546. d = GetLastError ();
  1547. break;
  1548. }
  1549. }
  1550. }
  1551. FREE(buffer);
  1552. if (d != ERROR_SUCCESS) {
  1553. //
  1554. // try to clean up
  1555. //
  1556. WritePrivateProfileString (
  1557. WINNT_DATA,
  1558. WINNT_OEMDRIVERS,
  1559. TEXT(""),
  1560. ActualParamFile
  1561. );
  1562. }
  1563. return d;
  1564. }
  1565. DWORD
  1566. DumpHardwareIdsToInf(
  1567. IN PUNSUPORTED_PNP_HARDWARE_ID HwIdList,
  1568. IN LPTSTR DriverId,
  1569. IN PINFFILEGEN Context
  1570. )
  1571. {
  1572. LPTSTR SectionName;
  1573. DWORD Error;
  1574. LPTSTR szHardwareIds = TEXT("HardwareIds.");
  1575. PUNSUPORTED_PNP_HARDWARE_ID p;
  1576. LPTSTR Line;
  1577. ULONG Length;
  1578. Error = ERROR_SUCCESS;
  1579. SectionName = MALLOC( (lstrlen( szHardwareIds ) + lstrlen( DriverId ) + 1)*sizeof( TCHAR ) );
  1580. if( SectionName == NULL ) {
  1581. Error = ERROR_NOT_ENOUGH_MEMORY;
  1582. goto c0;
  1583. }
  1584. lstrcpy( SectionName, szHardwareIds );
  1585. lstrcat( SectionName, DriverId );
  1586. Error = InfCreateSection( SectionName, &Context );
  1587. for( p = HwIdList; p != NULL; p = p->Next ) {
  1588. Length = (lstrlen( p->Id ) + lstrlen( p->Service ) + 3)*sizeof(TCHAR);
  1589. if( p->ClassGuid ) {
  1590. Length += (lstrlen( p->ClassGuid) + 1 )*sizeof(TCHAR);
  1591. }
  1592. Line = MALLOC( Length );
  1593. if( Line == NULL ) {
  1594. goto c0;
  1595. }
  1596. lstrcpy( Line, p->Id );
  1597. lstrcat( Line, TEXT("=") );
  1598. lstrcat( Line, p->Service );
  1599. if( p->ClassGuid ) {
  1600. lstrcat( Line, TEXT(",") );
  1601. lstrcat( Line, p->ClassGuid );
  1602. }
  1603. Error = WriteText(Context->FileHandle,MSG_INF_SINGLELINE,Line);
  1604. FREE( Line );
  1605. if( Error != ERROR_SUCCESS ) {
  1606. goto c0;
  1607. }
  1608. }
  1609. c0:
  1610. if( SectionName != NULL ) {
  1611. FREE( SectionName );
  1612. }
  1613. return( Error );
  1614. }
  1615. BOOL
  1616. SaveUnsupportedDriverInfo(
  1617. IN HWND ParentWindow,
  1618. IN LPTSTR FileName,
  1619. IN PUNSUPORTED_DRIVER_INFO DriverList
  1620. )
  1621. {
  1622. HKEY Key;
  1623. DWORD d;
  1624. LONG l = ERROR_SUCCESS;
  1625. TCHAR Path[MAX_PATH];
  1626. PINFFILEGEN InfContext;
  1627. TCHAR SectionName[MAX_PATH];
  1628. PUNSUPORTED_DRIVER_INFO p;
  1629. #if defined(_AMD64_) || defined(_X86_)
  1630. if(Floppyless) {
  1631. //These are both size MAX_PATH
  1632. lstrcpy(Path,LocalBootDirectory);
  1633. } else {
  1634. Path[0] = FirstFloppyDriveLetter;
  1635. Path[1] = TEXT(':');
  1636. Path[2] = 0;
  1637. }
  1638. #else
  1639. //These are both size MAX_PATH
  1640. lstrcpy(Path,LocalSourceWithPlatform);
  1641. #endif
  1642. l = InfStart( FileName,
  1643. Path,
  1644. &InfContext);
  1645. if(l != ERROR_SUCCESS) {
  1646. return(FALSE);
  1647. }
  1648. for( p = DriverList; p != NULL; p = p->Next ) {
  1649. if( p->KeyList != NULL ) {
  1650. l = DumpRegInfoToInf( p->KeyList,p->DriverId, InfContext );
  1651. if(l != ERROR_SUCCESS) {
  1652. goto c0;
  1653. }
  1654. }
  1655. if( p->FileList ) {
  1656. l = DumpFileInfoToInf( p->FileList, p->DriverId, InfContext );
  1657. if(l != ERROR_SUCCESS) {
  1658. goto c0;
  1659. }
  1660. }
  1661. if (p->InstallList) {
  1662. l = DumpInstallInfoToAnswerFile(p->InstallList, p->DriverId);
  1663. if(l != ERROR_SUCCESS) {
  1664. goto c0;
  1665. }
  1666. }
  1667. if( p->HardwareIdsList ) {
  1668. l = DumpHardwareIdsToInf( p->HardwareIdsList, p->DriverId, InfContext );
  1669. if(l != ERROR_SUCCESS) {
  1670. goto c0;
  1671. }
  1672. }
  1673. }
  1674. if( DriverList != NULL ) {
  1675. l = InfCreateSection( TEXT("Devices"), &InfContext );
  1676. if(l != NO_ERROR) {
  1677. goto c0;
  1678. }
  1679. for( p = DriverList; p != NULL; p = p->Next ) {
  1680. l = WriteText(InfContext->FileHandle,MSG_INF_SINGLELINE,p->DriverId);
  1681. if(l != ERROR_SUCCESS) {
  1682. goto c0;
  1683. }
  1684. }
  1685. }
  1686. c0:
  1687. InfEnd( &InfContext );
  1688. if( l != ERROR_SUCCESS ) {
  1689. StringCchCat( Path, ARRAYSIZE(Path), TEXT("\\") );
  1690. if (SUCCEEDED(StringCchCat( Path, ARRAYSIZE(Path), FileName )))
  1691. {
  1692. DeleteFile( Path );
  1693. }
  1694. return( FALSE );
  1695. }
  1696. return(TRUE);
  1697. }
  1698. BOOL
  1699. MigrateUnsupportedNTDrivers(
  1700. IN HWND ParentWindow,
  1701. IN PVOID TxtsetupSifHandle
  1702. )
  1703. {
  1704. BOOL b;
  1705. PUNSUPORTED_DRIVER_INFO UnsupportedDriverList = NULL;
  1706. b = BuildUnsupportedDriverList( TxtsetupSif, &UnsupportedDriverList );
  1707. if( !CheckUpgradeOnly && b ) {
  1708. if( UnsupportedDriverList ) {
  1709. b = SaveUnsupportedDriverInfo( ParentWindow, WINNT_UNSUPDRV_INF_FILE, UnsupportedDriverList );
  1710. if( b ) {
  1711. b = AddUnsupportedFilesToCopyList( ParentWindow, UnsupportedDriverList );
  1712. if( !b ) {
  1713. TCHAR Path[ MAX_PATH + 1 ];
  1714. //
  1715. // If we failed to add the files to the copy list, then
  1716. // delete unsupdrv.inf since there is no point in migrating
  1717. // these drivers.
  1718. //
  1719. #if defined(_AMD64_) || defined(_X86_)
  1720. if(Floppyless) {
  1721. //These are both size MAX_PATH
  1722. lstrcpy(Path,LocalBootDirectory);
  1723. } else {
  1724. Path[0] = FirstFloppyDriveLetter;
  1725. Path[1] = TEXT(':');
  1726. Path[2] = 0;
  1727. }
  1728. #else
  1729. //These are both size MAX_PATH
  1730. lstrcpy(Path,LocalSourceWithPlatform);
  1731. #endif
  1732. StringCchCat( Path, ARRAYSIZE(Path), TEXT("\\") );
  1733. if (SUCCEEDED(StringCchCat( Path, ARRAYSIZE(Path), WINNT_UNSUPDRV_INF_FILE )))
  1734. {
  1735. DeleteFile( Path );
  1736. }
  1737. }
  1738. }
  1739. }
  1740. FreeDriverInformationList( &UnsupportedDriverList );
  1741. }
  1742. if( !b ) {
  1743. //
  1744. // Inform the user that unsupported drivers could not be migrated.
  1745. //
  1746. MessageBoxFromMessage( ParentWindow,
  1747. MSG_CANT_MIGRATE_UNSUP_DRIVERS,
  1748. FALSE,
  1749. AppTitleStringId,
  1750. MB_OK | MB_ICONINFORMATION | MB_TASKMODAL
  1751. );
  1752. }
  1753. return( b );
  1754. }
  1755. #endif