Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1668 lines
42 KiB

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