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.

5079 lines
150 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. filegen.c
  5. Abstract:
  6. This module creates a tool that generates filelist.dat and is executed for us by
  7. the NT build lab. It scans the INI files to build a list for all files that are
  8. going to be installed by NT
  9. Author:
  10. Calin Negreanu (calinn) 18-Feb-1998
  11. Revision History:
  12. <alias> <date> <comments>
  13. --*/
  14. #include "pch.h"
  15. #include <conio.h>
  16. #ifdef UNICODE
  17. #error UNICODE not allowed
  18. #endif
  19. #define S_IGNORE_THIS_FILE TEXT("*")
  20. #define FILEGEN_VERSION 3
  21. #define DIRS_FIELD 8
  22. #define DISP_FIELD 9
  23. #define DEST_FIELD 11
  24. #define SRC_NEVER_COPY 0x01
  25. BOOL CancelFlag = FALSE;
  26. BOOL *g_CancelFlagPtr = &CancelFlag;
  27. POOLHANDLE g_TempPool;
  28. #ifdef DEBUG
  29. extern BOOL g_DoLog;
  30. #endif
  31. typedef BOOL (*PSETUPGETINFSECTIONS) ( HINF,PTSTR,UINT,UINT*);
  32. PSETUPGETINFSECTIONS MypSetupGetInfSections;
  33. // this section is populated from the directories with either INF files or with compressed
  34. // INF files that were uncompressed in the temp directory. Two things: The value of every
  35. // key will have a checksum of the INF, if this is 0xFFFFFFFF it means that the INF file
  36. // has changed and all the other information about this INF file should be discarded.
  37. #define MEMDB_CATEGORY_INF_FILES TEXT("InfFiles")
  38. // this section needs no optimization. It will be created every time from the additional file
  39. #define MEMDB_CATEGORY_NT_KNOWN_FILES TEXT("NtKnownFiles")
  40. // this section needs no optimization. It will be created every time from the additional file
  41. #define MEMDB_CATEGORY_NT_HEADER_FILES TEXT("NtHeaderFiles")
  42. // this section needs no optimization. It will be created every time from the additional file
  43. #define MEMDB_CATEGORY_NT_CHECK_FILES TEXT("NtCheckFiles")
  44. #define MEMDB_CATEGORY_NT_FILES_DOUBLED_COPY "NtFilesDoubledCopy"
  45. #define MEMDB_CATEGORY_NT_FILES_DOUBLED_IDX_COPY "NtFilesDoubledIdxCopy"
  46. #define MEMDB_CATEGORY_NT_FILES_NODIR_COPY "NtFilesNoDirCopy"
  47. #define MEMDB_CATEGORY_NT_FILES_NODIR_OTHER_COPY "NtFilesNoDirOtherCopy"
  48. #define MEMDB_CATEGORY_NT_FILES_DOUBLED_DEL "NtFilesDoubledDel"
  49. #define MEMDB_CATEGORY_NT_FILES_DOUBLED_IDX_DEL "NtFilesDoubledIdxDel"
  50. #define MEMDB_CATEGORY_NT_FILES_NODIR_DEL "NtFilesNoDirDel"
  51. #define MEMDB_CATEGORY_NT_FILES_NODIR_OTHER_DEL "NtFilesNoDirOtherDel"
  52. #define MEMDB_CATEGORY_NT_SECT_NODIR "NtSectNoDir"
  53. #define MEMDB_CATEGORY_NT_SECT_BADDIR "NtSectBadDir"
  54. #define MEMDB_CATEGORY_NT_INSTALLED_INFS "NtInstalledInfs"
  55. #define MEMDB_CATEGORY_NT_FILES_NO_LAYOUT "NtFileNoLayout"
  56. #define MEMDB_CATEGORY_DEL_FILES "DelFiles"
  57. #define MEMDB_CATEGORY_SRC_INF_FILES_NR "Source INF Files\\Total Number"
  58. #define MEMDB_CATEGORY_SRC_INF_FILES "Source INF Files"
  59. #define MEMDB_CATEGORY_KNOWN_FILE_NAMES "KnownFileNames"
  60. #define SECT_KNOWN_LOCATION "NtFiles_KnownLocation"
  61. HANDLE g_hHeap;
  62. HINSTANCE g_hInst;
  63. extern POOLHANDLE g_TextPool;
  64. CHAR g_TempDirBuf[MAX_MBCHAR_PATH];
  65. CHAR g_TempDirWackBuf[MAX_MBCHAR_PATH];
  66. PSTR g_TempDir;
  67. PSTR g_TempDirWack;
  68. INT g_TempDirWackChars;
  69. PSTR g_WinDir;
  70. CHAR g_WinDirBuf[MAX_MBCHAR_PATH];
  71. CHAR g_SourceDirectoryBuf[MAX_SOURCE_COUNT][MAX_MBCHAR_PATH];
  72. PCSTR g_SourceDirectories[MAX_SOURCE_COUNT];
  73. DWORD g_SourceDirectoryCount = 0;
  74. BOOL g_DoWarnings = FALSE;
  75. CHAR g_WarnFileBuf[MAX_MBCHAR_PATH];
  76. PSTR g_WarnFile = NULL;
  77. BOOL g_DoHeader = FALSE;
  78. CHAR g_HeaderFileBuf[MAX_MBCHAR_PATH];
  79. PSTR g_HeaderFile = NULL;
  80. PSTR g_AddnlFile = NULL;
  81. BOOL g_AddnlFileForced = FALSE;
  82. CHAR g_AddnlFileBuf[MAX_MBCHAR_PATH];
  83. CHAR g_AddnlFileAlt[MAX_MBCHAR_PATH];
  84. HINF g_AddnlInf = INVALID_HANDLE_VALUE;
  85. CHAR g_PlatformBuf[MAX_MBCHAR_PATH];
  86. PSTR g_Platform = NULL;
  87. CHAR g_ProductBuf[MAX_MBCHAR_PATH];
  88. PSTR g_Product = NULL;
  89. CHAR g_StructNameBuf[MAX_MBCHAR_PATH] = "Tier2Files";
  90. PSTR g_StructName = NULL;
  91. BOOL g_StrictInfs = TRUE;
  92. #define LAYOUT_CACHE_SIZE 3
  93. CHAR g_LastLayoutFile[LAYOUT_CACHE_SIZE][MAX_MBCHAR_PATH];
  94. UINT g_LayoutRef[LAYOUT_CACHE_SIZE];
  95. HINF g_LastLayoutHandle[LAYOUT_CACHE_SIZE];
  96. BOOL g_NextAvailLayoutData = 0;
  97. BOOL g_ForceRescan = FALSE;
  98. PSTR g_InfDatabase = NULL;
  99. UINT g_TotalInfFiles = 0;
  100. typedef struct _EXCLUDED_FILES {
  101. PCSTR File;
  102. INT ExcludeType;
  103. struct _EXCLUDED_FILES *Next;
  104. } EXCLUDED_FILES, *PEXCLUDED_FILES;
  105. PEXCLUDED_FILES g_ExcludedFiles = NULL;
  106. typedef struct _FORCED_FILES {
  107. PCSTR FilePattern;
  108. struct _FORCED_FILES *Next;
  109. } FORCED_FILES, *PFORCED_FILES;
  110. PFORCED_FILES g_ForcedFiles = NULL;
  111. typedef struct _EXCLUDED_INF_FILES {
  112. PCSTR InfName;
  113. PCSTR CopySectName;
  114. struct _EXCLUDED_INF_FILES *Next;
  115. } EXCLUDED_INF_FILES, *PEXCLUDED_INF_FILES;
  116. HASHITEM g_ExcludedInfsTable;
  117. HASHITEM g_ExcludedDirsTable;
  118. typedef struct _RENAMED_DIRS {
  119. PCSTR SrcDir;
  120. PCSTR DestDir;
  121. struct _RENAMED_DIRS *Next;
  122. } RENAMED_DIRS, *PRENAMED_DIRS;
  123. PRENAMED_DIRS g_RenamedDirs = NULL;
  124. typedef struct _HEADER_FILES {
  125. PCSTR FilePattern;
  126. UINT Priority;
  127. struct _HEADER_FILES *Next;
  128. } HEADER_FILES, *PHEADER_FILES;
  129. PHEADER_FILES g_HeaderFiles;
  130. HASHITEM g_PrivateIdInfsTable;
  131. typedef struct _PRIVATE_ID_INFS {
  132. PCSTR PrivateId;
  133. PCSTR EquivalentId;
  134. struct _PRIVATE_ID_INFS *Next;
  135. } PRIVATE_ID_INFS, *PPRIVATE_ID_INFS;
  136. HASHITEM g_IgnoredDirsTable;
  137. BOOL
  138. WINAPI
  139. MigUtil_Entry (
  140. HINSTANCE hinstDLL,
  141. DWORD fdwReason,
  142. LPVOID lpvReserved
  143. );
  144. BOOL
  145. WINAPI
  146. MemDb_Entry (
  147. HINSTANCE hinstDLL,
  148. DWORD fdwReason,
  149. LPVOID lpvReserved
  150. );
  151. BOOL
  152. pCreateNtFileList (
  153. IN PCSTR FileListDatPath
  154. );
  155. BOOL
  156. LocalGetFileNames (
  157. IN PCTSTR *InfDirs,
  158. IN UINT InfDirCount,
  159. IN BOOL QueryFlag
  160. );
  161. BOOL
  162. pLocalGetFileNamesWorker (
  163. IN PCTSTR InfDir,
  164. IN BOOL QueryFlag
  165. );
  166. VOID
  167. LocalFreeFileNames (
  168. IN BOOL QueryFlag
  169. );
  170. BOOL
  171. pLocalReadNtFiles (
  172. IN PCTSTR InfPath
  173. );
  174. BOOL
  175. pFixDir (
  176. IN PCSTR src,
  177. OUT PSTR dest
  178. );
  179. BOOL
  180. pIsExcludedDir (
  181. IN PCTSTR DirName
  182. );
  183. BOOL
  184. pShouldRescanInfs (
  185. IN PCTSTR *InfDirs,
  186. IN UINT InfDirCount
  187. );
  188. VOID
  189. pProcessDelFileSpec (
  190. IN PCSTR DestDirectory,
  191. IN PCSTR DestFile
  192. );
  193. VOID
  194. HelpAndExit (
  195. VOID
  196. )
  197. {
  198. printf ("Command line syntax:\n\n"
  199. "filegen [-i:<infdir>] [-o:<outputfile>] [-t:<tempdir>] [-w[:<warningfile>]]\n"
  200. " [-h:<headerfile>] [-a:<additional_file>] [-p:<platform>]\n"
  201. " [-d:<product>] [-s:<struct_name>] [-b:<INF database>] [-f] [-l]\n\n"
  202. "Optional Arguments:\n"
  203. " [-i:<infdir>] - Specifies directory containing INF files.\n"
  204. " Default: %%_NTTREE%%\n"
  205. " [-o:<outputfile>] - Specifies path and file name of DAT file.\n"
  206. " Default: %%_NTTREE%%\\filelist.dat\n"
  207. " [-t:<tempdir>] - Specifies path for temporary files.\n"
  208. " Default: %%TEMP%%\n"
  209. " [-w[:<warningfile>]] - Specifies if warning file is generated and it's\n"
  210. " location. Default: %%_NTTREE%%\\dump\\filegen.wrn\n"
  211. " [-h:<headerfile>] - Specifies if header file is generated and it's\n"
  212. " location. Default: %%_NTTREE%%\\dump\\filegen.hdr\n"
  213. " [-a:<addnl_file>] - Specifies full path name for FILEGEN.INF file\n"
  214. " [-p:<platform>] - Specifies platform (such as x86 or ia64)\n"
  215. " Default: x86\n"
  216. " [-d:<product>] - Specifies product type (WKS, DTC, ENT, SRV)\n"
  217. " Default: WKS\n"
  218. " [-s:<struct_name>] - Specifies the structure name (for header file)\n"
  219. " Default: Tier2Files\n"
  220. " [-b:<INF database>] - Specifies INF database file from the last run\n"
  221. " [-f] - Force rescanning all INFs\n"
  222. " [-l] - List content of existing output file\n"
  223. );
  224. exit(255);
  225. }
  226. HINF
  227. pOpenInfWithCache (
  228. IN PCSTR InfFile
  229. )
  230. {
  231. HINF infHandle;
  232. INT index;
  233. for (index = 0 ; index < LAYOUT_CACHE_SIZE ; index++) {
  234. if (StringIMatch (InfFile, g_LastLayoutFile[index])) {
  235. infHandle = g_LastLayoutHandle[index];
  236. g_LayoutRef[index] += 1;
  237. break;
  238. }
  239. }
  240. if (index == LAYOUT_CACHE_SIZE) {
  241. infHandle = InfOpenInfFile (InfFile);
  242. if (infHandle != INVALID_HANDLE_VALUE) {
  243. for (index = 0 ; index < LAYOUT_CACHE_SIZE ; index++) {
  244. if (g_LayoutRef[index] == 0) {
  245. break;
  246. }
  247. }
  248. if (index < LAYOUT_CACHE_SIZE) {
  249. if (g_LastLayoutFile[index][0]) {
  250. InfCloseInfFile (g_LastLayoutHandle[index]);
  251. }
  252. StringCopy (g_LastLayoutFile[index], InfFile);
  253. g_LastLayoutHandle[index] = infHandle;
  254. g_LayoutRef[index] = 1;
  255. }
  256. }
  257. }
  258. return infHandle;
  259. }
  260. VOID
  261. pCloseInfWithCache (
  262. IN HINF Inf
  263. )
  264. {
  265. INT i;
  266. for (i = 0 ; i < LAYOUT_CACHE_SIZE ; i++) {
  267. if (g_LastLayoutFile[i][0] && g_LastLayoutHandle[i] == Inf) {
  268. break;
  269. }
  270. }
  271. if (i < LAYOUT_CACHE_SIZE) {
  272. if (g_LayoutRef[i] == 0) {
  273. MYASSERT(FALSE);
  274. } else {
  275. g_LayoutRef[i] -= 1;
  276. }
  277. } else {
  278. InfCloseInfFile (Inf);
  279. }
  280. }
  281. VOID
  282. pCloseCachedHandles (
  283. VOID
  284. )
  285. {
  286. INT index;
  287. for (index = 0 ; index < LAYOUT_CACHE_SIZE ; index++) {
  288. if (g_LastLayoutFile[index][0]) {
  289. InfCloseInfFile (g_LastLayoutHandle[index]);
  290. g_LastLayoutHandle[index] = INVALID_HANDLE_VALUE;
  291. g_LastLayoutFile[index][0] = 0;
  292. g_LayoutRef[index] = 0;
  293. }
  294. }
  295. }
  296. PTSTR
  297. pGetNonEmptyField (
  298. IN OUT PINFSTRUCT InfStruct,
  299. IN UINT Field
  300. )
  301. {
  302. PTSTR result;
  303. result = InfGetStringField (InfStruct, Field);
  304. if (result && *result == 0) {
  305. result = NULL;
  306. }
  307. return result;
  308. }
  309. BOOL
  310. pIsForcedFile (
  311. IN PCTSTR FileName
  312. )
  313. {
  314. PFORCED_FILES forcedFile;
  315. forcedFile = g_ForcedFiles;
  316. while (forcedFile) {
  317. if (IsPatternMatch (forcedFile->FilePattern, FileName)) {
  318. return TRUE;
  319. }
  320. forcedFile = forcedFile->Next;
  321. }
  322. return FALSE;
  323. }
  324. INT
  325. pIsExcludedFile (
  326. IN PCTSTR FileName
  327. )
  328. {
  329. PEXCLUDED_FILES excludedFile;
  330. //
  331. // Test if a file referenced by an INF should be excluded from the file list
  332. //
  333. // Return value -1 means not excluded
  334. // Return value 0 means excluded
  335. // Return value 1 means not excluded, but include in excluded files section of filelist.dat
  336. //
  337. excludedFile = g_ExcludedFiles;
  338. while (excludedFile) {
  339. if (IsPatternMatch (excludedFile->File, FileName)) {
  340. if (!pIsForcedFile (FileName)) {
  341. return excludedFile->ExcludeType;
  342. }
  343. }
  344. excludedFile = excludedFile->Next;
  345. }
  346. return -1;
  347. }
  348. BOOL
  349. pIsExcludedInfSection (
  350. IN PCTSTR InfFileName,
  351. IN PCTSTR InfSectionName
  352. )
  353. {
  354. BOOL excluded = FALSE;
  355. PEXCLUDED_INF_FILES excludedInf;
  356. if (HtFindStringAndData (g_ExcludedInfsTable, InfFileName, &excludedInf)) {
  357. if (!excludedInf) {
  358. //this means that the whole INF is excluded
  359. excluded = TRUE;
  360. } else {
  361. while (excludedInf) {
  362. if (StringIMatch (excludedInf->CopySectName, InfSectionName)) {
  363. excluded = TRUE;
  364. break;
  365. }
  366. excludedInf = excludedInf->Next;
  367. }
  368. }
  369. }
  370. return excluded;
  371. }
  372. BOOL
  373. pLoadForcedFilesFromSect (
  374. IN HINF infHandle,
  375. IN PCSTR SectName
  376. )
  377. {
  378. INFSTRUCT context = INITINFSTRUCT_POOLHANDLE;
  379. PCSTR filePattern;
  380. PFORCED_FILES forcedFile;
  381. if (InfFindFirstLine (infHandle, SectName, NULL, &context)) {
  382. do {
  383. filePattern = pGetNonEmptyField (&context, 1);
  384. if (filePattern) {
  385. forcedFile = (PFORCED_FILES) PoolMemGetMemory (g_TextPool, sizeof (FORCED_FILES));
  386. if (forcedFile) {
  387. forcedFile->FilePattern = PoolMemDuplicateString (g_TextPool, filePattern);
  388. forcedFile->Next = g_ForcedFiles;
  389. g_ForcedFiles = forcedFile;
  390. }
  391. }
  392. } while (InfFindNextLine (&context));
  393. }
  394. InfCleanUpInfStruct (&context);
  395. return TRUE;
  396. }
  397. BOOL
  398. pLoadForcedFiles (
  399. IN HINF infHandle
  400. )
  401. {
  402. PTSTR sectTmp;
  403. sectTmp = AllocText (256);
  404. if (!sectTmp) {
  405. return FALSE;
  406. }
  407. StringCopy (sectTmp, TEXT("FILELIST.FORCEINCLUDE"));
  408. pLoadForcedFilesFromSect (infHandle, sectTmp);
  409. StringCat (sectTmp, TEXT("."));
  410. StringCat (sectTmp, g_Platform);
  411. pLoadForcedFilesFromSect (infHandle, sectTmp);
  412. StringCat (sectTmp, TEXT("."));
  413. StringCat (sectTmp, g_Product);
  414. pLoadForcedFilesFromSect (infHandle, sectTmp);
  415. StringCopy (sectTmp, TEXT("FILELIST.FORCEINCLUDE"));
  416. StringCat (sectTmp, TEXT("."));
  417. StringCat (sectTmp, g_Product);
  418. pLoadForcedFilesFromSect (infHandle, sectTmp);
  419. StringCat (sectTmp, TEXT("."));
  420. StringCat (sectTmp, g_Platform);
  421. pLoadForcedFilesFromSect (infHandle, sectTmp);
  422. FreeText (sectTmp);
  423. return TRUE;
  424. }
  425. BOOL
  426. pLoadExcludedFilesFromSect (
  427. IN HINF infHandle,
  428. IN PCSTR SectName
  429. )
  430. {
  431. INFSTRUCT context = INITINFSTRUCT_POOLHANDLE;
  432. PCSTR filePattern;
  433. PEXCLUDED_FILES excludedFile;
  434. if (InfFindFirstLine (infHandle, SectName, NULL, &context)) {
  435. do {
  436. filePattern = pGetNonEmptyField (&context, 1);
  437. if (filePattern) {
  438. excludedFile = (PEXCLUDED_FILES) PoolMemGetMemory (g_TextPool, sizeof (EXCLUDED_FILES));
  439. if (excludedFile) {
  440. excludedFile->File = PoolMemDuplicateString (g_TextPool, filePattern);
  441. if (!InfGetIntField (&context, 2, &(excludedFile->ExcludeType))) {
  442. excludedFile->ExcludeType = 0;
  443. }
  444. excludedFile->Next = g_ExcludedFiles;
  445. g_ExcludedFiles = excludedFile;
  446. }
  447. }
  448. } while (InfFindNextLine (&context));
  449. }
  450. InfCleanUpInfStruct (&context);
  451. return TRUE;
  452. }
  453. BOOL
  454. pLoadExcludedFiles (
  455. IN HINF infHandle
  456. )
  457. {
  458. PTSTR sectTmp;
  459. sectTmp = AllocText (256);
  460. if (!sectTmp) {
  461. return FALSE;
  462. }
  463. StringCopy (sectTmp, TEXT("FILELIST.EXCLUDE"));
  464. pLoadExcludedFilesFromSect (infHandle, sectTmp);
  465. StringCat (sectTmp, TEXT("."));
  466. StringCat (sectTmp, g_Platform);
  467. pLoadExcludedFilesFromSect (infHandle, sectTmp);
  468. StringCat (sectTmp, TEXT("."));
  469. StringCat (sectTmp, g_Product);
  470. pLoadExcludedFilesFromSect (infHandle, sectTmp);
  471. StringCopy (sectTmp, TEXT("FILELIST.EXCLUDE"));
  472. StringCat (sectTmp, TEXT("."));
  473. StringCat (sectTmp, g_Product);
  474. pLoadExcludedFilesFromSect (infHandle, sectTmp);
  475. StringCat (sectTmp, TEXT("."));
  476. StringCat (sectTmp, g_Platform);
  477. pLoadExcludedFilesFromSect (infHandle, sectTmp);
  478. FreeText (sectTmp);
  479. return TRUE;
  480. }
  481. BOOL
  482. pLoadRenamedDirsFromSect (
  483. IN HINF infHandle,
  484. IN PCSTR SectName
  485. )
  486. {
  487. INFSTRUCT context = INITINFSTRUCT_POOLHANDLE;
  488. PCSTR srcDir, destDir;
  489. PRENAMED_DIRS renamedDir;
  490. if (InfFindFirstLine (infHandle, SectName, NULL, &context)) {
  491. do {
  492. srcDir = pGetNonEmptyField (&context, 1);
  493. destDir = pGetNonEmptyField (&context, 2);
  494. if (srcDir && destDir) {
  495. renamedDir = (PRENAMED_DIRS) PoolMemGetMemory (g_TextPool, sizeof (RENAMED_DIRS));
  496. if (renamedDir) {
  497. renamedDir->SrcDir = PoolMemDuplicateString (g_TextPool, srcDir);
  498. renamedDir->DestDir = PoolMemDuplicateString (g_TextPool, destDir);
  499. renamedDir->Next = g_RenamedDirs;
  500. g_RenamedDirs = renamedDir;
  501. }
  502. }
  503. } while (InfFindNextLine (&context));
  504. }
  505. InfCleanUpInfStruct (&context);
  506. return TRUE;
  507. }
  508. BOOL
  509. pLoadRenamedDirs (
  510. IN HINF infHandle
  511. )
  512. {
  513. PTSTR sectTmp;
  514. sectTmp = AllocText (256);
  515. if (!sectTmp) {
  516. return FALSE;
  517. }
  518. StringCopy (sectTmp, TEXT("FILELIST.RENAMEDIRS"));
  519. pLoadRenamedDirsFromSect (infHandle, sectTmp);
  520. StringCat (sectTmp, TEXT("."));
  521. StringCat (sectTmp, g_Platform);
  522. pLoadRenamedDirsFromSect (infHandle, sectTmp);
  523. StringCat (sectTmp, TEXT("."));
  524. StringCat (sectTmp, g_Product);
  525. pLoadRenamedDirsFromSect (infHandle, sectTmp);
  526. StringCopy (sectTmp, TEXT("FILELIST.RENAMEDIRS"));
  527. StringCat (sectTmp, TEXT("."));
  528. StringCat (sectTmp, g_Product);
  529. pLoadRenamedDirsFromSect (infHandle, sectTmp);
  530. StringCat (sectTmp, TEXT("."));
  531. StringCat (sectTmp, g_Platform);
  532. pLoadRenamedDirsFromSect (infHandle, sectTmp);
  533. FreeText (sectTmp);
  534. return TRUE;
  535. }
  536. BOOL
  537. pLoadHeaderFilesFromSect (
  538. IN HINF infHandle,
  539. IN PCSTR SectName
  540. )
  541. {
  542. INFSTRUCT context = INITINFSTRUCT_POOLHANDLE;
  543. PCSTR filePattern;
  544. PHEADER_FILES headerFile;
  545. if (InfFindFirstLine (infHandle, SectName, NULL, &context)) {
  546. do {
  547. filePattern = pGetNonEmptyField (&context, 1);
  548. if (filePattern) {
  549. headerFile = (PHEADER_FILES) PoolMemGetMemory (g_TextPool, sizeof (HEADER_FILES));
  550. if (headerFile) {
  551. headerFile->FilePattern = PoolMemDuplicateString (g_TextPool, filePattern);
  552. if (!InfGetIntField (&context, 2, &(headerFile->Priority))) {
  553. headerFile->Priority = 0xFFFFFFFF;
  554. }
  555. headerFile->Next = g_HeaderFiles;
  556. g_HeaderFiles = headerFile;
  557. }
  558. }
  559. } while (InfFindNextLine (&context));
  560. }
  561. InfCleanUpInfStruct (&context);
  562. return TRUE;
  563. }
  564. BOOL
  565. pLoadHeaderFiles (
  566. IN HINF infHandle
  567. )
  568. {
  569. PTSTR sectTmp;
  570. sectTmp = AllocText (256);
  571. if (!sectTmp) {
  572. return FALSE;
  573. }
  574. StringCopy (sectTmp, TEXT("FILELIST.HEADERFILES"));
  575. pLoadHeaderFilesFromSect (infHandle, sectTmp);
  576. StringCat (sectTmp, TEXT("."));
  577. StringCat (sectTmp, g_Platform);
  578. pLoadHeaderFilesFromSect (infHandle, sectTmp);
  579. StringCat (sectTmp, TEXT("."));
  580. StringCat (sectTmp, g_Product);
  581. pLoadHeaderFilesFromSect (infHandle, sectTmp);
  582. StringCopy (sectTmp, TEXT("FILELIST.HEADERFILES"));
  583. StringCat (sectTmp, TEXT("."));
  584. StringCat (sectTmp, g_Product);
  585. pLoadHeaderFilesFromSect (infHandle, sectTmp);
  586. StringCat (sectTmp, TEXT("."));
  587. StringCat (sectTmp, g_Platform);
  588. pLoadHeaderFilesFromSect (infHandle, sectTmp);
  589. FreeText (sectTmp);
  590. return TRUE;
  591. }
  592. BOOL
  593. pLoadExcludedInfsFromSect (
  594. IN HINF infHandle,
  595. IN PCSTR SectName
  596. )
  597. {
  598. INFSTRUCT is = INITINFSTRUCT_POOLHANDLE;
  599. PCTSTR InfFile, CopySect;
  600. PEXCLUDED_INF_FILES excludedInfFile;
  601. HASHITEM findIndex;
  602. if (InfFindFirstLine (infHandle, SectName, NULL, &is)) {
  603. do {
  604. InfFile = pGetNonEmptyField (&is, 1);
  605. CopySect = pGetNonEmptyField (&is, 2);
  606. if (InfFile) {
  607. if (CopySect) {
  608. excludedInfFile = (PEXCLUDED_INF_FILES) PoolMemGetMemory (g_TextPool, sizeof (EXCLUDED_INF_FILES));
  609. excludedInfFile->InfName = PoolMemDuplicateString (g_TextPool, InfFile);
  610. excludedInfFile->CopySectName = PoolMemDuplicateString (g_TextPool, CopySect);
  611. findIndex = HtFindStringAndData (g_ExcludedInfsTable, InfFile, &(excludedInfFile->Next));
  612. if (findIndex) {
  613. HtSetStringData (g_ExcludedInfsTable, findIndex, &excludedInfFile);
  614. } else {
  615. excludedInfFile->Next = NULL;
  616. HtAddStringAndData (g_ExcludedInfsTable, InfFile, &excludedInfFile);
  617. }
  618. } else {
  619. // the whole INF file is excluded
  620. findIndex = HtFindStringAndData (g_ExcludedInfsTable, InfFile, &excludedInfFile);
  621. if (findIndex) {
  622. excludedInfFile = NULL;
  623. HtSetStringData (g_ExcludedInfsTable, findIndex, &excludedInfFile);
  624. } else {
  625. excludedInfFile = NULL;
  626. HtAddStringAndData (g_ExcludedInfsTable, InfFile, &excludedInfFile);
  627. }
  628. }
  629. }
  630. InfResetInfStruct (&is);
  631. } while (InfFindNextLine (&is));
  632. }
  633. InfCleanUpInfStruct (&is);
  634. return TRUE;
  635. }
  636. BOOL
  637. pCreateExcludedInfsTable (
  638. IN HINF infHandle
  639. )
  640. {
  641. PTSTR sectTmp;
  642. sectTmp = AllocText (256);
  643. if (!sectTmp) {
  644. return FALSE;
  645. }
  646. g_ExcludedInfsTable = HtAllocWithData (sizeof (PCTSTR));
  647. StringCopy (sectTmp, TEXT("FILELIST.EXCLUDEINF"));
  648. pLoadExcludedInfsFromSect (infHandle, sectTmp);
  649. StringCat (sectTmp, TEXT("."));
  650. StringCat (sectTmp, g_Platform);
  651. pLoadExcludedInfsFromSect (infHandle, sectTmp);
  652. StringCat (sectTmp, TEXT("."));
  653. StringCat (sectTmp, g_Product);
  654. pLoadExcludedInfsFromSect (infHandle, sectTmp);
  655. StringCopy (sectTmp, TEXT("FILELIST.EXCLUDEINF"));
  656. StringCat (sectTmp, TEXT("."));
  657. StringCat (sectTmp, g_Product);
  658. pLoadExcludedInfsFromSect (infHandle, sectTmp);
  659. StringCat (sectTmp, TEXT("."));
  660. StringCat (sectTmp, g_Platform);
  661. pLoadExcludedInfsFromSect (infHandle, sectTmp);
  662. FreeText (sectTmp);
  663. return TRUE;
  664. }
  665. BOOL
  666. pLoadPrivateIdInfsFromSect (
  667. IN HINF infHandle,
  668. IN PCSTR SectName
  669. )
  670. {
  671. INFSTRUCT is = INITINFSTRUCT_POOLHANDLE;
  672. PCTSTR InfFile, PrivateId, EquivalentId;
  673. PPRIVATE_ID_INFS privateIdInfFile;
  674. HASHITEM findIndex;
  675. if (InfFindFirstLine (infHandle, SectName, NULL, &is)) {
  676. do {
  677. InfFile = pGetNonEmptyField (&is, 1);
  678. PrivateId = pGetNonEmptyField (&is, 2);
  679. EquivalentId = pGetNonEmptyField (&is, 3);
  680. if (InfFile && PrivateId && EquivalentId) {
  681. privateIdInfFile = (PPRIVATE_ID_INFS) PoolMemGetMemory (g_TextPool, sizeof (PRIVATE_ID_INFS));
  682. privateIdInfFile->PrivateId = PoolMemDuplicateString (g_TextPool, PrivateId);
  683. privateIdInfFile->EquivalentId = PoolMemDuplicateString (g_TextPool, EquivalentId);
  684. findIndex = HtFindStringAndData (g_PrivateIdInfsTable, InfFile, &(privateIdInfFile->Next));
  685. if (findIndex) {
  686. HtSetStringData (g_PrivateIdInfsTable, findIndex, &privateIdInfFile);
  687. } else {
  688. privateIdInfFile->Next = NULL;
  689. HtAddStringAndData (g_PrivateIdInfsTable, InfFile, &privateIdInfFile);
  690. }
  691. }
  692. InfResetInfStruct (&is);
  693. } while (InfFindNextLine (&is));
  694. }
  695. InfCleanUpInfStruct (&is);
  696. return TRUE;
  697. }
  698. BOOL
  699. pCreatePrivateIdInfsTable (
  700. IN HINF infHandle
  701. )
  702. {
  703. PTSTR sectTmp;
  704. sectTmp = AllocText (256);
  705. if (!sectTmp) {
  706. return FALSE;
  707. }
  708. g_PrivateIdInfsTable = HtAllocWithData (sizeof (PCTSTR));
  709. StringCopy (sectTmp, TEXT("FILELIST.PRIVATEIDDIR"));
  710. pLoadPrivateIdInfsFromSect (infHandle, sectTmp);
  711. StringCat (sectTmp, TEXT("."));
  712. StringCat (sectTmp, g_Platform);
  713. pLoadPrivateIdInfsFromSect (infHandle, sectTmp);
  714. StringCat (sectTmp, TEXT("."));
  715. StringCat (sectTmp, g_Product);
  716. pLoadPrivateIdInfsFromSect (infHandle, sectTmp);
  717. StringCopy (sectTmp, TEXT("FILELIST.PRIVATEIDDIR"));
  718. StringCat (sectTmp, TEXT("."));
  719. StringCat (sectTmp, g_Product);
  720. pLoadPrivateIdInfsFromSect (infHandle, sectTmp);
  721. StringCat (sectTmp, TEXT("."));
  722. StringCat (sectTmp, g_Platform);
  723. pLoadPrivateIdInfsFromSect (infHandle, sectTmp);
  724. FreeText (sectTmp);
  725. return TRUE;
  726. }
  727. BOOL
  728. pLoadExcludedDirsFromSect (
  729. IN HINF infHandle,
  730. IN PCSTR SectName
  731. )
  732. {
  733. INFSTRUCT is = INITINFSTRUCT_POOLHANDLE;
  734. PCTSTR DirId;
  735. if (InfFindFirstLine (infHandle, SectName, NULL, &is)) {
  736. do {
  737. DirId = pGetNonEmptyField (&is, 1);
  738. if (DirId) {
  739. HtAddString (g_ExcludedDirsTable, DirId);
  740. }
  741. InfResetInfStruct (&is);
  742. } while (InfFindNextLine (&is));
  743. }
  744. InfCleanUpInfStruct (&is);
  745. return TRUE;
  746. }
  747. BOOL
  748. pLoadExcludedDirs (
  749. IN HINF infHandle
  750. )
  751. {
  752. PTSTR sectTmp;
  753. sectTmp = AllocText (256);
  754. if (!sectTmp) {
  755. return FALSE;
  756. }
  757. g_ExcludedDirsTable = HtAlloc ();
  758. StringCopy (sectTmp, TEXT("FILELIST.EXCLUDEDIR"));
  759. pLoadExcludedDirsFromSect (infHandle, sectTmp);
  760. StringCat (sectTmp, TEXT("."));
  761. StringCat (sectTmp, g_Platform);
  762. pLoadExcludedDirsFromSect (infHandle, sectTmp);
  763. StringCat (sectTmp, TEXT("."));
  764. StringCat (sectTmp, g_Product);
  765. pLoadExcludedDirsFromSect (infHandle, sectTmp);
  766. StringCopy (sectTmp, TEXT("FILELIST.EXCLUDEDIR"));
  767. StringCat (sectTmp, TEXT("."));
  768. StringCat (sectTmp, g_Product);
  769. pLoadExcludedDirsFromSect (infHandle, sectTmp);
  770. StringCat (sectTmp, TEXT("."));
  771. StringCat (sectTmp, g_Platform);
  772. pLoadExcludedDirsFromSect (infHandle, sectTmp);
  773. FreeText (sectTmp);
  774. return TRUE;
  775. }
  776. BOOL
  777. pLoadIgnoredDirsFromSect (
  778. IN HINF infHandle,
  779. IN PCSTR SectName
  780. )
  781. {
  782. INFSTRUCT is = INITINFSTRUCT_POOLHANDLE;
  783. PCTSTR DirId;
  784. if (InfFindFirstLine (infHandle, SectName, NULL, &is)) {
  785. do {
  786. DirId = pGetNonEmptyField (&is, 1);
  787. if (DirId) {
  788. HtAddString (g_IgnoredDirsTable, DirId);
  789. }
  790. InfResetInfStruct (&is);
  791. } while (InfFindNextLine (&is));
  792. }
  793. InfCleanUpInfStruct (&is);
  794. return TRUE;
  795. }
  796. BOOL
  797. pLoadIgnoredDirs (
  798. IN HINF infHandle
  799. )
  800. {
  801. PTSTR sectTmp;
  802. sectTmp = AllocText (256);
  803. if (!sectTmp) {
  804. return FALSE;
  805. }
  806. g_IgnoredDirsTable = HtAlloc ();
  807. StringCopy (sectTmp, TEXT("FILELIST.IGNOREDIR"));
  808. pLoadIgnoredDirsFromSect (infHandle, sectTmp);
  809. StringCat (sectTmp, TEXT("."));
  810. StringCat (sectTmp, g_Platform);
  811. pLoadIgnoredDirsFromSect (infHandle, sectTmp);
  812. StringCat (sectTmp, TEXT("."));
  813. StringCat (sectTmp, g_Product);
  814. pLoadIgnoredDirsFromSect (infHandle, sectTmp);
  815. StringCopy (sectTmp, TEXT("FILELIST.IGNOREDIR"));
  816. StringCat (sectTmp, TEXT("."));
  817. StringCat (sectTmp, g_Product);
  818. pLoadIgnoredDirsFromSect (infHandle, sectTmp);
  819. StringCat (sectTmp, TEXT("."));
  820. StringCat (sectTmp, g_Platform);
  821. pLoadIgnoredDirsFromSect (infHandle, sectTmp);
  822. FreeText (sectTmp);
  823. return TRUE;
  824. }
  825. BOOL
  826. pLoadKnownFilesFromSect (
  827. IN HINF infHandle,
  828. IN PCSTR SectName,
  829. IN BOOL CountPriority
  830. )
  831. {
  832. INFSTRUCT is = INITINFSTRUCT_POOLHANDLE;
  833. PCTSTR SrcName;
  834. PCTSTR DestName;
  835. PCTSTR InfName;
  836. PCTSTR DirName;
  837. UINT Priority;
  838. DWORD offset;
  839. PTSTR key;
  840. key = AllocText (MEMDB_MAX);
  841. if (!key) {
  842. return FALSE;
  843. }
  844. if (InfFindFirstLine (infHandle, SectName, NULL, &is)) {
  845. do {
  846. DestName = pGetNonEmptyField (&is, 1);
  847. SrcName = pGetNonEmptyField (&is, 2);
  848. InfName = pGetNonEmptyField (&is, 3);
  849. DirName = pGetNonEmptyField (&is, 4);
  850. if (!InfGetIntField (&is, 5, &Priority)) {
  851. Priority = 0xFFFFFFFF;
  852. }
  853. if (DestName && DirName) {
  854. MemDbSetValueEx (
  855. MEMDB_CATEGORY_NT_DIRS,
  856. DirName,
  857. NULL,
  858. NULL,
  859. 0,
  860. &offset
  861. );
  862. if (CountPriority) {
  863. _stprintf (key, TEXT("%s\\%07ud\\%s\\%s\\%s"), MEMDB_CATEGORY_NT_KNOWN_FILES, Priority, DestName, SrcName, InfName);
  864. } else {
  865. _stprintf (key, TEXT("%s\\%s\\%s\\%s"), MEMDB_CATEGORY_NT_KNOWN_FILES, DestName, SrcName, InfName);
  866. }
  867. MemDbSetValue (key, offset);
  868. MemDbBuildKey (key, MEMDB_CATEGORY_KNOWN_FILE_NAMES, SrcName, NULL, NULL);
  869. MemDbSetValue (key, offset);
  870. }
  871. InfResetInfStruct (&is);
  872. } while (InfFindNextLine (&is));
  873. }
  874. InfCleanUpInfStruct (&is);
  875. FreeText (key);
  876. return TRUE;
  877. }
  878. BOOL
  879. pIsKnownFile (
  880. IN PCTSTR DestDir,
  881. IN PCTSTR DestFile
  882. )
  883. {
  884. TCHAR testKey[MEMDB_MAX];
  885. DWORD storedOffset;
  886. DWORD dirOffset;
  887. MemDbSetValueEx (
  888. MEMDB_CATEGORY_NT_DIRS,
  889. DestDir,
  890. NULL,
  891. NULL,
  892. 0,
  893. &dirOffset
  894. );
  895. MemDbBuildKey (testKey, MEMDB_CATEGORY_KNOWN_FILE_NAMES, DestFile, NULL, NULL);
  896. if (!MemDbGetValue (testKey, &storedOffset)) {
  897. return FALSE;
  898. }
  899. return storedOffset != dirOffset;
  900. }
  901. BOOL
  902. pLoadKnownFiles (
  903. IN HINF InfHandle,
  904. IN BOOL CountPriority
  905. )
  906. {
  907. PTSTR sectTmp;
  908. sectTmp = AllocText (256);
  909. if (!sectTmp) {
  910. return FALSE;
  911. }
  912. MemDbDeleteTree (MEMDB_CATEGORY_NT_KNOWN_FILES);
  913. StringCopy (sectTmp, TEXT("FILELIST.KNOWNFILES"));
  914. pLoadKnownFilesFromSect (InfHandle, sectTmp, CountPriority);
  915. StringCat (sectTmp, TEXT("."));
  916. StringCat (sectTmp, g_Platform);
  917. pLoadKnownFilesFromSect (InfHandle, sectTmp, CountPriority);
  918. StringCat (sectTmp, TEXT("."));
  919. StringCat (sectTmp, g_Product);
  920. pLoadKnownFilesFromSect (InfHandle, sectTmp, CountPriority);
  921. StringCopy (sectTmp, TEXT("FILELIST.KNOWNFILES"));
  922. StringCat (sectTmp, TEXT("."));
  923. StringCat (sectTmp, g_Product);
  924. pLoadKnownFilesFromSect (InfHandle, sectTmp, CountPriority);
  925. StringCat (sectTmp, TEXT("."));
  926. StringCat (sectTmp, g_Platform);
  927. pLoadKnownFilesFromSect (InfHandle, sectTmp, CountPriority);
  928. FreeText (sectTmp);
  929. return TRUE;
  930. }
  931. VOID
  932. pPrintWarningGroupPart (
  933. IN HANDLE FileHandle,
  934. IN PCSTR Title,
  935. IN PCSTR MemDbPattern,
  936. IN INT Type,
  937. IN BOOL LastPartOfGroup,
  938. IN OUT PBOOL OneItem OPTIONAL
  939. )
  940. {
  941. MEMDB_ENUM enumFiles;
  942. MEMDB_ENUM enumSubFiles;
  943. PSTR outptr;
  944. PSTR output;
  945. BOOL dummy = FALSE;
  946. PTSTR outputStr;
  947. PTSTR key;
  948. __try {
  949. outputStr = AllocText (MEMDB_MAX);
  950. key = AllocText (MEMDB_MAX);
  951. if (!key || !outputStr) {
  952. __leave;
  953. }
  954. if (!OneItem) {
  955. OneItem = &dummy;
  956. }
  957. if (MemDbEnumFirstValue (
  958. &enumFiles,
  959. MemDbPattern,
  960. MEMDB_ALL_SUBLEVELS,
  961. MEMDB_ENDPOINTS_ONLY
  962. )) {
  963. if (*OneItem == FALSE) {
  964. WriteFileString (FileHandle, Title);
  965. }
  966. do {
  967. switch (Type) {
  968. case 0:
  969. WriteFileString (FileHandle, enumFiles.szName);
  970. WriteFileString (FileHandle, "\r\n");
  971. break;
  972. case 1:
  973. output = DuplicatePathString (enumFiles.szName, 0);
  974. outptr = _mbschr (output, '\\');
  975. if (outptr) {
  976. *outptr = '=';
  977. }
  978. WriteFileString (FileHandle, output);
  979. WriteFileString (FileHandle, "\r\n");
  980. FreePathString (output);
  981. break;
  982. case 2:
  983. output = DuplicatePathString (enumFiles.szName, 0);
  984. outptr = _mbschr (output, '\\');
  985. if (outptr) {
  986. *outptr = '=';
  987. }
  988. outptr = _mbschr (outptr, '\\');
  989. if (outptr) {
  990. *outptr = ',';
  991. }
  992. WriteFileString (FileHandle, output);
  993. WriteFileString (FileHandle, "\r\n");
  994. FreePathString (output);
  995. break;
  996. case 3:
  997. WriteFileString (FileHandle, enumFiles.szName);
  998. WriteFileString (FileHandle, "=");
  999. MemDbBuildKeyFromOffset (enumFiles.dwValue, outputStr, 1, NULL);
  1000. outptr = _mbschr (outputStr, '\\');
  1001. if (outptr) {
  1002. *outptr = ',';
  1003. }
  1004. if (Type == 4) {
  1005. outptr = _mbschr (outptr, '\\');
  1006. if (outptr) {
  1007. *outptr = ',';
  1008. }
  1009. }
  1010. WriteFileString (FileHandle, outputStr);
  1011. WriteFileString (FileHandle, "\r\n");
  1012. break;
  1013. case 4:
  1014. case 5:
  1015. if (Type == 4) {
  1016. MemDbBuildKey (key, MEMDB_CATEGORY_NT_FILES_DOUBLED_COPY, enumFiles.szName, TEXT("*"), NULL);
  1017. } else {
  1018. MemDbBuildKey (key, MEMDB_CATEGORY_NT_FILES_DOUBLED_DEL, enumFiles.szName, TEXT("*"), NULL);
  1019. }
  1020. if (MemDbEnumFirstValue (
  1021. &enumSubFiles,
  1022. key,
  1023. MEMDB_ALL_SUBLEVELS,
  1024. MEMDB_ENDPOINTS_ONLY
  1025. )) {
  1026. do {
  1027. WriteFileString (FileHandle, enumFiles.szName);
  1028. WriteFileString (FileHandle, "=");
  1029. output = DuplicatePathString (enumSubFiles.szName, 0);
  1030. outptr = _mbschr (output, '\\');
  1031. if (outptr) {
  1032. *outptr = ',';
  1033. }
  1034. WriteFileString (FileHandle, output);
  1035. WriteFileString (FileHandle, "\r\n");
  1036. FreePathString (output);
  1037. } while (MemDbEnumNextValue (&enumSubFiles));
  1038. }
  1039. break;
  1040. }
  1041. } while (MemDbEnumNextValue (&enumFiles));
  1042. *OneItem = TRUE;
  1043. }
  1044. if (LastPartOfGroup) {
  1045. if (*OneItem) {
  1046. WriteFileString (FileHandle, "\r\n\r\n");
  1047. }
  1048. *OneItem = FALSE;
  1049. }
  1050. }
  1051. __finally {
  1052. FreeText (outputStr);
  1053. FreeText (key);
  1054. }
  1055. }
  1056. VOID
  1057. pPrintWarnings (
  1058. VOID
  1059. )
  1060. {
  1061. HANDLE fileHandle;
  1062. MEMDB_ENUM enumFiles,enumFiles1;
  1063. DWORD dontCare;
  1064. PSTR output;
  1065. PSTR outptr;
  1066. PSTR outputStr;
  1067. PSTR key;
  1068. BOOL matchFound;
  1069. __try {
  1070. outputStr = AllocText (MEMDB_MAX);
  1071. key = AllocText (MEMDB_MAX);
  1072. if (!key || !outputStr) {
  1073. __leave;
  1074. }
  1075. fileHandle = CreateFile (g_WarnFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  1076. matchFound = FALSE;
  1077. pPrintWarningGroupPart (
  1078. fileHandle,
  1079. "Files with no directory information in LAYOUT.INF and INTL.INF:\r\n\r\n",
  1080. MEMDB_CATEGORY_NT_FILES_NODIR_COPY "\\*",
  1081. 0,
  1082. FALSE,
  1083. &matchFound
  1084. );
  1085. pPrintWarningGroupPart (
  1086. fileHandle,
  1087. "Files with no directory information in LAYOUT.INF and INTL.INF:\r\n\r\n",
  1088. MEMDB_CATEGORY_NT_FILES_NODIR_DEL "\\*",
  1089. 0,
  1090. TRUE,
  1091. &matchFound
  1092. );
  1093. pPrintWarningGroupPart (
  1094. fileHandle,
  1095. "INF files with section having no directory information:\r\n"
  1096. "(<INF file>=<copy section>)\r\n\r\n",
  1097. MEMDB_CATEGORY_NT_SECT_NODIR "\\*",
  1098. 1,
  1099. TRUE,
  1100. NULL
  1101. );
  1102. pPrintWarningGroupPart (
  1103. fileHandle,
  1104. "INF files with section having unknown directory ID:\r\n"
  1105. "(<INF file>=<copy section>,<dir ID>)\r\n\r\n",
  1106. MEMDB_CATEGORY_NT_SECT_BADDIR "\\*",
  1107. 2,
  1108. TRUE,
  1109. NULL
  1110. );
  1111. pPrintWarningGroupPart (
  1112. fileHandle,
  1113. "INF files with files having no source layout information:\r\n"
  1114. "(<INF file>=<section>,<file>)\r\n\r\n",
  1115. MEMDB_CATEGORY_NT_FILES_NO_LAYOUT "\\*",
  1116. 2,
  1117. TRUE,
  1118. NULL
  1119. );
  1120. pPrintWarningGroupPart (
  1121. fileHandle,
  1122. "Files within copy sections with bad or non-existent dir ID:\r\n"
  1123. "(<file>=<INF file>,<section>[,<dir ID>])\r\n\r\n",
  1124. MEMDB_CATEGORY_NT_FILES_NODIR_OTHER_COPY "\\*",
  1125. 3,
  1126. FALSE,
  1127. &matchFound
  1128. );
  1129. pPrintWarningGroupPart (
  1130. fileHandle,
  1131. "Files within copy sections with bad or non-existent dir ID:\r\n"
  1132. "(<file>=<INF file>,<section>[,<dir ID>])\r\n\r\n",
  1133. MEMDB_CATEGORY_NT_FILES_NODIR_OTHER_DEL "\\*",
  1134. 3,
  1135. TRUE,
  1136. &matchFound
  1137. );
  1138. pPrintWarningGroupPart (
  1139. fileHandle,
  1140. "Duplicate files:\r\n"
  1141. "(<dest file>=<INF file>,<dir ID>)\r\n\r\n",
  1142. MEMDB_CATEGORY_NT_FILES_DOUBLED_IDX_COPY "\\*",
  1143. 4,
  1144. FALSE,
  1145. &matchFound
  1146. );
  1147. pPrintWarningGroupPart (
  1148. fileHandle,
  1149. "Duplicate files:\r\n"
  1150. "(<dest file>=<INF file>,<dir ID>)\r\n\r\n",
  1151. MEMDB_CATEGORY_NT_FILES_DOUBLED_IDX_DEL "\\*",
  1152. 5,
  1153. TRUE,
  1154. &matchFound
  1155. );
  1156. CloseHandle (fileHandle);
  1157. }
  1158. __finally {
  1159. FreeText (outputStr);
  1160. FreeText (key);
  1161. }
  1162. }
  1163. BOOL
  1164. pIsHeaderFile (
  1165. IN PCTSTR FileName,
  1166. OUT PUINT Priority
  1167. )
  1168. {
  1169. PHEADER_FILES headerFile;
  1170. UINT priority = 0xFFFFFFFF;
  1171. BOOL result = FALSE;
  1172. headerFile = g_HeaderFiles;
  1173. while (headerFile) {
  1174. if (IsPatternMatch (headerFile->FilePattern, FileName)) {
  1175. if (priority > headerFile->Priority) {
  1176. priority = headerFile->Priority;
  1177. }
  1178. result = TRUE;
  1179. }
  1180. headerFile = headerFile->Next;
  1181. }
  1182. if (result && Priority) {
  1183. *Priority = priority;
  1184. }
  1185. return result;
  1186. }
  1187. VOID
  1188. pBuildHeaderFilesCategory (
  1189. VOID
  1190. )
  1191. {
  1192. MEMDB_ENUM enumFiles;
  1193. PSTR key;
  1194. PSTR dirName;
  1195. PSTR priorStr;
  1196. PSTR filePtr1 = NULL, filePtr2=NULL;
  1197. PSTR destName;
  1198. PSTR srcName;
  1199. PCSTR infName = NULL;
  1200. UINT Priority;
  1201. INT ExcludeType;
  1202. __try {
  1203. key = AllocText (MEMDB_MAX);
  1204. dirName = AllocText (MEMDB_MAX);
  1205. priorStr = AllocText (MEMDB_MAX);
  1206. destName = AllocText (MEMDB_MAX);
  1207. srcName = AllocText (MEMDB_MAX);
  1208. if (!key || !dirName || !priorStr || !destName || !srcName) {
  1209. __leave;
  1210. }
  1211. MemDbBuildKey (key, MEMDB_CATEGORY_NT_FILES, TEXT("*"), NULL, NULL);
  1212. if (MemDbEnumFirstValue (
  1213. &enumFiles,
  1214. key,
  1215. MEMDB_ALL_SUBLEVELS,
  1216. MEMDB_ENDPOINTS_ONLY
  1217. )) {
  1218. do {
  1219. MemDbBuildKeyFromOffset (enumFiles.dwValue, key, 1, NULL);
  1220. filePtr1 = enumFiles.szName;
  1221. filePtr2 = _mbschr (filePtr1, '\\');
  1222. if (filePtr2 == NULL) {
  1223. DEBUGMSG ((DBG_WARNING, "Bogus name found in NT_FILES: %S", enumFiles.szName));
  1224. continue;
  1225. }
  1226. StringCopyAB (destName, filePtr1, filePtr2);
  1227. filePtr1 = _mbsinc (filePtr2);
  1228. filePtr2 = _mbschr (filePtr1, '\\');
  1229. if (filePtr2 == NULL) {
  1230. DEBUGMSG ((DBG_WARNING, "Bogus name found in NT_FILES: %S", enumFiles.szName));
  1231. continue;
  1232. }
  1233. StringCopyAB (srcName, filePtr1, filePtr2);
  1234. infName = _mbsinc (filePtr2);
  1235. pFixDir (key, dirName);
  1236. ExcludeType = pIsExcludedFile (destName);
  1237. if ((ExcludeType == -1) || (ExcludeType == 1)) {
  1238. if (!pIsExcludedDir (key)) {
  1239. if (pIsHeaderFile (destName, &Priority)) {
  1240. _stprintf (
  1241. key,
  1242. TEXT("%s\\%07ud\\%s\\%s\\%s\\%s"),
  1243. MEMDB_CATEGORY_NT_HEADER_FILES,
  1244. Priority,
  1245. destName,
  1246. srcName,
  1247. infName,
  1248. dirName
  1249. );
  1250. MemDbSetValue (key, 0);
  1251. }
  1252. }
  1253. }
  1254. _stprintf (
  1255. key,
  1256. TEXT("%s\\%s\\%s"),
  1257. MEMDB_CATEGORY_NT_CHECK_FILES,
  1258. srcName,
  1259. destName
  1260. );
  1261. MemDbSetValue (key, 0);
  1262. } while (MemDbEnumNextValue (&enumFiles));
  1263. }
  1264. MemDbBuildKey (key, MEMDB_CATEGORY_NT_KNOWN_FILES, TEXT("*"), NULL, NULL);
  1265. if (MemDbEnumFirstValue (
  1266. &enumFiles,
  1267. key,
  1268. MEMDB_ALL_SUBLEVELS,
  1269. MEMDB_ENDPOINTS_ONLY
  1270. )) {
  1271. do {
  1272. MemDbBuildKeyFromOffset (enumFiles.dwValue, key, 1, NULL);
  1273. filePtr1 = enumFiles.szName;
  1274. //let's skip priority number
  1275. filePtr2 = _mbschr (filePtr1, '\\');
  1276. if (filePtr2 == NULL) {
  1277. DEBUGMSG ((DBG_WARNING, "Bogus name found in NT_FILES: %S", enumFiles.szName));
  1278. continue;
  1279. }
  1280. StringCopyAB (priorStr, filePtr1, filePtr2);
  1281. filePtr1 = _mbsinc (filePtr2);
  1282. filePtr2 = _mbschr (filePtr1, '\\');
  1283. if (filePtr2 == NULL) {
  1284. DEBUGMSG ((DBG_WARNING, "Bogus name found in NT_FILES: %S", enumFiles.szName));
  1285. continue;
  1286. }
  1287. StringCopyAB (destName, filePtr1, filePtr2);
  1288. filePtr1 = _mbsinc (filePtr2);
  1289. filePtr2 = _mbschr (filePtr1, '\\');
  1290. if (filePtr2 == NULL) {
  1291. DEBUGMSG ((DBG_WARNING, "Bogus name found in NT_FILES: %S", enumFiles.szName));
  1292. continue;
  1293. }
  1294. StringCopyAB (srcName, filePtr1, filePtr2);
  1295. infName = _mbsinc (filePtr2);
  1296. pFixDir (key, dirName);
  1297. _stprintf (
  1298. key,
  1299. TEXT("%s\\%s\\%s\\%s\\%s\\%s"),
  1300. MEMDB_CATEGORY_NT_HEADER_FILES,
  1301. priorStr,
  1302. destName,
  1303. srcName,
  1304. infName,
  1305. dirName
  1306. );
  1307. MemDbSetValue (key, 0);
  1308. _stprintf (
  1309. key,
  1310. TEXT("%s\\%s\\%s"),
  1311. MEMDB_CATEGORY_NT_CHECK_FILES,
  1312. srcName,
  1313. destName
  1314. );
  1315. MemDbSetValue (key, 0);
  1316. } while (MemDbEnumNextValue (&enumFiles));
  1317. }
  1318. }
  1319. __finally {
  1320. FreeText (key);
  1321. FreeText (dirName);
  1322. FreeText (priorStr);
  1323. FreeText (destName);
  1324. FreeText (srcName);
  1325. }
  1326. }
  1327. VOID
  1328. pPrintHeaderFileFromCategory (
  1329. IN HANDLE fileHandle,
  1330. IN PCTSTR Category
  1331. )
  1332. {
  1333. MEMDB_ENUM enumFiles, e1;
  1334. PSTR key;
  1335. PCSTR dirName;
  1336. PSTR filePtr1 = NULL, filePtr2=NULL;
  1337. PSTR tempStr;
  1338. PSTR string;
  1339. PSTR string1;
  1340. PSTR stringPtr, stringPtr1;
  1341. DWORD dontCare;
  1342. PSTR destName;
  1343. PSTR srcName;
  1344. PSTR infName;
  1345. __try {
  1346. key = AllocText (MEMDB_MAX);
  1347. tempStr = AllocText (MAX_MBCHAR_PATH);
  1348. string = AllocText (MAX_MBCHAR_PATH);
  1349. string1 = AllocText (MEMDB_MAX);
  1350. destName = AllocText (MEMDB_MAX);
  1351. srcName = AllocText (MEMDB_MAX);
  1352. infName = AllocText (MEMDB_MAX);
  1353. if (!key || !tempStr || !string || !string1 || !destName || !srcName || !infName) {
  1354. __leave;
  1355. }
  1356. MemDbBuildKey (key, Category, TEXT("*"), NULL, NULL);
  1357. if (MemDbEnumFirstValue (
  1358. &enumFiles,
  1359. key,
  1360. MEMDB_ALL_SUBLEVELS,
  1361. MEMDB_ENDPOINTS_ONLY
  1362. )) {
  1363. do {
  1364. filePtr2 = enumFiles.szName;
  1365. //let's skip priority number
  1366. filePtr1 = _mbschr (filePtr2, '\\');
  1367. if (filePtr1 == NULL) {
  1368. DEBUGMSG ((DBG_WARNING, "Bogus name found in NT_FILES: %S", enumFiles.szName));
  1369. continue;
  1370. }
  1371. filePtr1 = _mbsinc (filePtr1);
  1372. filePtr2 = _mbschr (filePtr1, '\\');
  1373. if (filePtr2 == NULL) {
  1374. DEBUGMSG ((DBG_WARNING, "Bogus name found in NT_FILES: %S", enumFiles.szName));
  1375. continue;
  1376. }
  1377. StringCopyAB (destName, filePtr1, filePtr2);
  1378. filePtr1 = _mbsinc (filePtr2);
  1379. filePtr2 = _mbschr (filePtr1, '\\');
  1380. if (filePtr2 == NULL) {
  1381. DEBUGMSG ((DBG_WARNING, "Bogus name found in NT_FILES: %S", enumFiles.szName));
  1382. continue;
  1383. }
  1384. StringCopyAB (srcName, filePtr1, filePtr2);
  1385. filePtr1 = _mbsinc (filePtr2);
  1386. filePtr2 = _mbschr (filePtr1, '\\');
  1387. if (filePtr2 == NULL) {
  1388. DEBUGMSG ((DBG_WARNING, "Bogus name found in NT_FILES: %S", enumFiles.szName));
  1389. continue;
  1390. }
  1391. StringCopyAB (infName, filePtr1, filePtr2);
  1392. //
  1393. // Now let's try to fix the infName if possible
  1394. //
  1395. MemDbBuildKey (key, MEMDB_CATEGORY_NT_CHECK_FILES, infName, TEXT("*"), NULL);
  1396. if (MemDbEnumFirstValue (&e1, key, MEMDB_ALL_SUBLEVELS, MEMDB_ENDPOINTS_ONLY)) {
  1397. StringCopy (infName, e1.szName);
  1398. }
  1399. dirName = _mbsinc (filePtr2);
  1400. if (CountInstancesOfSubString (dirName, "%Platform%")) {
  1401. INFCONTEXT context;
  1402. GROWBUFFER platforms = GROWBUF_INIT;
  1403. UINT index;
  1404. CHAR field [MAX_MBCHAR_PATH];
  1405. MULTISZ_ENUMA platformsEnum;
  1406. PCSTR newDir = NULL;
  1407. if (SetupFindFirstLine (g_AddnlInf, TEXT("FILELIST.MULTIPLEPLATFORMS"), g_Platform, &context)) {
  1408. index = 1;
  1409. while (SetupGetStringField (&context, index, field, MAX_MBCHAR_PATH, NULL)) {
  1410. MultiSzAppend (&platforms, field);
  1411. index++;
  1412. }
  1413. } else {
  1414. MultiSzAppend (&platforms, g_Platform);
  1415. }
  1416. if (EnumFirstMultiSz (&platformsEnum, platforms.Buf)) {
  1417. do {
  1418. newDir = StringSearchAndReplace (dirName, "%Platform%", platformsEnum.CurrentString);
  1419. if (StringIMatch (destName, srcName)) {
  1420. StringCopy (string, " {NULL, ");
  1421. } else {
  1422. sprintf (string, " {L\"%s\", ", srcName);
  1423. }
  1424. sprintf (tempStr, "L\"%s\\%s\", ", newDir, destName);
  1425. StringCat (string, tempStr);
  1426. if (StringIMatch (infName, "LAYOUT.INF") ||
  1427. StringIMatch (infName, "LAYOUT.INF")
  1428. ) {
  1429. StringCopy (tempStr, "NULL},\r\n");
  1430. } else {
  1431. sprintf (tempStr, "L\"%s\"},\r\n", infName);
  1432. }
  1433. StringCat (string, tempStr);
  1434. stringPtr = string;
  1435. stringPtr1= string1;
  1436. while (*stringPtr) {
  1437. if (*stringPtr == '\\') {
  1438. *stringPtr1 = *stringPtr;
  1439. stringPtr1++;
  1440. }
  1441. *stringPtr1 = *stringPtr;
  1442. if (IsLeadByte (*stringPtr)) {
  1443. stringPtr ++;
  1444. stringPtr1 ++;
  1445. *stringPtr1 = *stringPtr;
  1446. }
  1447. stringPtr ++;
  1448. stringPtr1 ++;
  1449. }
  1450. *stringPtr1 = 0;
  1451. WriteFile (fileHandle, string1, GetEndOfStringA (string1) - string1, &dontCare, NULL);
  1452. FreePathString (newDir);
  1453. } while (EnumNextMultiSz (&platformsEnum));
  1454. }
  1455. } else {
  1456. if (StringIMatch (destName, srcName)) {
  1457. StringCopy (string, " {NULL, ");
  1458. } else {
  1459. sprintf (string, " {L\"%s\", ", srcName);
  1460. }
  1461. sprintf (tempStr, "L\"%s\\%s\", ", dirName, destName);
  1462. StringCat (string, tempStr);
  1463. if (StringIMatch (infName, "LAYOUT.INF") ||
  1464. StringIMatch (infName, "LAYOUT.INF")
  1465. ) {
  1466. StringCopy (tempStr, "NULL},\r\n");
  1467. } else {
  1468. sprintf (tempStr, "L\"%s\"},\r\n", infName);
  1469. }
  1470. StringCat (string, tempStr);
  1471. stringPtr = string;
  1472. stringPtr1= string1;
  1473. while (*stringPtr) {
  1474. if (*stringPtr == '\\') {
  1475. *stringPtr1 = *stringPtr;
  1476. stringPtr1++;
  1477. }
  1478. *stringPtr1 = *stringPtr;
  1479. if (IsLeadByte (*stringPtr)) {
  1480. stringPtr ++;
  1481. stringPtr1 ++;
  1482. *stringPtr1 = *stringPtr;
  1483. }
  1484. stringPtr ++;
  1485. stringPtr1 ++;
  1486. }
  1487. *stringPtr1 = 0;
  1488. WriteFile (fileHandle, string1, GetEndOfStringA (string1) - string1, &dontCare, NULL);
  1489. }
  1490. } while (MemDbEnumNextValue (&enumFiles));
  1491. }
  1492. }
  1493. __finally {
  1494. FreeText (key);
  1495. FreeText (tempStr);
  1496. FreeText (string);
  1497. FreeText (string1);
  1498. FreeText (destName);
  1499. FreeText (srcName);
  1500. FreeText (infName);
  1501. }
  1502. }
  1503. VOID
  1504. pPrintHeaderFile (
  1505. VOID
  1506. )
  1507. {
  1508. HANDLE fileHandle;
  1509. CHAR string [MAX_PATH];
  1510. DWORD dontCare;
  1511. printf ("Writing %s...", g_HeaderFile);
  1512. fileHandle = CreateFile (g_HeaderFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  1513. if (fileHandle == INVALID_HANDLE_VALUE) {
  1514. return;
  1515. }
  1516. StringCopyA (string, "PROTECT_FILE_ENTRY ");
  1517. WriteFile (fileHandle, string, GetEndOfStringA (string) - string, &dontCare, NULL);
  1518. StringCopyA (string, g_StructName);
  1519. WriteFile (fileHandle, string, GetEndOfStringA (string) - string, &dontCare, NULL);
  1520. StringCopyA (string, "[] =\r\n");
  1521. WriteFile (fileHandle, string, GetEndOfStringA (string) - string, &dontCare, NULL);
  1522. StringCopyA (string, "{\r\n");
  1523. WriteFile (fileHandle, string, GetEndOfStringA (string) - string, &dontCare, NULL);
  1524. pBuildHeaderFilesCategory ();
  1525. pPrintHeaderFileFromCategory (fileHandle, MEMDB_CATEGORY_NT_HEADER_FILES);
  1526. StringCopyA (string, "};\r\n\r\n");
  1527. WriteFile (fileHandle, string, GetEndOfStringA (string) - string, &dontCare, NULL);
  1528. StringCopyA (string, "#define Count");
  1529. WriteFile (fileHandle, string, GetEndOfStringA (string) - string, &dontCare, NULL);
  1530. StringCopyA (string, g_StructName);
  1531. WriteFile (fileHandle, string, GetEndOfStringA (string) - string, &dontCare, NULL);
  1532. StringCopyA (string, " (sizeof(");
  1533. WriteFile (fileHandle, string, GetEndOfStringA (string) - string, &dontCare, NULL);
  1534. StringCopyA (string, g_StructName);
  1535. WriteFile (fileHandle, string, GetEndOfStringA (string) - string, &dontCare, NULL);
  1536. StringCopyA (string, ")/sizeof(");
  1537. WriteFile (fileHandle, string, GetEndOfStringA (string) - string, &dontCare, NULL);
  1538. StringCopyA (string, g_StructName);
  1539. WriteFile (fileHandle, string, GetEndOfStringA (string) - string, &dontCare, NULL);
  1540. StringCopyA (string, "[0]))\r\n\r\n");
  1541. WriteFile (fileHandle, string, GetEndOfStringA (string) - string, &dontCare, NULL);
  1542. CloseHandle (fileHandle);
  1543. printf ("done\n");
  1544. }
  1545. BOOL
  1546. pGetProperLayoutInf (
  1547. VOID
  1548. )
  1549. {
  1550. DWORD index = 0;
  1551. PCTSTR layoutInfName = NULL;
  1552. PCTSTR partialName = NULL;
  1553. INFCONTEXT context;
  1554. TCHAR productInfDir [MAX_PATH];
  1555. TCHAR UncompressedFile[MAX_PATH];
  1556. if (!SetupFindFirstLine (g_AddnlInf, TEXT("FILELIST.PRODUCTS"), g_Product, &context)) {
  1557. return FALSE;
  1558. }
  1559. if (!SetupGetStringField (&context, 1, productInfDir, MAX_TCHAR_PATH, NULL)) {
  1560. return FALSE;
  1561. }
  1562. partialName = JoinPaths (productInfDir, TEXT("layout.inf"));
  1563. while (index < g_SourceDirectoryCount) {
  1564. layoutInfName = JoinPaths (g_SourceDirectories [index], partialName);
  1565. if (DoesFileExist (layoutInfName)) {
  1566. //
  1567. // copy the file to temporary directory
  1568. //
  1569. StringCopy (UncompressedFile, g_TempDir);
  1570. StringCopy (AppendWack (UncompressedFile), TEXT("layout.inf"));
  1571. CopyFile (layoutInfName, UncompressedFile, FALSE);
  1572. }
  1573. index ++;
  1574. }
  1575. FreePathString (partialName);
  1576. return TRUE;
  1577. }
  1578. DWORD
  1579. pComputeChecksum (
  1580. PCTSTR FullPath
  1581. )
  1582. {
  1583. HANDLE File;
  1584. HANDLE Map;
  1585. PBYTE Data;
  1586. UINT Size;
  1587. UINT u;
  1588. DWORD Checksum = 0;
  1589. Data = MapFileIntoMemory (FullPath, &File, &Map);
  1590. if (!Data) {
  1591. return 0xFFFFFFFF;
  1592. }
  1593. Size = GetFileSize (File, NULL);
  1594. for (u = 0 ; u < Size ; u++) {
  1595. Checksum = _rotl (Checksum, 3);
  1596. Checksum ^= Data[u];
  1597. }
  1598. UnmapFile (Data, Map, File);
  1599. return Checksum;
  1600. }
  1601. VOID
  1602. pDumpFileListDat (
  1603. IN PCSTR DatFile
  1604. )
  1605. {
  1606. HANDLE datHandle;
  1607. PDWORD versionPtr;
  1608. DWORD dontCare;
  1609. BOOL error = TRUE;
  1610. HANDLE datMapping;
  1611. PCSTR p;
  1612. if (!DatFile) {
  1613. fprintf (stderr, "No output file to dump.\n");
  1614. return;
  1615. }
  1616. versionPtr = (PDWORD) MapFileIntoMemory (DatFile, &datHandle, &datMapping);
  1617. if (!versionPtr) {
  1618. fprintf (stderr, "Can't open %s. Error=%u (0x%08X).\n", DatFile, GetLastError(), GetLastError());
  1619. return;
  1620. }
  1621. __try {
  1622. __try {
  1623. if (*versionPtr == 0 || *versionPtr > 3) {
  1624. fprintf (stderr, "Unsupported file format: %s\n", DatFile);
  1625. __leave;
  1626. }
  1627. printf ("Version: %u\n\n", *versionPtr);
  1628. //
  1629. // Version 1: Dump out the normal files
  1630. //
  1631. p = (PCSTR) (&versionPtr[1]);
  1632. if (*p) {
  1633. printf ("Files:\n");
  1634. do {
  1635. printf (" %s", p);
  1636. p = GetEndOfString (p) + 1;
  1637. printf ("\\%s\n", p);
  1638. p = GetEndOfString (p) + 1;
  1639. } while (*p);
  1640. printf ("\n");
  1641. } else {
  1642. printf ("No files to list.\n");
  1643. }
  1644. p++;
  1645. //
  1646. // Version 2: Dump out the excluded files
  1647. //
  1648. if (*versionPtr >= 2 && *p) {
  1649. printf ("Excluded Files:\n");
  1650. do {
  1651. printf (" %s", p);
  1652. p = GetEndOfString (p) + 1;
  1653. printf ("\\%s\n", p);
  1654. p = GetEndOfString (p) + 1;
  1655. } while (*p);
  1656. printf ("\n");
  1657. } else {
  1658. printf ("No excluded files to list.\n");
  1659. }
  1660. p++;
  1661. //
  1662. // Version 3: Dump out the deleted files
  1663. //
  1664. if (*versionPtr >= 3 && *p) {
  1665. printf ("Deleted Files:\n");
  1666. do {
  1667. printf (" %s", p);
  1668. p = GetEndOfString (p) + 1;
  1669. printf ("\\%s\n", p);
  1670. p = GetEndOfString (p) + 1;
  1671. } while (*p);
  1672. printf ("\n");
  1673. } else {
  1674. printf ("No deleted files to list.\n");
  1675. }
  1676. error = FALSE;
  1677. }
  1678. __except (TRUE) {
  1679. fprintf (stderr, "Invalid file format: %s\n", DatFile);
  1680. }
  1681. }
  1682. __finally {
  1683. UnmapFile (versionPtr, datMapping, datHandle);
  1684. }
  1685. return;
  1686. }
  1687. INT
  1688. __cdecl
  1689. main (
  1690. INT argc,
  1691. CHAR *argv[]
  1692. )
  1693. {
  1694. CHAR NtTree[MAX_MBCHAR_PATH];
  1695. CHAR OutputFileBuf[MAX_MBCHAR_PATH];
  1696. CHAR key [MEMDB_MAX];
  1697. DWORD value;
  1698. PSTR OutputFile;
  1699. PSTR p;
  1700. INT i;
  1701. LONG rc;
  1702. PSTR AddnlPtr;
  1703. INFCONTEXT context;
  1704. PCSTR infPath;
  1705. BOOL listSwitch = FALSE;
  1706. MypSetupGetInfSections = (PSETUPGETINFSECTIONS) GetProcAddress(GetModuleHandle("setupapi.dll"), "pSetupGetInfSections");
  1707. if (!MypSetupGetInfSections)
  1708. MypSetupGetInfSections = (PSETUPGETINFSECTIONS) GetProcAddress(GetModuleHandle("setupapi.dll"), "SetupGetInfSections");
  1709. #ifdef DEBUG
  1710. //g_DoLog = TRUE;
  1711. #endif
  1712. //
  1713. // Get environment variables
  1714. //
  1715. p = getenv ("_NT386TREE");
  1716. if (!p || !(*p)) {
  1717. p = getenv ("_NTTREE");
  1718. }
  1719. if (p && *p) {
  1720. StringCopyA (NtTree, p);
  1721. } else {
  1722. StringCopyA (NtTree, ".");
  1723. }
  1724. //
  1725. // Set defaults
  1726. //
  1727. g_TempDir = NULL;
  1728. g_TempDirWack = g_TempDirWackBuf;
  1729. g_WinDir = g_WinDirBuf;
  1730. StringCopyA (OutputFileBuf, NtTree);
  1731. AppendPathWack (OutputFileBuf);
  1732. StringCatA (OutputFileBuf, "filelist.dat");
  1733. OutputFile = OutputFileBuf;
  1734. StringCopyA (g_WarnFileBuf, NtTree);
  1735. AppendPathWack (g_WarnFileBuf);
  1736. StringCatA (g_WarnFileBuf, "DUMP\\FILELIST.WRN");
  1737. g_WarnFile = g_WarnFileBuf;
  1738. StringCopyA (g_HeaderFileBuf, NtTree);
  1739. AppendPathWack (g_HeaderFileBuf);
  1740. StringCatA (g_HeaderFileBuf, "DUMP\\FILELIST.HDR");
  1741. g_HeaderFile = g_HeaderFileBuf;
  1742. StringCopyA (g_PlatformBuf, "X86");
  1743. g_Platform = g_PlatformBuf;
  1744. StringCopyA (g_ProductBuf, "WKS");
  1745. g_Product = g_ProductBuf;
  1746. GetModuleFileName (g_hInst, g_AddnlFileBuf, MAX_MBCHAR_PATH);
  1747. AddnlPtr = (PSTR)GetFileExtensionFromPath (g_AddnlFileBuf);
  1748. if (AddnlPtr) {
  1749. StringCopyA (AddnlPtr, "INF");
  1750. }
  1751. g_AddnlFile = g_AddnlFileBuf;
  1752. //
  1753. // Parse command line
  1754. //
  1755. for (i = 1 ; i < argc ; i++) {
  1756. if (argv[i][0] == '-' || argv[i][0] == '/') {
  1757. switch (tolower (argv[i][1])) {
  1758. case 'i':
  1759. if (argv[i][2] == ':') {
  1760. if (g_SourceDirectoryCount < MAX_SOURCE_COUNT) {
  1761. StringCopy (g_SourceDirectoryBuf[g_SourceDirectoryCount], &argv[i][3]);
  1762. g_SourceDirectories[g_SourceDirectoryCount] = g_SourceDirectoryBuf[g_SourceDirectoryCount];
  1763. g_SourceDirectoryCount++;
  1764. }
  1765. } else if (i + 1 < argc) {
  1766. i++;
  1767. if (g_SourceDirectoryCount < MAX_SOURCE_COUNT) {
  1768. StringCopy (g_SourceDirectoryBuf[g_SourceDirectoryCount], argv[i]);
  1769. g_SourceDirectories[g_SourceDirectoryCount] = g_SourceDirectoryBuf[g_SourceDirectoryCount];
  1770. g_SourceDirectoryCount++;
  1771. }
  1772. } else {
  1773. HelpAndExit();
  1774. }
  1775. break;
  1776. case 'a':
  1777. g_AddnlFileForced = TRUE;
  1778. if (argv[i][2] == ':') {
  1779. g_AddnlFile = &argv[i][3];
  1780. } else if (i + 1 < argc) {
  1781. i++;
  1782. g_AddnlFile = argv[i];
  1783. } else {
  1784. HelpAndExit();
  1785. }
  1786. break;
  1787. case 'o':
  1788. if (argv[i][2] == ':') {
  1789. OutputFile = &argv[i][3];
  1790. } else if (i + 1 < argc) {
  1791. i++;
  1792. OutputFile = argv[i];
  1793. } else {
  1794. HelpAndExit();
  1795. }
  1796. break;
  1797. case 'w':
  1798. g_DoWarnings = TRUE;
  1799. if (argv[i][2] == ':') {
  1800. g_WarnFile = &argv[i][3];
  1801. } else if ((i + 1 < argc) && (argv[i][0] != '/') && (argv[i][0] != '-')) {
  1802. i++;
  1803. g_WarnFile = argv[i];
  1804. }
  1805. break;
  1806. case 'h':
  1807. g_DoHeader = TRUE;
  1808. if (argv[i][2] == ':') {
  1809. g_HeaderFile = &argv[i][3];
  1810. } else if ((i + 1 < argc) && (argv[i][0] != '/') && (argv[i][0] != '-')) {
  1811. i++;
  1812. g_HeaderFile = argv[i];
  1813. }
  1814. break;
  1815. case 'p':
  1816. if (argv[i][2] == ':') {
  1817. g_Platform = &argv[i][3];
  1818. } else if ((i + 1 < argc) && (argv[i][0] != '/') && (argv[i][0] != '-')) {
  1819. i++;
  1820. g_Platform = argv[i];
  1821. }
  1822. break;
  1823. case 'd':
  1824. if (argv[i][2] == ':') {
  1825. g_Product = &argv[i][3];
  1826. } else if ((i + 1 < argc) && (argv[i][0] != '/') && (argv[i][0] != '-')) {
  1827. i++;
  1828. g_Product = argv[i];
  1829. }
  1830. break;
  1831. case 't':
  1832. if (argv[i][2] == ':') {
  1833. g_TempDir = &argv[i][3];
  1834. } else if ((i + 1 < argc) && (argv[i][0] != '/') && (argv[i][0] != '-')) {
  1835. i++;
  1836. g_TempDir = argv[i];
  1837. }
  1838. break;
  1839. case 's':
  1840. if (argv[i][2] == ':') {
  1841. g_StructName = &argv[i][3];
  1842. } else if ((i + 1 < argc) && (argv[i][0] != '/') && (argv[i][0] != '-')) {
  1843. i++;
  1844. g_StructName = argv[i];
  1845. }
  1846. break;
  1847. case 'b':
  1848. if (argv[i][2] == ':') {
  1849. g_InfDatabase = &argv[i][3];
  1850. } else if ((i + 1 < argc) && (argv[i][0] != '/') && (argv[i][0] != '-')) {
  1851. i++;
  1852. g_InfDatabase = argv[i];
  1853. }
  1854. break;
  1855. case 'f':
  1856. g_ForceRescan = TRUE;
  1857. break;
  1858. case 'l':
  1859. listSwitch = TRUE;
  1860. break;
  1861. default:
  1862. HelpAndExit();
  1863. }
  1864. } else {
  1865. HelpAndExit();
  1866. }
  1867. }
  1868. //
  1869. // Init libs
  1870. //
  1871. g_hHeap = GetProcessHeap();
  1872. g_hInst = GetModuleHandle (NULL);
  1873. GetWindowsDirectoryA (g_WinDir, MAX_MBCHAR_PATH);
  1874. if (!MigUtil_Entry (g_hInst, DLL_PROCESS_ATTACH, NULL)) {
  1875. fprintf (stderr, "Initialization error!\n");
  1876. return 254;
  1877. }
  1878. if (!MemDb_Entry (g_hInst, DLL_PROCESS_ATTACH, NULL)) {
  1879. fprintf (stderr, "Initialization error!\n");
  1880. return 254;
  1881. }
  1882. //
  1883. // List mode -- skip right to dumping filelist.dat
  1884. //
  1885. if (listSwitch && g_SourceDirectoryCount == 0) {
  1886. pDumpFileListDat (OutputFile);
  1887. return 0;
  1888. }
  1889. if (g_SourceDirectoryCount == 0) {
  1890. StringCopyA (g_SourceDirectoryBuf[0], NtTree);
  1891. g_SourceDirectories[0] = g_SourceDirectoryBuf[0];
  1892. g_SourceDirectoryCount = 1;
  1893. }
  1894. if (g_InfDatabase && DoesFileExist (g_InfDatabase)) {
  1895. MemDbImport (g_InfDatabase);
  1896. }
  1897. if (!g_AddnlFileForced) {
  1898. // now let's try and find the newest additional file
  1899. // we want to compare time stamps for the one that's in the same dir
  1900. // with filegen.exe and for the one that's on NTTREE\mstools
  1901. WIN32_FIND_DATAA findData1, findData2;
  1902. ULARGE_INTEGER time1, time2;
  1903. StringCopyA (g_AddnlFileAlt, NtTree);
  1904. AppendPathWackA (g_AddnlFileAlt);
  1905. StringCatA (g_AddnlFileAlt, "MSTOOLS\\FILEGEN.INF");
  1906. if (DoesFileExistExA (g_AddnlFileAlt, &findData2)) {
  1907. if (DoesFileExistExA (g_AddnlFileBuf, &findData1)) {
  1908. time1.LowPart = findData1.ftLastWriteTime.dwLowDateTime;
  1909. time1.HighPart = findData1.ftLastWriteTime.dwHighDateTime;
  1910. time2.LowPart = findData2.ftLastWriteTime.dwLowDateTime;
  1911. time2.HighPart = findData2.ftLastWriteTime.dwHighDateTime;
  1912. if (time1.QuadPart < time2.QuadPart) {
  1913. g_AddnlFile = g_AddnlFileAlt;
  1914. }
  1915. } else {
  1916. g_AddnlFile = g_AddnlFileAlt;
  1917. }
  1918. }
  1919. }
  1920. // let's try to see if the additional file changed since our last run
  1921. if (!g_ForceRescan) {
  1922. MemDbBuildKey (key, MEMDB_CATEGORY_SRC_INF_FILES, g_AddnlFile, NULL, NULL);
  1923. if (MemDbGetValue (key, &value)) {
  1924. if (value != pComputeChecksum (g_AddnlFile)) {
  1925. printf ("INF changed -- rescanning\n");
  1926. g_ForceRescan = TRUE;
  1927. }
  1928. }
  1929. }
  1930. if (g_DoHeader) {
  1931. if (!g_StructName) {
  1932. g_StructName = g_StructNameBuf;
  1933. }
  1934. }
  1935. if (g_AddnlFile == NULL) {
  1936. HelpAndExit();
  1937. } else {
  1938. g_AddnlInf = SetupOpenInfFile (g_AddnlFile, NULL, INF_STYLE_OLDNT|INF_STYLE_WIN4, NULL);
  1939. if (g_AddnlInf == INVALID_HANDLE_VALUE) {
  1940. fprintf (stderr, "Could not open %s, error:%d", g_AddnlFile, GetLastError());
  1941. return 254;
  1942. }
  1943. }
  1944. // validate platform
  1945. if (!SetupFindFirstLine (g_AddnlInf, TEXT("FILELIST.PLATFORMS"), g_Platform, &context)) {
  1946. fprintf (stderr, "Invalid platform: %s", g_Platform);
  1947. return 254;
  1948. }
  1949. // validate product
  1950. if (!SetupFindFirstLine (g_AddnlInf, TEXT("FILELIST.PRODUCTS"), g_Product, &context)) {
  1951. fprintf (stderr, "Invalid product type: %s", g_Product);
  1952. return 254;
  1953. }
  1954. //
  1955. // get Temp dir
  1956. //
  1957. if (g_TempDir) {
  1958. StringCopyA (g_TempDirBuf, g_TempDir);
  1959. g_TempDir = g_TempDirBuf;
  1960. } else {
  1961. g_TempDir = g_TempDirBuf;
  1962. GetTempPathA (MAX_MBCHAR_PATH, g_TempDir);
  1963. StringCopy (AppendWack (g_TempDirBuf), g_Product);
  1964. }
  1965. StringCopyA (g_TempDirWack, g_TempDir);
  1966. AppendWack (g_TempDirWack);
  1967. g_TempDirWackChars = CharCountA (g_TempDirWack);
  1968. if (!CreateDirectory (g_TempDir, NULL)) {
  1969. DWORD error;
  1970. error = GetLastError ();
  1971. if (error != ERROR_ALREADY_EXISTS) {
  1972. fprintf (stderr, "Cannot create temporary directory. Error: %d", error);
  1973. return 254;
  1974. }
  1975. }
  1976. printf ("Input path(s) : ");
  1977. {
  1978. DWORD index = 0;
  1979. while (index < g_SourceDirectoryCount) {
  1980. if (index == 0) {
  1981. printf ("'%s'\n", g_SourceDirectories [index]);
  1982. } else {
  1983. printf (" '%s'\n", g_SourceDirectories [index]);
  1984. }
  1985. index ++;
  1986. }
  1987. }
  1988. printf ("Output file : '%s'\n", OutputFile);
  1989. printf ("Temporary dir : '%s'\n", g_TempDir);
  1990. if (g_DoWarnings) {
  1991. printf ("Warnings : '%s'\n", g_WarnFile);
  1992. }
  1993. if (g_DoHeader) {
  1994. printf ("Header file : '%s'\n", g_HeaderFile);
  1995. }
  1996. printf ("Additional file : '%s'\n", g_AddnlFile);
  1997. printf ("Platform : '%s'\n", g_Platform);
  1998. printf ("Product : '%s'\n", g_Product);
  1999. if (g_InfDatabase) {
  2000. printf ("Rescan database : '%s'\n", g_InfDatabase);
  2001. }
  2002. printf ("\n");
  2003. //
  2004. // Build filelist.dat
  2005. //
  2006. DISABLETRACKCOMMENT();
  2007. g_TempPool = PoolMemInitNamedPool ("filegen");
  2008. PoolMemDisableTracking (g_TempPool);
  2009. if (!pLoadExcludedFiles (g_AddnlInf)) {
  2010. rc = GetLastError();
  2011. fprintf (stderr, "Could not read %s. Win32 Error Code: %x\n", g_AddnlFile, rc);
  2012. return 2;
  2013. }
  2014. if (!pLoadForcedFiles (g_AddnlInf)) {
  2015. rc = GetLastError();
  2016. fprintf (stderr, "Could not read %s. Win32 Error Code: %x\n", g_AddnlFile, rc);
  2017. return 2;
  2018. }
  2019. if (!pLoadRenamedDirs (g_AddnlInf)) {
  2020. rc = GetLastError();
  2021. fprintf (stderr, "Could not read %s. Win32 Error Code: %x\n", g_AddnlFile, rc);
  2022. return 2;
  2023. }
  2024. if (!pLoadHeaderFiles (g_AddnlInf)) {
  2025. rc = GetLastError();
  2026. fprintf (stderr, "Could not read %s. Win32 Error Code: %x\n", g_AddnlFile, rc);
  2027. return 2;
  2028. }
  2029. if (!pCreateExcludedInfsTable (g_AddnlInf)) {
  2030. rc = GetLastError();
  2031. fprintf (stderr, "Could not read %s. Win32 Error Code: %x\n", g_AddnlFile, rc);
  2032. return 2;
  2033. }
  2034. if (!pCreatePrivateIdInfsTable (g_AddnlInf)) {
  2035. rc = GetLastError();
  2036. fprintf (stderr, "Could not read %s. Win32 Error Code: %x\n", g_AddnlFile, rc);
  2037. return 2;
  2038. }
  2039. if (!pLoadExcludedDirs (g_AddnlInf)) {
  2040. rc = GetLastError();
  2041. fprintf (stderr, "Could not read %s. Win32 Error Code: %x\n", g_AddnlFile, rc);
  2042. return 2;
  2043. }
  2044. if (!pLoadIgnoredDirs (g_AddnlInf)) {
  2045. rc = GetLastError();
  2046. fprintf (stderr, "Could not read %s. Win32 Error Code: %x\n", g_AddnlFile, rc);
  2047. return 2;
  2048. }
  2049. // let's try to see if any INF files changed since our last run
  2050. if (!g_ForceRescan) {
  2051. printf ("Checking INF changes\n");
  2052. if (!pShouldRescanInfs (g_SourceDirectories, g_SourceDirectoryCount)) {
  2053. printf ("No INF file changes. Tool will not run\n");
  2054. return 0;
  2055. }
  2056. }
  2057. MemDbDeleteTree (MEMDB_CATEGORY_SRC_INF_FILES);
  2058. MemDbBuildKey (key, MEMDB_CATEGORY_SRC_INF_FILES, g_AddnlFile, NULL, NULL);
  2059. MemDbSetValue (key, pComputeChecksum (g_AddnlFile));
  2060. //
  2061. // load the INFs
  2062. //
  2063. printf ("Finding all INFs\n");
  2064. if (!LocalGetFileNames (g_SourceDirectories, g_SourceDirectoryCount, FALSE)) {
  2065. fprintf (stderr, "ERROR: Cannot get INF file list\n");
  2066. DEBUGMSG ((DBG_WARNING, "NTFILELIST: Can't get INF file names"));
  2067. LocalFreeFileNames (FALSE);
  2068. return 3;
  2069. }
  2070. SetFileAttributes (OutputFile, FILE_ATTRIBUTE_NORMAL);
  2071. if (!DeleteFile (OutputFile)) {
  2072. if ((GetLastError() != ERROR_FILE_NOT_FOUND) &&
  2073. (GetLastError() != ERROR_PATH_NOT_FOUND)
  2074. ) {
  2075. fprintf (stderr, "DeleteFile failed for %s. Win32 Error Code: %x\n",
  2076. OutputFile, GetLastError ());
  2077. LocalFreeFileNames (FALSE);
  2078. return 252;
  2079. }
  2080. }
  2081. if (g_DoWarnings) {
  2082. SetFileAttributes (g_WarnFile, FILE_ATTRIBUTE_NORMAL);
  2083. if (!DeleteFile (g_WarnFile)) {
  2084. if ((GetLastError() != ERROR_FILE_NOT_FOUND) &&
  2085. (GetLastError() != ERROR_PATH_NOT_FOUND)
  2086. ) {
  2087. fprintf (stderr, "DeleteFile failed for %s. Win32 Error Code: %x\n",
  2088. g_WarnFile, GetLastError ());
  2089. LocalFreeFileNames (FALSE);
  2090. return 252;
  2091. }
  2092. }
  2093. }
  2094. if (g_DoHeader) {
  2095. SetFileAttributes (g_HeaderFile, FILE_ATTRIBUTE_NORMAL);
  2096. if (!DeleteFile (g_HeaderFile)) {
  2097. if ((GetLastError() != ERROR_FILE_NOT_FOUND) &&
  2098. (GetLastError() != ERROR_PATH_NOT_FOUND)
  2099. ) {
  2100. fprintf (stderr, "DeleteFile failed for %s. Win32 Error Code: %x\n",
  2101. g_HeaderFile, GetLastError ());
  2102. LocalFreeFileNames (FALSE);
  2103. return 252;
  2104. }
  2105. }
  2106. }
  2107. //
  2108. // now let's try to find the proper layout.inf
  2109. // We will look into all source directories for a subdir with the name of the
  2110. // product we are processing (for ENT is ENTINF etc.) and try to find layout.inf
  2111. // there.
  2112. //
  2113. pGetProperLayoutInf ();
  2114. printf ("Reading NT file list (layout.inf)\n");
  2115. infPath = JoinPaths (g_TempDir, "layout.inf");
  2116. if (!pLocalReadNtFiles (infPath)) {
  2117. rc = GetLastError();
  2118. printf ("Could not read %s. Win32 Error Code: %x\n", infPath, rc);
  2119. LocalFreeFileNames (FALSE);
  2120. return 3;
  2121. }
  2122. FreePathString (infPath);
  2123. printf ("Reading NT file list (intl.inf)\n");
  2124. infPath = JoinPaths (g_TempDir, "intl.inf");
  2125. if (!pLocalReadNtFiles (infPath)) {
  2126. rc = GetLastError();
  2127. printf ("Could not read %s. Win32 Error Code: %x\n", infPath, rc);
  2128. LocalFreeFileNames (FALSE);
  2129. return 3;
  2130. }
  2131. FreePathString (infPath);
  2132. if (!pCreateNtFileList (OutputFile)) {
  2133. rc = GetLastError();
  2134. printf ("Could not build complete filelist. Win32 Error Code: %x\n", rc);
  2135. LocalFreeFileNames (FALSE);
  2136. return 3;
  2137. } else {
  2138. printf ("%s was built successfully.\n", OutputFile);
  2139. if (listSwitch) {
  2140. pDumpFileListDat (OutputFile);
  2141. }
  2142. }
  2143. if (g_DoWarnings) {
  2144. pPrintWarnings ();
  2145. }
  2146. if (g_DoHeader) {
  2147. pLoadKnownFiles (g_AddnlInf, TRUE);
  2148. pPrintHeaderFile ();
  2149. }
  2150. HtFree (g_ExcludedInfsTable);
  2151. if (g_AddnlInf != INVALID_HANDLE_VALUE) {
  2152. SetupCloseInfFile (g_AddnlInf);
  2153. }
  2154. LocalFreeFileNames (FALSE);
  2155. ENABLETRACKCOMMENT();
  2156. //
  2157. // Terminate libs
  2158. //
  2159. PoolMemEmptyPool (g_TempPool);
  2160. PoolMemDestroyPool (g_TempPool);
  2161. if (!MemDb_Entry (g_hInst, DLL_PROCESS_DETACH, NULL)) {
  2162. fprintf (stderr, "Termination error!\n");
  2163. return 253;
  2164. }
  2165. if (!MigUtil_Entry (g_hInst, DLL_PROCESS_DETACH, NULL)) {
  2166. fprintf (stderr, "Termination error!\n");
  2167. return 253;
  2168. }
  2169. return 0;
  2170. }
  2171. typedef struct _KNOWN_DIRS {
  2172. PCSTR DirId;
  2173. PCSTR DirValue;
  2174. }
  2175. KNOWN_DIRS, *PKNOWN_DIRS;
  2176. KNOWN_DIRS g_LocalKnownDirs [] = {
  2177. {"10" , "%systemroot%"},
  2178. {"11" , "%systemroot%\\system32"},
  2179. {"12" , "%systemroot%\\system32\\drivers"},
  2180. {"17" , "%systemroot%\\inf"},
  2181. {"18" , "%systemroot%\\help"},
  2182. {"20" , "%systemroot%\\fonts"},
  2183. {"21" , "%systemroot%\\system32\\viewers"},
  2184. {"23" , "%systemroot%\\system32\\spool\\drivers\\color"},
  2185. {"24" , "%systemdrive%"},
  2186. {"25" , "%systemroot%"},
  2187. {"30" , "%systemdrive%"},
  2188. {"50" , "%systemroot%\\system"},
  2189. {"51" , "%systemroot%\\system32\\spool"},
  2190. {"52" , "%systemroot%\\system32\\spool\\drivers"},
  2191. {"53" , "%systemdrive%\\Documents and Settings"},
  2192. {"54" , "%systemdrive%"},
  2193. {"55" , "%systemroot%\\system32\\spool\\prtprocs"},
  2194. {"16422", "%ProgramFiles%"},
  2195. {"16427", "%commonprogramfiles%"},
  2196. {"16428", "%commonprogramfiles(x86)%"},
  2197. {"XX001", "%ProgramFilesX86%"},
  2198. {"66000", "%systemroot%\\system32\\spool\\drivers\\W32%Platform%\\3"},
  2199. {"66002", "%systemroot%\\system32"},
  2200. {"66003", "%systemroot%\\system32\\spool\\drivers\\color"},
  2201. {NULL, NULL}
  2202. };
  2203. typedef struct _CONVERT_DIRS {
  2204. PCSTR SifDir;
  2205. PCSTR SetupDir;
  2206. }
  2207. CONVERT_DIRS, *PCONVERT_DIRS;
  2208. CONVERT_DIRS g_LocalConvertDirs [] = {
  2209. {"1", "10"},
  2210. {"2", "11"},
  2211. {"3", "11\\config"},
  2212. {"4", "12"},
  2213. {"5", "50"},
  2214. {"6", "11\\os2"},
  2215. {"7", "11\\ras"},
  2216. {"8", "11\\os2\\dll"},
  2217. {"9", "51"},
  2218. {"10", "52"},
  2219. {"11", "66000"},
  2220. {"12", "55"},
  2221. {"14", "11\\wins"},
  2222. {"15", "11\\dhcp"},
  2223. {"16", "10\\repair"},
  2224. {"17", "12\\etc"},
  2225. {"20", "17"},
  2226. {"21", "18"},
  2227. {"22", "20"},
  2228. {"23", "10\\config"},
  2229. {"24", "10\\msagent\\intl"},
  2230. {"25", "10\\Cursors"},
  2231. {"26", "10\\Media"},
  2232. {"27", "10\\java"},
  2233. {"28", "10\\java\\classes"},
  2234. {"29", "10\\java\\trustlib"},
  2235. {"30", "11\\ShellExt"},
  2236. {"31", "10\\Web"},
  2237. {"32", "11\\Setup"},
  2238. {"33", "10\\Web\\printers"},
  2239. {"34", "66003"},
  2240. {"35", "11\\wbem"},
  2241. {"36", "11\\wbem\\Repository"},
  2242. {"37", "10\\addins"},
  2243. {"38", "10\\Connection Wizard"},
  2244. {"40", "10\\security"},
  2245. {"41", "10\\security\\templates"},
  2246. {"42", "11\\npp"},
  2247. {"43", "11\\ias"},
  2248. {"44", "11\\dllcache"},
  2249. {"45", "10\\Temp"},
  2250. {"46", "10\\Web\\printers\\images"},
  2251. {"47", "11\\export"},
  2252. {"48", "11\\wbem\\mof\\good"},
  2253. {"49", "11\\wbem\\mof\\bad"},
  2254. {"50", "10\\twain_32"},
  2255. {"51", "10\\msapps\\msinfo"},
  2256. {"52", "10\\msagent"},
  2257. {"53", "10\\msagent\\chars"},
  2258. {"54", "10\\security\\logs"},
  2259. {NULL, NULL}
  2260. };
  2261. VOID
  2262. pConvertSIFDir (
  2263. IN OUT PSTR Dir
  2264. )
  2265. {
  2266. PCONVERT_DIRS p = g_LocalConvertDirs;
  2267. while (p->SifDir) {
  2268. if (StringIMatch (Dir, p->SifDir)) {
  2269. StringCopy (Dir, p->SetupDir);
  2270. return;
  2271. }
  2272. p++;
  2273. }
  2274. }
  2275. typedef struct _INF_DIRS {
  2276. PCSTR InfName;
  2277. PCSTR DirId;
  2278. PCSTR DirValue;
  2279. } INF_DIRS, *PINF_DIRS;
  2280. BOOL
  2281. pCheckIdDir (
  2282. IN PCSTR IdDir
  2283. )
  2284. {
  2285. PKNOWN_DIRS currDir = g_LocalKnownDirs;
  2286. while (currDir->DirId) {
  2287. if (StringIMatch (currDir->DirId, IdDir)) {
  2288. return TRUE;
  2289. }
  2290. currDir++;
  2291. }
  2292. return FALSE;
  2293. }
  2294. BOOL
  2295. pCheckInfIdDir (
  2296. IN PCSTR InfName,
  2297. OUT PSTR IdDir
  2298. )
  2299. {
  2300. PPRIVATE_ID_INFS privateIdInfs;
  2301. if (HtFindStringAndData (g_PrivateIdInfsTable, InfName, &privateIdInfs)) {
  2302. while (privateIdInfs) {
  2303. if (StringIMatch (privateIdInfs->PrivateId, IdDir)) {
  2304. StringCopy (IdDir, privateIdInfs->EquivalentId);
  2305. return TRUE;
  2306. }
  2307. privateIdInfs = privateIdInfs->Next;
  2308. }
  2309. }
  2310. return FALSE;
  2311. }
  2312. VOID
  2313. pMinimizeIdPath (
  2314. IN PCSTR SourceDirectoryWithLdirId,
  2315. OUT PSTR DestDirectoryWithLdirId
  2316. )
  2317. {
  2318. PSTR temp;
  2319. PKNOWN_DIRS knownDir;
  2320. UINT thisSize;
  2321. UINT bestSize = 0;
  2322. PKNOWN_DIRS bestMatch = NULL;
  2323. PCSTR end;
  2324. __try {
  2325. temp = AllocText (MAX_PATH);
  2326. if (!temp) {
  2327. __leave;
  2328. }
  2329. //
  2330. // Search for the longest match
  2331. //
  2332. pFixDir (SourceDirectoryWithLdirId, temp);
  2333. knownDir = g_LocalKnownDirs;
  2334. while (knownDir->DirId) {
  2335. thisSize = TcharCount (knownDir->DirValue);
  2336. if (thisSize > bestSize) {
  2337. end = temp + thisSize;
  2338. if (*end == 0 || *end == '\\') {
  2339. if (StringIPrefix (temp, knownDir->DirValue)) {
  2340. bestMatch = knownDir;
  2341. bestSize = thisSize;
  2342. }
  2343. }
  2344. }
  2345. knownDir++;
  2346. }
  2347. //
  2348. // Copy the shortest path to the caller's buffer
  2349. //
  2350. if (bestMatch) {
  2351. end = temp + bestSize;
  2352. StringCopy (DestDirectoryWithLdirId, bestMatch->DirId);
  2353. if (end) {
  2354. StringCat (DestDirectoryWithLdirId, end);
  2355. }
  2356. } else {
  2357. StringCopy (DestDirectoryWithLdirId, SourceDirectoryWithLdirId);
  2358. }
  2359. }
  2360. __finally {
  2361. FreeText (temp);
  2362. }
  2363. }
  2364. PSTR
  2365. pReadDestDir (
  2366. IN PCSTR FileName,
  2367. IN PCSTR Section,
  2368. IN HINF FileHandle,
  2369. IN PGROWBUFFER LayoutFiles,
  2370. OUT PDWORD badOffset
  2371. )
  2372. {
  2373. INFSTRUCT context = INITINFSTRUCT_POOLHANDLE;
  2374. MULTISZ_ENUMA layoutFilesEnum;
  2375. PCSTR localLayoutFile = NULL;
  2376. HINF infHandle;
  2377. PSTR idDir;
  2378. PSTR idDirPtr;
  2379. PSTR subDir;
  2380. PSTR result = NULL;
  2381. PSTR srcDir, destDir, wildCharPtr;
  2382. PSTR resultTmp = NULL;
  2383. PRENAMED_DIRS renamedDir;
  2384. BOOL found;
  2385. *badOffset = 0;
  2386. __try {
  2387. idDir = AllocText (MEMDB_MAX);
  2388. if (!idDir) {
  2389. __leave;
  2390. }
  2391. if (InfFindFirstLine (FileHandle, "DestinationDirs", (Section[0]=='@')?(Section+1):Section, &context) ||
  2392. InfFindFirstLine (FileHandle, "DestinationDirs", "DefaultDestDir", &context)
  2393. ) {
  2394. idDirPtr = pGetNonEmptyField (&context, 1);
  2395. if (idDirPtr) {
  2396. StringCopy (idDir, idDirPtr);
  2397. } else {
  2398. idDir [0] = 0;
  2399. }
  2400. subDir = pGetNonEmptyField (&context, 2);
  2401. if (!pCheckIdDir (idDir)) {
  2402. if (!pCheckInfIdDir (GetFileNameFromPath (FileName), idDir)) {
  2403. DEBUGMSG ((DBG_WARNING, "Directory ID not found for %s in %s", Section, GetFileNameFromPath (FileName)));
  2404. if (g_DoWarnings) {
  2405. MemDbSetValueEx (MEMDB_CATEGORY_NT_SECT_BADDIR, GetFileNameFromPath (FileName), Section, idDir, 0, badOffset);
  2406. }
  2407. result = NULL;
  2408. __leave;
  2409. }
  2410. }
  2411. if (subDir != NULL) {
  2412. result = JoinPaths (idDir, subDir);
  2413. }
  2414. else {
  2415. result = DuplicatePathString (idDir, 0);
  2416. }
  2417. __leave;
  2418. }
  2419. if (LayoutFiles) {
  2420. if (EnumFirstMultiSz (&layoutFilesEnum, LayoutFiles->Buf)) {
  2421. do {
  2422. localLayoutFile = JoinPaths (g_TempDir, layoutFilesEnum.CurrentString);
  2423. infHandle = pOpenInfWithCache (localLayoutFile);
  2424. if (infHandle != INVALID_HANDLE_VALUE) {
  2425. result = pReadDestDir (FileName, Section, infHandle, NULL, badOffset);
  2426. pCloseInfWithCache (infHandle);
  2427. if (result != NULL) {
  2428. FreePathString (localLayoutFile);
  2429. __leave;
  2430. }
  2431. }
  2432. FreePathString (localLayoutFile);
  2433. } while (EnumNextMultiSz (&layoutFilesEnum));
  2434. }
  2435. }
  2436. DEBUGMSG ((DBG_WARNING, "No directory found for %s in %s", Section, GetFileNameFromPath (FileName)));
  2437. if (g_DoWarnings) {
  2438. MemDbSetValueEx (MEMDB_CATEGORY_NT_SECT_NODIR, GetFileNameFromPath (FileName), Section, NULL, 0, badOffset);
  2439. }
  2440. }
  2441. __finally {
  2442. if (result != NULL) {
  2443. // let's do some dir replacement here
  2444. found = TRUE;
  2445. while (found) {
  2446. renamedDir = g_RenamedDirs;
  2447. found = FALSE;
  2448. while ((!found) && renamedDir) {
  2449. if (IsPatternMatch (renamedDir->SrcDir, result)) {
  2450. srcDir = DuplicatePathString (renamedDir->SrcDir, 0);
  2451. destDir = DuplicatePathString (renamedDir->DestDir, 0);
  2452. wildCharPtr = _tcschr (srcDir, TEXT('*'));
  2453. if (wildCharPtr) {
  2454. *wildCharPtr = 0;
  2455. }
  2456. wildCharPtr = _tcschr (destDir, TEXT('*'));
  2457. if (wildCharPtr) {
  2458. *wildCharPtr = 0;
  2459. }
  2460. MYASSERT (!StringIPrefix (srcDir, destDir));
  2461. MYASSERT (!StringIPrefix (destDir, srcDir));
  2462. resultTmp = (PSTR)StringSearchAndReplace (result, srcDir, destDir);
  2463. if (resultTmp) {
  2464. FreePathString (result);
  2465. result = resultTmp;
  2466. found = TRUE;
  2467. }
  2468. FreePathString (destDir);
  2469. FreePathString (srcDir);
  2470. }
  2471. renamedDir = renamedDir->Next;
  2472. }
  2473. }
  2474. }
  2475. InfCleanUpInfStruct (&context);
  2476. FreeText (idDir);
  2477. }
  2478. return result;
  2479. }
  2480. PTSTR
  2481. pGetAdditionalLocation (
  2482. IN PCTSTR DestFile
  2483. )
  2484. {
  2485. INFCONTEXT context;
  2486. TCHAR field [MAX_MBCHAR_PATH];
  2487. if (g_AddnlInf == INVALID_HANDLE_VALUE) {
  2488. return NULL;
  2489. }
  2490. if (SetupFindFirstLine (g_AddnlInf, SECT_KNOWN_LOCATION, DestFile, &context)) {
  2491. if (SetupGetStringField (&context, 1, field, MAX_MBCHAR_PATH, NULL)) {
  2492. return (DuplicatePathString (field, 0));
  2493. }
  2494. }
  2495. return NULL;
  2496. }
  2497. BOOL
  2498. pFixDir (
  2499. IN PCSTR src,
  2500. OUT PSTR dest
  2501. )
  2502. {
  2503. PSTR tempPtr;
  2504. PKNOWN_DIRS knownDir;
  2505. BOOL result = FALSE;
  2506. PSTR temp;
  2507. __try {
  2508. temp = AllocText (MEMDB_MAX);
  2509. if (!temp) {
  2510. __leave;
  2511. }
  2512. *dest = 0;
  2513. tempPtr = _mbschr (src, '\\');
  2514. if (tempPtr) {
  2515. StringCopyABA (temp, src, tempPtr);
  2516. } else {
  2517. StringCopy (temp, src);
  2518. }
  2519. knownDir = g_LocalKnownDirs;
  2520. while (knownDir->DirId) {
  2521. if (StringIMatch (temp, knownDir->DirId)) {
  2522. StringCopy (dest, knownDir->DirValue);
  2523. break;
  2524. }
  2525. knownDir ++;
  2526. }
  2527. if (*dest == 0) {
  2528. __leave;
  2529. }
  2530. if (tempPtr) {
  2531. StringCat (dest, tempPtr);
  2532. }
  2533. result = TRUE;
  2534. }
  2535. __finally {
  2536. FreeText (temp);
  2537. }
  2538. return result;
  2539. }
  2540. BOOL
  2541. DoDirsMatch (
  2542. IN DWORD Offset1,
  2543. IN DWORD Offset2
  2544. )
  2545. {
  2546. PSTR dir1;
  2547. PSTR fixedDir1;
  2548. PSTR dir2;
  2549. PSTR fixedDir2;
  2550. BOOL result = FALSE;
  2551. dir1 = AllocText (MEMDB_MAX);
  2552. fixedDir1 = AllocText (MEMDB_MAX);
  2553. dir2 = AllocText (MEMDB_MAX);
  2554. fixedDir2 = AllocText (MEMDB_MAX);
  2555. if (dir1 && fixedDir1 && dir2 && fixedDir2) {
  2556. if (MemDbBuildKeyFromOffset (Offset1, dir1, 1, NULL) &&
  2557. MemDbBuildKeyFromOffset (Offset2, dir2, 1, NULL) &&
  2558. pFixDir (dir1, fixedDir1) &&
  2559. pFixDir (dir2, fixedDir1)
  2560. ) {
  2561. result = StringIMatch (fixedDir1, fixedDir2);
  2562. }
  2563. }
  2564. FreeText (dir1);
  2565. FreeText (fixedDir1);
  2566. FreeText (dir2);
  2567. FreeText (fixedDir2);
  2568. return result;
  2569. }
  2570. PCSTR
  2571. pGetLayoutInfFile (
  2572. IN PCSTR FileName,
  2573. IN HINF FileHandle,
  2574. IN PGROWBUFFER LayoutFiles,
  2575. IN PCSTR SrcName
  2576. )
  2577. {
  2578. INFSTRUCT context = INITINFSTRUCT_POOLHANDLE;
  2579. MULTISZ_ENUMA layoutFilesEnum;
  2580. HINF layoutHandle;
  2581. CHAR sectName [MAX_PATH];
  2582. PCSTR result = NULL;
  2583. PCSTR layoutFile = NULL;
  2584. PCSTR localLayoutFile = NULL;
  2585. GROWBUFFER layoutFiles = GROWBUF_INIT;
  2586. UINT fieldIdx = 0;
  2587. StringCopy (sectName, "SourceDisksFiles");
  2588. if (InfFindFirstLine (FileHandle, sectName, SrcName, &context)) {
  2589. InfCleanUpInfStruct (&context);
  2590. result = DuplicatePathString (GetFileNameFromPath (FileName), 0);
  2591. }
  2592. if (!result) {
  2593. StringCat (sectName, ".");
  2594. StringCat (sectName, g_Platform);
  2595. if (InfFindFirstLine (FileHandle, sectName, SrcName, &context)) {
  2596. InfCleanUpInfStruct (&context);
  2597. result = DuplicatePathString (GetFileNameFromPath (FileName), 0);
  2598. }
  2599. }
  2600. if (!result) {
  2601. if (LayoutFiles) {
  2602. if (EnumFirstMultiSz (&layoutFilesEnum, LayoutFiles->Buf)) {
  2603. do {
  2604. localLayoutFile = JoinPaths (g_TempDir, layoutFilesEnum.CurrentString);
  2605. layoutHandle = pOpenInfWithCache (localLayoutFile);
  2606. if (layoutHandle != INVALID_HANDLE_VALUE) {
  2607. // get all layout files in a multisz
  2608. if (InfFindFirstLine (layoutHandle, "Version", "LayoutFile", &context)) {
  2609. fieldIdx = 1;
  2610. layoutFile = pGetNonEmptyField (&context, fieldIdx);
  2611. while (layoutFile) {
  2612. MultiSzAppend (&layoutFiles, layoutFile);
  2613. fieldIdx ++;
  2614. layoutFile = pGetNonEmptyField (&context, fieldIdx);
  2615. }
  2616. InfCleanUpInfStruct (&context);
  2617. }
  2618. result = pGetLayoutInfFile (layoutFilesEnum.CurrentString, layoutHandle, &layoutFiles, SrcName);
  2619. pCloseInfWithCache (layoutHandle);
  2620. if (result != NULL) {
  2621. FreeGrowBuffer (&layoutFiles);
  2622. FreePathString (localLayoutFile);
  2623. break;
  2624. }
  2625. FreeGrowBuffer (&layoutFiles);
  2626. } else {
  2627. //MessageBox (NULL, "Layout", "Layout", MB_OK);
  2628. }
  2629. FreePathString (localLayoutFile);
  2630. } while (EnumNextMultiSz (&layoutFilesEnum));
  2631. }
  2632. }
  2633. }
  2634. InfCleanUpInfStruct (&context);
  2635. return result;
  2636. }
  2637. //
  2638. // Use globals for highly used memory allocations (to avoid reallocs)
  2639. //
  2640. typedef enum {
  2641. ST_COPYFILES,
  2642. ST_DELFILES
  2643. } SECTIONTYPE;
  2644. VOID
  2645. pProcessCopyFileSpec (
  2646. IN PCSTR InfFileName,
  2647. IN HINF InfFileHandle,
  2648. IN PCSTR InfSection,
  2649. IN PCSTR SrcFile, OPTIONAL
  2650. IN PCSTR DestDirectory,
  2651. IN PCSTR DestFile,
  2652. IN BOOL NoDestDirSpec,
  2653. IN DWORD NoDirOffset,
  2654. IN PGROWBUFFER LayoutFilesBuf
  2655. )
  2656. {
  2657. BOOL twice = FALSE;
  2658. BOOL removeExistingEntry = FALSE;
  2659. BOOL outputFile = TRUE;
  2660. PSTR key;
  2661. MEMDB_ENUM enumFiles;
  2662. DWORD offset;
  2663. PCSTR layoutInfFile;
  2664. PCSTR finalDestDir;
  2665. PSTR tmpDest;
  2666. __try {
  2667. key = AllocText (MEMDB_MAX);
  2668. if (!key) {
  2669. __leave;
  2670. }
  2671. //
  2672. // If DestFile has a subpath, join it with DestDirectory
  2673. //
  2674. if (_mbschr (DestFile, '\\')) {
  2675. //
  2676. // This dest file has a dir in it. Join it with the root,
  2677. // then recompute the file name ptr.
  2678. //
  2679. finalDestDir = JoinPaths (DestDirectory, DestFile);
  2680. tmpDest = _mbsrchr (finalDestDir, '\\');
  2681. *tmpDest = 0;
  2682. DestFile = tmpDest + 1;
  2683. } else {
  2684. finalDestDir = DestDirectory;
  2685. }
  2686. //
  2687. // Make SrcFile non-NULL
  2688. //
  2689. if (!SrcFile || !(*SrcFile)) {
  2690. SrcFile = DestFile;
  2691. } else {
  2692. if (_mbschr (SrcFile, '\\')) {
  2693. //
  2694. // This src file has a dir in it -- skip the
  2695. // dir specification
  2696. //
  2697. SrcFile = GetFileNameFromPath (SrcFile);
  2698. }
  2699. }
  2700. //
  2701. // Now add the file spec (if it does not already exist)
  2702. //
  2703. if (NoDestDirSpec) {
  2704. MemDbBuildKey (key, MEMDB_CATEGORY_NT_FILES, DestFile, SrcFile, "*");
  2705. if (!MemDbEnumFirstValue (&enumFiles, key, MEMDB_ALL_SUBLEVELS, MEMDB_ENDPOINTS_ONLY)) {
  2706. if (g_DoWarnings) {
  2707. //
  2708. // Record a "no directory spec" warning because this file is not
  2709. // listed in a section that is also listed in [DestinationDirs]
  2710. //
  2711. MemDbSetValueEx (
  2712. MEMDB_CATEGORY_NT_FILES_NODIR_OTHER_COPY,
  2713. DestFile,
  2714. NULL,
  2715. NULL,
  2716. NoDirOffset,
  2717. NULL
  2718. );
  2719. }
  2720. } else {
  2721. //
  2722. // Already listed properly -- ignore this bad spec
  2723. //
  2724. return;
  2725. }
  2726. }
  2727. //
  2728. // Add the destination directory to the NtDirs category.
  2729. //
  2730. MemDbSetValueEx (
  2731. MEMDB_CATEGORY_NT_DIRS,
  2732. finalDestDir,
  2733. NULL,
  2734. NULL,
  2735. 0,
  2736. &offset
  2737. );
  2738. //
  2739. // Now write the file to the caller-specified category.
  2740. //
  2741. MemDbBuildKey (key, MEMDB_CATEGORY_NT_FILES, DestFile, SrcFile, "*");
  2742. if (MemDbEnumFirstValue (&enumFiles, key, MEMDB_ALL_SUBLEVELS, MEMDB_ENDPOINTS_ONLY)) {
  2743. removeExistingEntry = TRUE;
  2744. do {
  2745. //
  2746. // If file is marked in layout.inf as "never copy" then skip keep this file.
  2747. //
  2748. if (!(enumFiles.UserFlags & SRC_NEVER_COPY)) {
  2749. //
  2750. // Is there a non-identical match already in memdb?
  2751. //
  2752. if (offset != enumFiles.dwValue && !DoDirsMatch (offset, enumFiles.dwValue)) {
  2753. twice = TRUE;
  2754. removeExistingEntry = TRUE;
  2755. outputFile = TRUE;
  2756. //
  2757. // Add the first duplicate to the del list, so that
  2758. // uninstall backs it up.
  2759. //
  2760. MemDbBuildKeyFromOffset (enumFiles.dwValue, key, 1, NULL);
  2761. pProcessDelFileSpec (key, DestFile);
  2762. break;
  2763. } else {
  2764. // ignore identical duplicate
  2765. removeExistingEntry = FALSE;
  2766. outputFile = FALSE;
  2767. }
  2768. }
  2769. } while (MemDbEnumNextValue (&enumFiles));
  2770. }
  2771. //
  2772. // Provide a warning when a file is listed in multiple INFs, or the
  2773. // same INF twice. It must have a different dest directory.
  2774. //
  2775. if (twice) {
  2776. DEBUGMSG ((DBG_WARNING, "File %s is listed in more that one directory.", DestFile));
  2777. if (g_DoWarnings) {
  2778. MemDbSetValueEx (MEMDB_CATEGORY_NT_FILES_DOUBLED_IDX_COPY, DestFile, NULL, NULL, 0, NULL);
  2779. }
  2780. }
  2781. //
  2782. // Always use the last file spec, ignoring the early dups.
  2783. //
  2784. if (removeExistingEntry) {
  2785. MemDbBuildKey (key, MEMDB_CATEGORY_NT_FILES, DestFile, SrcFile, NULL);
  2786. MemDbDeleteTree (key);
  2787. }
  2788. if (outputFile) {
  2789. layoutInfFile = pGetLayoutInfFile (
  2790. InfFileName,
  2791. InfFileHandle,
  2792. LayoutFilesBuf,
  2793. SrcFile
  2794. );
  2795. if (layoutInfFile) {
  2796. MemDbSetValueEx (
  2797. MEMDB_CATEGORY_NT_FILES,
  2798. DestFile,
  2799. SrcFile,
  2800. layoutInfFile,
  2801. offset,
  2802. NULL
  2803. );
  2804. FreePathString (layoutInfFile);
  2805. } else {
  2806. if (g_DoWarnings) {
  2807. MemDbSetValueEx (
  2808. MEMDB_CATEGORY_NT_FILES_NO_LAYOUT,
  2809. GetFileNameFromPath (InfFileName),
  2810. InfSection,
  2811. DestFile,
  2812. 0,
  2813. NULL
  2814. );
  2815. }
  2816. }
  2817. }
  2818. //
  2819. // Write the file to keep track of dups
  2820. //
  2821. MemDbSetValueEx (
  2822. MEMDB_CATEGORY_NT_FILES_DOUBLED_COPY,
  2823. DestFile,
  2824. GetFileNameFromPath (InfFileName),
  2825. finalDestDir,
  2826. 0,
  2827. NULL
  2828. );
  2829. //
  2830. // Remove directory warning keys when a [DestinationDirs]
  2831. // specification exists.
  2832. //
  2833. if (!NoDestDirSpec) {
  2834. MemDbBuildKey(key, MEMDB_CATEGORY_NT_FILES_NODIR_COPY, DestFile, NULL, NULL);
  2835. MemDbDeleteTree (key);
  2836. MemDbBuildKey(key, MEMDB_CATEGORY_NT_FILES_NODIR_OTHER_COPY, DestFile, NULL, NULL);
  2837. MemDbDeleteValue (key);
  2838. }
  2839. }
  2840. __finally {
  2841. //
  2842. // Clean up
  2843. //
  2844. if (finalDestDir != DestDirectory) {
  2845. FreePathString (finalDestDir);
  2846. }
  2847. FreeText (key);
  2848. }
  2849. }
  2850. VOID
  2851. pProcessDelFileSpec (
  2852. IN PCSTR DestDirectory,
  2853. IN PCSTR DestFile
  2854. )
  2855. {
  2856. PSTR key;
  2857. PCSTR p;
  2858. PCSTR finalDestDir;
  2859. PSTR tmpDest;
  2860. CHAR fixedFullPath[MAX_PATH];
  2861. __try {
  2862. key = AllocText (MEMDB_MAX);
  2863. if (!key) {
  2864. __leave;
  2865. }
  2866. //
  2867. // If DestFile has a subpath, join it with DestDirectory
  2868. //
  2869. if (_mbschr (DestFile, '\\')) {
  2870. //
  2871. // This dest file has a dir in it. Join it with the root,
  2872. // then recompute the file name ptr.
  2873. //
  2874. finalDestDir = JoinPaths (DestDirectory, DestFile);
  2875. tmpDest = _mbsrchr (finalDestDir, '\\');
  2876. *tmpDest = 0;
  2877. DestFile = tmpDest + 1;
  2878. } else {
  2879. finalDestDir = DestDirectory;
  2880. }
  2881. //
  2882. // Minimize the destination path
  2883. //
  2884. pMinimizeIdPath (DestDirectory, fixedFullPath);
  2885. //
  2886. // Record the spec in the DelFiles category
  2887. //
  2888. MemDbBuildKey (key, MEMDB_CATEGORY_DEL_FILES, fixedFullPath, DestFile, NULL);
  2889. MemDbSetValue (key, 0);
  2890. }
  2891. __finally {
  2892. if (finalDestDir != DestDirectory) {
  2893. FreePathString (finalDestDir);
  2894. }
  2895. FreeText (key);
  2896. }
  2897. }
  2898. VOID
  2899. pProcessFileSpec (
  2900. IN PCSTR InfFileName,
  2901. IN HINF InfFileHandle,
  2902. IN PCSTR InfSection,
  2903. IN SECTIONTYPE SectionType,
  2904. IN PCSTR SrcFile, OPTIONAL
  2905. IN PCSTR DestDirectory,
  2906. IN PCSTR DestFile,
  2907. IN BOOL NoDestDirSpec,
  2908. IN DWORD NoDirOffset,
  2909. IN PGROWBUFFER LayoutFilesBuf
  2910. )
  2911. {
  2912. if (SectionType == ST_COPYFILES) {
  2913. pProcessCopyFileSpec (
  2914. InfFileName,
  2915. InfFileHandle,
  2916. InfSection,
  2917. SrcFile,
  2918. DestDirectory,
  2919. DestFile,
  2920. NoDestDirSpec,
  2921. NoDirOffset,
  2922. LayoutFilesBuf
  2923. );
  2924. } else if (SectionType == ST_DELFILES) {
  2925. if (!NoDestDirSpec) {
  2926. pProcessDelFileSpec (DestDirectory, DestFile);
  2927. }
  2928. }
  2929. }
  2930. BOOL
  2931. pProcessInfCommand (
  2932. IN PCSTR InfFileName,
  2933. IN PCSTR SectionMultiSz,
  2934. IN HINF InfFileHandle,
  2935. IN SECTIONTYPE SectionType,
  2936. IN PGROWBUFFER LayoutFilesBuf
  2937. )
  2938. {
  2939. MULTISZ_ENUM multiSz;
  2940. BOOL done;
  2941. PCSTR destDirectory;
  2942. PCSTR knownDestDir;
  2943. PCSTR srcFile;
  2944. PCSTR destFile;
  2945. DWORD noDirOffset;
  2946. INFSTRUCT context;
  2947. //
  2948. // Evaluate the INF section
  2949. //
  2950. if (EnumFirstMultiSz (&multiSz, SectionMultiSz)) {
  2951. do {
  2952. //
  2953. // If this section is excluded, continue without processing it.
  2954. //
  2955. if (pIsExcludedInfSection (GetFileNameFromPath (InfFileName), multiSz.CurrentString)) {
  2956. continue;
  2957. }
  2958. //
  2959. // Read destination directory for this particular copy section. This comes
  2960. // from the INF's [DestinationDirs] section.
  2961. //
  2962. destDirectory = pReadDestDir (
  2963. InfFileName,
  2964. multiSz.CurrentString,
  2965. InfFileHandle,
  2966. LayoutFilesBuf,
  2967. &noDirOffset
  2968. );
  2969. //
  2970. // read all the lines that contain destination file name and source file name
  2971. //
  2972. InitInfStruct (&context, NULL, g_TempPool);
  2973. if (multiSz.CurrentString[0] == '@' ||
  2974. InfFindFirstLine (InfFileHandle, multiSz.CurrentString, NULL, &context)
  2975. ) {
  2976. done = FALSE;
  2977. do {
  2978. //
  2979. // Get the dest and src file names
  2980. //
  2981. if (multiSz.CurrentString[0]=='@') {
  2982. destFile = multiSz.CurrentString + 1;
  2983. } else {
  2984. destFile = pGetNonEmptyField (&context, 1);
  2985. }
  2986. if (multiSz.CurrentString[0]=='@') {
  2987. srcFile = NULL;
  2988. } else {
  2989. srcFile = pGetNonEmptyField (&context, 2);
  2990. }
  2991. if (destDirectory) {
  2992. //
  2993. // Perform processing to ensure that the file spec is
  2994. // unique, that it is fully formed, and that it gets
  2995. // written to filelist.dat.
  2996. //
  2997. pProcessFileSpec (
  2998. InfFileName,
  2999. InfFileHandle,
  3000. multiSz.CurrentString,
  3001. SectionType,
  3002. srcFile,
  3003. destDirectory,
  3004. destFile,
  3005. FALSE,
  3006. noDirOffset,
  3007. LayoutFilesBuf
  3008. );
  3009. } else if (destFile) {
  3010. knownDestDir = pGetAdditionalLocation (GetFileNameFromPath (destFile));
  3011. if (knownDestDir) {
  3012. pProcessFileSpec (
  3013. InfFileName,
  3014. InfFileHandle,
  3015. multiSz.CurrentString,
  3016. SectionType,
  3017. srcFile,
  3018. knownDestDir,
  3019. destFile,
  3020. TRUE,
  3021. noDirOffset,
  3022. LayoutFilesBuf
  3023. );
  3024. FreePathString (knownDestDir);
  3025. }
  3026. }
  3027. if (multiSz.CurrentString[0]=='@') {
  3028. done = TRUE;
  3029. } else if (!InfFindNextLine (&context)) {
  3030. done = TRUE;
  3031. }
  3032. } while (!done);
  3033. InfCleanUpInfStruct (&context);
  3034. }
  3035. if (destDirectory != NULL) {
  3036. FreePathString (destDirectory);
  3037. }
  3038. } while (EnumNextMultiSz (&multiSz));
  3039. }
  3040. return TRUE;
  3041. }
  3042. BOOL
  3043. pProcessFile (
  3044. IN PCSTR FileName
  3045. )
  3046. {
  3047. GROWBUFFER sectionNamesBuf = GROWBUF_INIT;
  3048. PWSTR sectBuffer = NULL;
  3049. PWSTR currentSect;
  3050. HINF fileHandle;
  3051. UINT sizeNeeded = 0;
  3052. UINT fieldIdx = 0;
  3053. CHAR section[MAX_MBCHAR_PATH];
  3054. MULTISZ_ENUMA sectionEnum;
  3055. PCSTR layoutFile;
  3056. PCSTR cmdSection;
  3057. INFSTRUCT context = INITINFSTRUCT_POOLHANDLE;
  3058. GROWBUFFER layoutFilesBuf = GROWBUF_INIT;
  3059. fileHandle = InfOpenInfFile (FileName);
  3060. if (fileHandle == INVALID_HANDLE_VALUE) {
  3061. fprintf (stderr, "WARNING: Cannot open inf file:%s\n", FileName);
  3062. return TRUE;
  3063. }
  3064. __try {
  3065. //
  3066. // get all layout files in a multisz
  3067. //
  3068. if (InfFindFirstLine (fileHandle, "Version", "LayoutFile", &context)) {
  3069. fieldIdx = 1;
  3070. layoutFile = pGetNonEmptyField (&context, fieldIdx);
  3071. while (layoutFile) {
  3072. MultiSzAppend (&layoutFilesBuf, layoutFile);
  3073. fieldIdx ++;
  3074. layoutFile = pGetNonEmptyField (&context, fieldIdx);
  3075. }
  3076. } else {
  3077. // put layout.inf in the list, because it is the default layout file
  3078. MultiSzAppend (&layoutFilesBuf, "layout.inf");
  3079. }
  3080. InfResetInfStruct (&context);
  3081. //
  3082. // get all the sections
  3083. //
  3084. if (!(*MypSetupGetInfSections) (fileHandle, NULL, 0, &sizeNeeded)) {
  3085. fprintf (stderr, "WARNING: Error processing inf file:%s\n", FileName);
  3086. __leave;
  3087. }
  3088. if (sizeNeeded == 0) {
  3089. __leave;
  3090. }
  3091. sectBuffer = AllocPathStringW (sizeNeeded + 1);
  3092. if (!(*MypSetupGetInfSections) (fileHandle, (PSTR)sectBuffer, sizeNeeded, NULL)) {
  3093. fprintf (stderr, "WARNING: Error processing inf file:%s\n", FileName);
  3094. __leave;
  3095. }
  3096. //
  3097. // enumerate all sections looking for CopyFiles key
  3098. //
  3099. currentSect = sectBuffer;
  3100. while (*currentSect) {
  3101. sprintf (section, "%S", currentSect);
  3102. //
  3103. // get all sections that copy files in a multisz
  3104. //
  3105. if (InfFindFirstLine (fileHandle, section, "CopyFiles", &context)) {
  3106. do {
  3107. fieldIdx = 1;
  3108. cmdSection = pGetNonEmptyField (&context, fieldIdx);
  3109. while (cmdSection) {
  3110. MultiSzAppend (&sectionNamesBuf, cmdSection);
  3111. fieldIdx ++;
  3112. cmdSection = pGetNonEmptyField (&context, fieldIdx);
  3113. }
  3114. //
  3115. // enumerate all sections that copy files
  3116. //
  3117. if (EnumFirstMultiSz (&sectionEnum, sectionNamesBuf.Buf)) {
  3118. do {
  3119. if (!pProcessInfCommand (
  3120. FileName,
  3121. sectionEnum.CurrentString,
  3122. fileHandle,
  3123. ST_COPYFILES,
  3124. &layoutFilesBuf
  3125. )) {
  3126. __leave;
  3127. }
  3128. } while (EnumNextMultiSz (&sectionEnum));
  3129. }
  3130. FreeGrowBuffer (&sectionNamesBuf);
  3131. } while (InfFindNextLine (&context));
  3132. }
  3133. InfResetInfStruct (&context);
  3134. //
  3135. // get all sections that delete files in a multisz
  3136. //
  3137. if (InfFindFirstLine (fileHandle, section, "DelFiles", &context)) {
  3138. do {
  3139. fieldIdx = 1;
  3140. cmdSection = pGetNonEmptyField (&context, fieldIdx);
  3141. while (cmdSection) {
  3142. MultiSzAppend (&sectionNamesBuf, cmdSection);
  3143. fieldIdx ++;
  3144. cmdSection = pGetNonEmptyField (&context, fieldIdx);
  3145. }
  3146. //
  3147. // enumerate all sections that delete files
  3148. //
  3149. if (EnumFirstMultiSz (&sectionEnum, sectionNamesBuf.Buf)) {
  3150. do {
  3151. if (!pProcessInfCommand (
  3152. FileName,
  3153. sectionEnum.CurrentString,
  3154. fileHandle,
  3155. ST_DELFILES,
  3156. &layoutFilesBuf
  3157. )) {
  3158. __leave;
  3159. }
  3160. } while (EnumNextMultiSz (&sectionEnum));
  3161. }
  3162. FreeGrowBuffer (&sectionNamesBuf);
  3163. } while (InfFindNextLine (&context));
  3164. }
  3165. InfResetInfStruct (&context);
  3166. currentSect = GetEndOfStringW (currentSect) + 1;
  3167. }
  3168. }
  3169. __finally {
  3170. FreePathStringW (sectBuffer);
  3171. FreeGrowBuffer (&layoutFilesBuf);
  3172. InfCleanUpInfStruct (&context);
  3173. InfCloseInfFile (fileHandle);
  3174. }
  3175. return TRUE;
  3176. }
  3177. typedef struct {
  3178. CHAR FilePath[MAX_PATH];
  3179. UINT ThreadNumber;
  3180. HANDLE GoEvent;
  3181. HANDLE DoneEvent;
  3182. } THREADARGS, *PTHREADARGS;
  3183. HANDLE g_Semaphores[4];
  3184. HANDLE g_FileThreads[4];
  3185. THREADARGS g_FileThreadInfo[4];
  3186. HANDLE g_DoneEvent;
  3187. DWORD
  3188. WINAPI
  3189. pProcessFileThread (
  3190. IN PVOID ThreadInfo
  3191. )
  3192. {
  3193. HANDLE array[2];
  3194. PTHREADARGS threadInfo = (PTHREADARGS) ThreadInfo;
  3195. DWORD rc;
  3196. array[0] = threadInfo->GoEvent;
  3197. array[1] = threadInfo->DoneEvent;
  3198. for (;;) {
  3199. rc = WaitForMultipleObjects (2, array, FALSE, INFINITE);
  3200. if (rc == WAIT_OBJECT_0) {
  3201. pProcessFile (threadInfo->FilePath);
  3202. ReleaseSemaphore (g_Semaphores[threadInfo->ThreadNumber], 1, NULL);
  3203. } else {
  3204. break;
  3205. }
  3206. }
  3207. return 0;
  3208. }
  3209. BOOL
  3210. pProcessFileDispatcher (
  3211. IN PCSTR FileName
  3212. )
  3213. {
  3214. DWORD rc;
  3215. //
  3216. // Wait for a thread to become availble
  3217. //
  3218. rc = WaitForMultipleObjects (4, g_Semaphores, FALSE, INFINITE);
  3219. if (rc <= WAIT_OBJECT_0 + 3) {
  3220. } else {
  3221. fprintf (stderr, "Failed to acquire thread\n");
  3222. exit (1);
  3223. }
  3224. //
  3225. // Put file name in thread's struct
  3226. //
  3227. rc -= WAIT_OBJECT_0;
  3228. StringCopy (g_FileThreadInfo[rc].FilePath, FileName);
  3229. //
  3230. // Start the thread
  3231. //
  3232. SetEvent (g_FileThreadInfo[rc].GoEvent);
  3233. return TRUE;
  3234. }
  3235. VOID
  3236. pInitFileThreads (
  3237. VOID
  3238. )
  3239. {
  3240. UINT u;
  3241. g_DoneEvent = CreateEvent (NULL, TRUE, FALSE, NULL);
  3242. if (!g_DoneEvent) {
  3243. fprintf (stderr, "Failed to init completion event\n");
  3244. }
  3245. for (u = 0 ; u < 4 ; u++) {
  3246. g_Semaphores[u] = CreateSemaphore (NULL, 1, 1, NULL);
  3247. if (!g_Semaphores[u]) {
  3248. fprintf (stderr, "Failed to init semaphores\n");
  3249. exit (1);
  3250. }
  3251. g_FileThreadInfo[u].ThreadNumber = u;
  3252. g_FileThreadInfo[u].GoEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
  3253. g_FileThreadInfo[u].DoneEvent = g_DoneEvent;
  3254. if (!g_FileThreadInfo[u].GoEvent) {
  3255. fprintf (stderr, "Failed to init thread info\n");
  3256. exit (1);
  3257. }
  3258. g_FileThreads[u] = CreateThread (NULL, 0, pProcessFileThread, &g_FileThreadInfo[u], 0, NULL);
  3259. if (!g_FileThreads[u]) {
  3260. fprintf (stderr, "Failed to init threads\n");
  3261. exit (1);
  3262. }
  3263. }
  3264. }
  3265. VOID
  3266. pStopFileThreads (
  3267. VOID
  3268. )
  3269. {
  3270. SetEvent (g_DoneEvent);
  3271. WaitForMultipleObjects (4, g_FileThreads, TRUE, INFINITE);
  3272. }
  3273. BOOL
  3274. pIsExcludedDir (
  3275. IN PCTSTR DirName
  3276. )
  3277. {
  3278. TCHAR DirId [MAX_PATH];
  3279. PCTSTR NextPtr = NULL;
  3280. NextPtr = _mbschr (DirName, '\\');
  3281. if (!NextPtr) {
  3282. NextPtr = GetEndOfString (DirName);
  3283. }
  3284. StringCopyAB (DirId, DirName, NextPtr);
  3285. return (HtFindString (g_ExcludedDirsTable, DirId) != NULL);
  3286. }
  3287. BOOL
  3288. pCreateNtFileList (
  3289. IN PCSTR FileListDatPath
  3290. )
  3291. {
  3292. MEMDB_ENUM enumFiles;
  3293. PSTR currentFile;
  3294. BOOL result = FALSE;
  3295. PSTR filePtr1 = NULL, filePtr2 = NULL;
  3296. DWORD version = FILEGEN_VERSION;
  3297. INT ExcludeType;
  3298. INFCONTEXT context;
  3299. BOOL found = FALSE;
  3300. PSTR platform;
  3301. PSTR product;
  3302. PSTR destName;
  3303. PSTR srcName;
  3304. PSTR temp;
  3305. PSTR key2;
  3306. PSTR key3;
  3307. PSTR extPtr;
  3308. BOOL process = TRUE;
  3309. DWORD offset;
  3310. BOOL b;
  3311. HANDLE fileHandle = INVALID_HANDLE_VALUE;
  3312. MEMDB_ENUM enumFiles2;
  3313. CHAR string [MAX_MBCHAR_PATH];
  3314. DWORD dontCare;
  3315. PSTR fileSpec;
  3316. HASHTABLE dupTable;
  3317. __try {
  3318. platform = AllocText (MAX_PATH);
  3319. product = AllocText (MAX_PATH);
  3320. destName = AllocText (MEMDB_MAX);
  3321. srcName = AllocText (MEMDB_MAX);
  3322. temp = AllocText (MEMDB_MAX);
  3323. key2 = AllocText (MEMDB_MAX);
  3324. key3 = AllocText (MEMDB_MAX);
  3325. dupTable = HtAlloc();
  3326. if (!platform || !product || !destName || !srcName || !temp || !key2 || !key3 || !dupTable) {
  3327. __leave;
  3328. }
  3329. //pInitFileThreads();
  3330. if (MemDbEnumFirstValue (
  3331. &enumFiles,
  3332. MEMDB_CATEGORY_INF_FILES TEXT("\\*"),
  3333. MEMDB_ALL_SUBLEVELS,
  3334. MEMDB_ENDPOINTS_ONLY
  3335. )) {
  3336. do {
  3337. currentFile = enumFiles.szName;
  3338. if (!StringMatch (currentFile, S_IGNORE_THIS_FILE)) {
  3339. process = TRUE;
  3340. if (g_StrictInfs) {
  3341. StringCopy (srcName, GetFileNameFromPath (currentFile));
  3342. extPtr = (PSTR)GetFileExtensionFromPath (srcName);
  3343. if (!StringIMatch (extPtr, "INF")) {
  3344. extPtr = _mbsdec (srcName, extPtr);
  3345. if (extPtr) {
  3346. *extPtr = 0;
  3347. }
  3348. }
  3349. MemDbBuildKey (temp, MEMDB_CATEGORY_NT_INSTALLED_INFS, srcName, NULL, NULL);
  3350. if (!MemDbGetValue (temp, NULL)) {
  3351. process = FALSE;
  3352. }
  3353. }
  3354. if (process) {
  3355. PEXCLUDED_INF_FILES excludedInf;
  3356. if (HtFindStringAndData (g_ExcludedInfsTable, currentFile, &excludedInf)) {
  3357. if (!excludedInf) {
  3358. //this means that the whole INF is excluded
  3359. printf ("Excluded: %s\n", currentFile);
  3360. process = FALSE;
  3361. }
  3362. }
  3363. }
  3364. if (process) {
  3365. printf ("Processing file : %s", currentFile);
  3366. //if (!pProcessFileDispatcher (currentFile)) {
  3367. if (!pProcessFile (currentFile)) {
  3368. DEBUGMSG ((DBG_ERROR, "Error while processing: %s", currentFile));
  3369. }
  3370. printf("\n");
  3371. }
  3372. }
  3373. } while (MemDbEnumNextValue (&enumFiles));
  3374. }
  3375. //pStopFileThreads();
  3376. pLoadKnownFiles (g_AddnlInf, FALSE);
  3377. // now let's write the filelist.dat file if we are on the right platform and product
  3378. found = FALSE;
  3379. if (SetupFindFirstLine (g_AddnlInf, TEXT("FILELIST.GENERATE"), NULL, &context)) {
  3380. do {
  3381. if (SetupGetStringField (&context, 1, platform, MAX_TCHAR_PATH, NULL) &&
  3382. SetupGetStringField (&context, 2, product, MAX_TCHAR_PATH, NULL) &&
  3383. StringIMatch (g_Platform, platform) &&
  3384. StringIMatch (g_Product, product)
  3385. ) {
  3386. found = TRUE;
  3387. break;
  3388. }
  3389. } while (SetupFindNextLine (&context, &context));
  3390. }
  3391. if (found) {
  3392. fileHandle = CreateFile (
  3393. FileListDatPath,
  3394. GENERIC_READ | GENERIC_WRITE,
  3395. 0,
  3396. NULL,
  3397. CREATE_ALWAYS,
  3398. FILE_ATTRIBUTE_NORMAL,
  3399. NULL
  3400. );
  3401. if (fileHandle == INVALID_HANDLE_VALUE) {
  3402. fprintf (stderr, "Cannot create output file : %s\n", FileListDatPath);
  3403. __leave;
  3404. }
  3405. if (!WriteFile (fileHandle, &version, sizeof (DWORD), &dontCare, NULL)) {
  3406. printf ("Error writing to %s. Error=%u\n", FileListDatPath, GetLastError());
  3407. __leave;
  3408. }
  3409. if (MemDbEnumFirstValue (
  3410. &enumFiles2,
  3411. MEMDB_CATEGORY_NT_KNOWN_FILES TEXT("\\*"),
  3412. MEMDB_ALL_SUBLEVELS,
  3413. MEMDB_ENDPOINTS_ONLY
  3414. )) {
  3415. do {
  3416. MemDbBuildKeyFromOffset (enumFiles2.dwValue, key3, 1, NULL);
  3417. if (!pIsExcludedDir (key3)) {
  3418. filePtr1 = enumFiles2.szName;
  3419. //let's skip priority number
  3420. filePtr2 = _mbschr (filePtr1, '\\');
  3421. if (filePtr2 == NULL) {
  3422. DEBUGMSG ((DBG_WARNING, "Bogus name found in NT_FILES: %S", enumFiles2.szName));
  3423. continue;
  3424. }
  3425. filePtr1 = _mbsinc (filePtr2);
  3426. filePtr2 = _mbschr (filePtr1, '\\');
  3427. if (filePtr2 == NULL) {
  3428. DEBUGMSG ((DBG_WARNING, "Bogus name found in NT_FILES: %S", enumFiles2.szName));
  3429. continue;
  3430. }
  3431. StringCopyAB (destName, filePtr1, filePtr2);
  3432. ExcludeType = pIsExcludedFile (destName);
  3433. if ((ExcludeType == -1) || (ExcludeType == 1)){
  3434. wsprintf (temp, "%s\\%s", key3, destName);
  3435. if (!HtFindString (dupTable, temp)) {
  3436. if (!WriteFile (fileHandle, key3, SizeOfString (key3), &dontCare, NULL)) {
  3437. printf ("Error writing to %s. Error=%u\n", FileListDatPath, GetLastError());
  3438. __leave;
  3439. }
  3440. if (!WriteFile (fileHandle, destName, SizeOfString (destName), &dontCare, NULL)) {
  3441. printf ("Error writing to %s. Error=%u\n", FileListDatPath, GetLastError());
  3442. __leave;
  3443. }
  3444. HtAddString (dupTable, temp);
  3445. }
  3446. }
  3447. }
  3448. } while (MemDbEnumNextValue (&enumFiles2));
  3449. }
  3450. if (MemDbEnumFirstValue (
  3451. &enumFiles2,
  3452. TEXT(MEMDB_CATEGORY_NT_FILESA)TEXT("\\*"),
  3453. MEMDB_ALL_SUBLEVELS,
  3454. MEMDB_ENDPOINTS_ONLY
  3455. )) {
  3456. do {
  3457. MemDbBuildKeyFromOffset (enumFiles2.dwValue, key3, 1, NULL);
  3458. if (!pIsExcludedDir (key3)) {
  3459. filePtr1 = enumFiles2.szName;
  3460. filePtr2 = _mbschr (filePtr1, '\\');
  3461. if (filePtr2 == NULL) {
  3462. StringCopy (destName, filePtr1);
  3463. } else {
  3464. StringCopyAB (destName, filePtr1, filePtr2);
  3465. }
  3466. ExcludeType = pIsExcludedFile (destName);
  3467. if ((ExcludeType == -1) || (ExcludeType == 1)){
  3468. if (!pIsKnownFile (key3, destName)) {
  3469. wsprintf (temp, "%s\\%s", key3, destName);
  3470. if (!HtFindString (dupTable, temp)) {
  3471. //
  3472. // Write file to list
  3473. //
  3474. if (!WriteFile (fileHandle, key3, SizeOfString (key3), &dontCare, NULL)) {
  3475. printf ("Error writing to %s. Error=%u\n", FileListDatPath, GetLastError());
  3476. __leave;
  3477. }
  3478. if (!WriteFile (fileHandle, destName, SizeOfString (destName), &dontCare, NULL)) {
  3479. printf ("Error writing to %s. Error=%u\n", FileListDatPath, GetLastError());
  3480. __leave;
  3481. }
  3482. HtAddString (dupTable, temp);
  3483. }
  3484. } else {
  3485. //
  3486. // Put overridden location in DelFiles list
  3487. //
  3488. pProcessDelFileSpec (key3, destName);
  3489. }
  3490. }
  3491. }
  3492. } while (MemDbEnumNextValue (&enumFiles2));
  3493. }
  3494. * string = 0;
  3495. if (!WriteFile (fileHandle, string, 1, &dontCare, NULL)) {
  3496. printf ("Error writing to %s. Error=%u\n", FileListDatPath, GetLastError());
  3497. __leave;
  3498. }
  3499. // now it's the time to write the excluded files
  3500. if (MemDbEnumFirstValue (
  3501. &enumFiles2,
  3502. TEXT(MEMDB_CATEGORY_NT_FILESA)TEXT("\\*"),
  3503. MEMDB_ALL_SUBLEVELS,
  3504. MEMDB_ENDPOINTS_ONLY
  3505. )) {
  3506. do {
  3507. filePtr1 = enumFiles2.szName;
  3508. filePtr2 = _mbschr (filePtr1, '\\');
  3509. if (filePtr2 == NULL) {
  3510. StringCopy (destName, filePtr1);
  3511. } else {
  3512. StringCopyAB (destName, filePtr1, filePtr2);
  3513. }
  3514. ExcludeType = pIsExcludedFile (destName);
  3515. if (ExcludeType == 1) {
  3516. if (!WriteFile (fileHandle, destName, SizeOfString (destName), &dontCare, NULL)) {
  3517. printf ("Error writing to %s. Error=%u\n", FileListDatPath, GetLastError());
  3518. __leave;
  3519. }
  3520. }
  3521. } while (MemDbEnumNextValue (&enumFiles2));
  3522. }
  3523. * string = 0;
  3524. if (!WriteFile (fileHandle, string, 1, &dontCare, NULL)) {
  3525. printf ("Error writing to %s. Error=%u\n", FileListDatPath, GetLastError());
  3526. __leave;
  3527. }
  3528. // now it's the time to write the deleted files
  3529. if (MemDbEnumFirstValue (
  3530. &enumFiles2,
  3531. MEMDB_CATEGORY_DEL_FILES TEXT("\\*"),
  3532. MEMDB_ALL_SUBLEVELS,
  3533. MEMDB_ENDPOINTS_ONLY
  3534. )) {
  3535. do {
  3536. if (HtFindString (dupTable, enumFiles2.szName)) {
  3537. continue;
  3538. }
  3539. StringCopy (key3, enumFiles2.szName);
  3540. fileSpec = (PSTR) GetFileNameFromPath (key3);
  3541. if (!fileSpec) {
  3542. continue;
  3543. }
  3544. *_mbsdec (key3, fileSpec) = 0;
  3545. if (!WriteFile (fileHandle, key3, SizeOfString (key3), &dontCare, NULL)) {
  3546. printf ("Error writing to %s. Error=%u\n", FileListDatPath, GetLastError());
  3547. __leave;
  3548. }
  3549. if (!WriteFile (fileHandle, fileSpec, SizeOfString (fileSpec), &dontCare, NULL)) {
  3550. printf ("Error writing to %s. Error=%u\n", FileListDatPath, GetLastError());
  3551. __leave;
  3552. }
  3553. } while (MemDbEnumNextValue (&enumFiles2));
  3554. }
  3555. *string = 0;
  3556. if (!WriteFile (fileHandle, string, 1, &dontCare, NULL)) {
  3557. printf ("Error writing to %s. Error=%u\n", FileListDatPath, GetLastError());
  3558. __leave;
  3559. }
  3560. } else {
  3561. fprintf (
  3562. stderr,
  3563. "Not generating %s.\nDid not find %s,%s in [FileList.Generate] section of %s.\n",
  3564. FileListDatPath,
  3565. g_Platform,
  3566. g_Product,
  3567. g_AddnlFile
  3568. );
  3569. // assume success
  3570. }
  3571. result = TRUE;
  3572. }
  3573. __finally {
  3574. FreeText (platform);
  3575. FreeText (product);
  3576. FreeText (destName);
  3577. FreeText (srcName);
  3578. FreeText (temp);
  3579. FreeText (key2);
  3580. FreeText (key3);
  3581. HtFree (dupTable);
  3582. pCloseCachedHandles();
  3583. if (fileHandle != INVALID_HANDLE_VALUE) {
  3584. CloseHandle (fileHandle);
  3585. }
  3586. }
  3587. return result;
  3588. }
  3589. BOOL
  3590. pLocalReadNtFileSection (
  3591. IN PCTSTR InfPath,
  3592. IN HINF InfHandle,
  3593. IN HASHTABLE DirsTable,
  3594. IN PCTSTR SectName
  3595. )
  3596. {
  3597. INFCONTEXT context;
  3598. PSTR fileName;
  3599. PSTR dirNumber;
  3600. PSTR destName;
  3601. PSTR key;
  3602. INT dispNumber;
  3603. WORD userFlags;
  3604. DWORD offset;
  3605. BOOL result = TRUE;
  3606. __try {
  3607. fileName = AllocText (MAX_PATH);
  3608. dirNumber = AllocText (MAX_PATH);
  3609. destName = AllocText (MAX_PATH);
  3610. key = AllocText (MEMDB_MAX);
  3611. if (!fileName || !dirNumber || !destName || !key) {
  3612. __leave;
  3613. }
  3614. if (SetupFindFirstLine (InfHandle, SectName, NULL, &context)) {
  3615. do {
  3616. if (!SetupGetOemStringField (&context, 0, fileName, MAX_TCHAR_PATH, NULL)) {
  3617. return result;
  3618. }
  3619. if (!SetupGetStringField (&context, DIRS_FIELD, dirNumber, MAX_TCHAR_PATH, NULL)) {
  3620. return result;
  3621. }
  3622. if (!SetupGetIntField (&context, DISP_FIELD, &dispNumber)) {
  3623. dispNumber = 3;
  3624. }
  3625. if (!SetupGetStringField (&context, DEST_FIELD, destName, MAX_TCHAR_PATH, NULL)) {
  3626. StringCopy (destName, fileName);
  3627. }
  3628. if (destName [0] == 0) {
  3629. StringCopy (destName, fileName);
  3630. }
  3631. if (dispNumber!=3) {
  3632. if (HtFindStringAndData (DirsTable, dirNumber, &offset)) {
  3633. userFlags = (dispNumber == 3) ? SRC_NEVER_COPY : 0;
  3634. pConvertSIFDir (dirNumber);
  3635. MemDbBuildKey (key, MEMDB_CATEGORY_NT_FILES, destName, fileName, GetFileNameFromPath (InfPath));
  3636. MemDbSetValueAndFlags (key, offset, userFlags, 0);
  3637. MemDbSetValueEx (
  3638. MEMDB_CATEGORY_NT_FILES_DOUBLED_COPY,
  3639. fileName,
  3640. GetFileNameFromPath (InfPath),
  3641. //TEXT("LAYOUT.INF"),
  3642. dirNumber,
  3643. 0,
  3644. NULL
  3645. );
  3646. if (g_StrictInfs) {
  3647. MemDbSetValueEx (
  3648. MEMDB_CATEGORY_NT_INSTALLED_INFS,
  3649. fileName,
  3650. NULL,
  3651. NULL,
  3652. 0,
  3653. NULL
  3654. );
  3655. }
  3656. }
  3657. else {
  3658. if (g_DoWarnings) {
  3659. MemDbSetValueEx (MEMDB_CATEGORY_NT_FILES_NODIR_COPY, fileName, NULL, NULL, 0, NULL);
  3660. }
  3661. }
  3662. }
  3663. } while (SetupFindNextLine (&context, &context));
  3664. }
  3665. }
  3666. __finally {
  3667. FreeText (fileName);
  3668. FreeText (dirNumber);
  3669. FreeText (destName);
  3670. FreeText (key);
  3671. }
  3672. return result;
  3673. }
  3674. BOOL
  3675. pLocalReadNtDirs (
  3676. IN HINF InfHandle,
  3677. IN OUT HASHTABLE DirsTable
  3678. )
  3679. {
  3680. INFCONTEXT context;
  3681. TCHAR dirNumber[MAX_TCHAR_PATH];
  3682. TCHAR dirString[MAX_TCHAR_PATH];
  3683. PCTSTR dirStringPtr;
  3684. PCTSTR fullPath;
  3685. DWORD offset;
  3686. BOOL result = TRUE;
  3687. PSTR srcDir, destDir, wildCharPtr;
  3688. PSTR resultTmp = NULL;
  3689. PRENAMED_DIRS renamedDir;
  3690. BOOL found;
  3691. if (SetupFindFirstLine (InfHandle, TEXT("WinntDirectories"), NULL, &context)) {
  3692. do {
  3693. if (!SetupGetOemStringField (&context, 0, dirNumber, MAX_TCHAR_PATH, NULL)) {
  3694. return result;
  3695. }
  3696. if (!SetupGetOemStringField (&context, 1, dirString, MAX_TCHAR_PATH, NULL)) {
  3697. return result;
  3698. }
  3699. if (_tcsnextc (dirString) == TEXT('\\')) {
  3700. dirStringPtr = _tcsinc (dirString);
  3701. }
  3702. else {
  3703. dirStringPtr = dirString;
  3704. }
  3705. if (*dirStringPtr) {
  3706. fullPath = JoinPaths ("10", dirStringPtr);
  3707. }
  3708. else {
  3709. fullPath = DuplicatePathString ("10", 0);
  3710. }
  3711. // let's do some dir replacement here
  3712. found = TRUE;
  3713. while (found) {
  3714. renamedDir = g_RenamedDirs;
  3715. found = FALSE;
  3716. while ((!found) && renamedDir) {
  3717. if (IsPatternMatch (renamedDir->SrcDir, fullPath)) {
  3718. srcDir = DuplicatePathString (renamedDir->SrcDir, 0);
  3719. destDir = DuplicatePathString (renamedDir->DestDir, 0);
  3720. wildCharPtr = _tcschr (srcDir, TEXT('*'));
  3721. if (wildCharPtr) {
  3722. *wildCharPtr = 0;
  3723. }
  3724. wildCharPtr = _tcschr (destDir, TEXT('*'));
  3725. if (wildCharPtr) {
  3726. *wildCharPtr = 0;
  3727. }
  3728. resultTmp = (PSTR)StringSearchAndReplace (fullPath, srcDir, destDir);
  3729. if (resultTmp) {
  3730. FreePathString (fullPath);
  3731. fullPath = resultTmp;
  3732. found = TRUE;
  3733. }
  3734. FreePathString (destDir);
  3735. FreePathString (srcDir);
  3736. }
  3737. renamedDir = renamedDir->Next;
  3738. }
  3739. }
  3740. MemDbSetValueEx (
  3741. MEMDB_CATEGORY_NT_DIRS,
  3742. fullPath,
  3743. NULL,
  3744. NULL,
  3745. 0,
  3746. &offset
  3747. );
  3748. HtAddStringAndData (DirsTable, dirNumber, &offset);
  3749. FreePathString (fullPath);
  3750. } while (SetupFindNextLine (&context, &context));
  3751. }
  3752. return result;
  3753. }
  3754. HASHTABLE g_DirsTable;
  3755. BOOL
  3756. pLocalReadNtFiles (
  3757. IN PCTSTR InfPath
  3758. )
  3759. {
  3760. BOOL result = TRUE;
  3761. HINF infHandle;
  3762. PCTSTR platformSect = NULL;
  3763. infHandle = SetupOpenInfFile (InfPath, NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
  3764. if (infHandle == INVALID_HANDLE_VALUE) {
  3765. return FALSE;
  3766. }
  3767. __try {
  3768. if (!g_DirsTable) {
  3769. g_DirsTable = HtAllocWithData (sizeof (DWORD));
  3770. }
  3771. if (g_DirsTable == NULL) {
  3772. result = FALSE;
  3773. __leave;
  3774. }
  3775. if (!pLocalReadNtDirs (infHandle, g_DirsTable)) {
  3776. result = FALSE;
  3777. __leave;
  3778. }
  3779. if (!pLocalReadNtFileSection (InfPath, infHandle, g_DirsTable, TEXT("SourceDisksfiles"))) {
  3780. result = FALSE;
  3781. __leave;
  3782. }
  3783. platformSect = JoinTextEx (NULL, TEXT("SourceDisksfiles"), g_Platform, TEXT("."), 0, NULL);
  3784. if (!pLocalReadNtFileSection (InfPath, infHandle, g_DirsTable, platformSect)) {
  3785. result = FALSE;
  3786. __leave;
  3787. }
  3788. }
  3789. __finally {
  3790. if (platformSect) {
  3791. FreeText (platformSect);
  3792. platformSect = NULL;
  3793. }
  3794. SetupCloseInfFile (infHandle);
  3795. }
  3796. return result;
  3797. }
  3798. // the following functions are copied from hwcomp.c and slightly modified to allow recursive search
  3799. // and to bypass the exclusion list.
  3800. BOOL
  3801. LocalGetFileNames (
  3802. IN PCTSTR *InfDirs,
  3803. IN UINT InfDirCount,
  3804. IN BOOL QueryFlag
  3805. )
  3806. /*++
  3807. Routine Description:
  3808. LocalGetFileNames searches InfDirs for any file that ends with .INF or .IN_.
  3809. It builds a MULTI_SZ list of file names that may contain PNP IDs. All
  3810. compressed INFs are decompressed into a temporary directory.
  3811. If the QueryFlag is set, the file name list is prepared but no files
  3812. are decompressed.
  3813. Arguments:
  3814. InfDirs - A list of paths to the directory containing INFs, either
  3815. compressed or non-compressed.
  3816. InfDirCount - Specifies the number of dirs in the InfDirs array.
  3817. QueryFlag - QUERYONLY if the function should build the file list but
  3818. should not decompress; PERFORMCOMPLETEOP if the function
  3819. should build the file list and decompress as needed.
  3820. Return Value:
  3821. TRUE if successfull, FALSE if not.
  3822. Call GetLastError for an error code.
  3823. --*/
  3824. {
  3825. UINT u;
  3826. //
  3827. // Add list of files for each directory
  3828. //
  3829. g_TotalInfFiles = 0;
  3830. for (u = 0 ; u < InfDirCount ; u++) {
  3831. if (!pLocalGetFileNamesWorker (InfDirs[u], QueryFlag)) {
  3832. return FALSE;
  3833. }
  3834. }
  3835. MemDbSetValue (MEMDB_CATEGORY_SRC_INF_FILES_NR, g_TotalInfFiles);
  3836. if (g_InfDatabase) {
  3837. MemDbExport (MEMDB_CATEGORY_SRC_INF_FILES, g_InfDatabase, TRUE);
  3838. }
  3839. return TRUE;
  3840. }
  3841. BOOL
  3842. pIsDirectorySuppressed (
  3843. IN PCTSTR SubDirName
  3844. )
  3845. {
  3846. return (HtFindString (g_IgnoredDirsTable, SubDirName) != NULL);
  3847. }
  3848. BOOL
  3849. pSameInfFiles (
  3850. IN PCTSTR InfDir
  3851. )
  3852. {
  3853. TREE_ENUM e;
  3854. PSTR key;
  3855. PTSTR p;
  3856. DWORD value;
  3857. DWORD totalInfFiles = 0;
  3858. BOOL result = TRUE;
  3859. __try {
  3860. key = AllocText (MEMDB_MAX);
  3861. if (!key) {
  3862. __leave;
  3863. }
  3864. if (EnumFirstFileInTreeEx (&e, InfDir, TEXT("*.in?"), FALSE, FALSE, 1)) {
  3865. do {
  3866. if (e.Directory) {
  3867. if (pIsDirectorySuppressed (e.SubPath)) {
  3868. AbortEnumCurrentDir (&e);
  3869. }
  3870. } else if (IsPatternMatch (TEXT("*.in?"), e.Name)) {
  3871. //
  3872. // Make sure file has _ or f at the end.
  3873. //
  3874. p = GetEndOfString (e.FindData->cFileName);
  3875. MYASSERT (p != e.FindData->cFileName);
  3876. p = _tcsdec2 (e.FindData->cFileName, p);
  3877. MYASSERT (p);
  3878. if (!p) {
  3879. continue;
  3880. }
  3881. if (*p != TEXT('_') && _totlower (*p) != TEXT('f')) {
  3882. continue;
  3883. }
  3884. g_TotalInfFiles ++;
  3885. MemDbBuildKey (key, MEMDB_CATEGORY_SRC_INF_FILES, e.FullPath, NULL, NULL);
  3886. if (MemDbGetValue (key, &value)) {
  3887. if (*p == TEXT('_')) {
  3888. result = (value == e.FindData->nFileSizeLow);
  3889. } else {
  3890. result = (value == pComputeChecksum (e.FullPath));
  3891. }
  3892. if (!result) {
  3893. AbortEnumFileInTree (&e);
  3894. break;
  3895. }
  3896. } else {
  3897. result = FALSE;
  3898. AbortEnumFileInTree (&e);
  3899. break;
  3900. }
  3901. }
  3902. } while (EnumNextFileInTree (&e));
  3903. }
  3904. }
  3905. __finally {
  3906. FreeText (key);
  3907. }
  3908. return result;
  3909. }
  3910. BOOL
  3911. pShouldRescanInfs (
  3912. IN PCTSTR *InfDirs,
  3913. IN UINT InfDirCount
  3914. )
  3915. {
  3916. UINT u;
  3917. DWORD value;
  3918. BOOL result = FALSE;
  3919. g_TotalInfFiles = 0;
  3920. for (u = 0 ; u < InfDirCount ; u++) {
  3921. if (!pSameInfFiles (InfDirs[u])) {
  3922. return TRUE;
  3923. }
  3924. }
  3925. if (MemDbGetValue (MEMDB_CATEGORY_SRC_INF_FILES_NR, &value)) {
  3926. result = (value != g_TotalInfFiles);
  3927. } else {
  3928. result = TRUE;
  3929. }
  3930. return result;
  3931. }
  3932. BOOL
  3933. pLocalGetFileNamesWorker (
  3934. IN PCTSTR InfDir,
  3935. IN BOOL QueryFlag
  3936. )
  3937. /*++
  3938. Routine Description:
  3939. pLocalGetFileNamesWorker gets the file names for a single directory.
  3940. See LocalGetFileNames for more details.
  3941. Arguments:
  3942. InfDir - Specifies directory holding zero or more INFs (either
  3943. compressed or non-compressed).
  3944. QueryFlag - Specifies TRUE if INF list is to be queried, or
  3945. FALSE if the list is to be fully processed. When
  3946. QueryFlag is TRUE, files are not decompressed or
  3947. opened.
  3948. Return Value:
  3949. TRUE if the function completes successfully, or FALSE if it fails.
  3950. Call GetLastError for additional failure information.
  3951. --*/
  3952. {
  3953. TREE_ENUM e;
  3954. PSTR key;
  3955. PTSTR p;
  3956. PSTR ActualFile;
  3957. PSTR AnsiFileName;
  3958. PTSTR FileNameOnDisk;
  3959. HANDLE hFile;
  3960. DWORD BytesRead;
  3961. PSTR UncompressedFile;
  3962. PSTR CompressedFile;
  3963. BOOL DecompressFlag;
  3964. DWORD rc = ERROR_SUCCESS;
  3965. BYTE BufForSp[2048];
  3966. PSP_INF_INFORMATION psp;
  3967. BOOL result = FALSE;
  3968. __try {
  3969. key = AllocText (MEMDB_MAX);
  3970. ActualFile = AllocText (MAX_PATH);
  3971. AnsiFileName = AllocText (MAX_PATH);
  3972. UncompressedFile = AllocText (MAX_PATH);
  3973. CompressedFile = AllocText (MAX_PATH);
  3974. if (!key || !ActualFile || !AnsiFileName || !UncompressedFile || !CompressedFile) {
  3975. __leave;
  3976. }
  3977. psp = (PSP_INF_INFORMATION) BufForSp;
  3978. DEBUGMSG ((DBG_WARNING, "Enumerating %s", InfDir));
  3979. //
  3980. // Get file names
  3981. //
  3982. if (EnumFirstFileInTreeEx (&e, InfDir, TEXT("*.in?"), FALSE, FALSE, 1)) {
  3983. rc = ERROR_SUCCESS;
  3984. do {
  3985. if (e.Directory) {
  3986. if (pIsDirectorySuppressed (e.SubPath)) {
  3987. AbortEnumCurrentDir (&e);
  3988. }
  3989. } else if (IsPatternMatch (TEXT("*.in?"), e.Name)) {
  3990. //
  3991. // Make sure file has _ or f at the end.
  3992. //
  3993. p = GetEndOfString (e.FindData->cFileName);
  3994. MYASSERT (p != e.FindData->cFileName);
  3995. p = _tcsdec2 (e.FindData->cFileName, p);
  3996. MYASSERT (p);
  3997. if (!p) {
  3998. continue;
  3999. }
  4000. if (*p != TEXT('_') && _totlower (*p) != TEXT('f')) {
  4001. continue;
  4002. }
  4003. //
  4004. // add the file to the database list
  4005. //
  4006. g_TotalInfFiles ++;
  4007. MemDbBuildKey (key, MEMDB_CATEGORY_SRC_INF_FILES, e.FullPath, NULL, NULL);
  4008. if (*p == TEXT('_')) {
  4009. MemDbSetValue (key, e.FindData->nFileSizeLow);
  4010. } else {
  4011. MemDbSetValue (key, pComputeChecksum (e.FullPath));
  4012. }
  4013. //
  4014. // Default actual file to uncompressed name
  4015. //
  4016. StringCopy (ActualFile, e.FindData->cFileName);
  4017. //
  4018. // Build source file (CompressedFile)
  4019. //
  4020. StringCopy (CompressedFile, InfDir);
  4021. StringCopy (AppendWack (CompressedFile), e.SubPath);
  4022. //
  4023. // Build destination file (UncompressedFile) and detect collisions
  4024. //
  4025. StringCopy (UncompressedFile, g_TempDir);
  4026. //
  4027. // Create uncompressed file path
  4028. //
  4029. if (*p == TEXT('_')) {
  4030. //
  4031. // Extract real name from INF file at offset 0x3c
  4032. //
  4033. ActualFile[0] = 0;
  4034. hFile = CreateFile (
  4035. CompressedFile,
  4036. GENERIC_READ,
  4037. FILE_SHARE_READ,
  4038. NULL,
  4039. OPEN_EXISTING,
  4040. FILE_ATTRIBUTE_NORMAL,
  4041. NULL
  4042. );
  4043. if (hFile != INVALID_HANDLE_VALUE) {
  4044. if (0xffffffff != SetFilePointer (hFile, 0x3c, NULL, FILE_BEGIN)) {
  4045. if (ReadFile (
  4046. hFile,
  4047. AnsiFileName,
  4048. MAX_PATH,
  4049. &BytesRead,
  4050. NULL
  4051. )) {
  4052. if (BytesRead >= SizeOfString (e.FindData->cFileName)) {
  4053. FileNameOnDisk = ConvertAtoT (AnsiFileName);
  4054. if (StringIMatchCharCount (
  4055. e.FindData->cFileName,
  4056. FileNameOnDisk,
  4057. CharCount (e.FindData->cFileName) - 1
  4058. )) {
  4059. //
  4060. // Real name found -- use it as ActualFile
  4061. //
  4062. StringCopy (ActualFile, FileNameOnDisk);
  4063. StringCopy (AppendWack (UncompressedFile), ActualFile);
  4064. }
  4065. FreeAtoT (FileNameOnDisk);
  4066. }
  4067. }
  4068. }
  4069. CloseHandle (hFile);
  4070. }
  4071. //
  4072. // If file name could not be found, discard this file
  4073. //
  4074. if (!ActualFile[0]) {
  4075. DEBUGMSG ((DBG_WARNING, "%s is not an INF file", e.FindData->cFileName));
  4076. continue;
  4077. }
  4078. DecompressFlag = TRUE;
  4079. } else {
  4080. StringCopy (AppendWack (UncompressedFile), ActualFile);
  4081. DecompressFlag = FALSE;
  4082. }
  4083. //
  4084. // Skip excluded files
  4085. //
  4086. if (!QueryFlag) {
  4087. //
  4088. // Uncompress file if necessary
  4089. //
  4090. /*
  4091. DEBUGMSG_IF ((
  4092. DoesFileExist (UncompressedFile),
  4093. DBG_WARNING,
  4094. "%s already exists and will be deleted",
  4095. UncompressedFile
  4096. ));
  4097. */
  4098. if (DecompressFlag) {
  4099. SetFileAttributes (UncompressedFile, FILE_ATTRIBUTE_NORMAL);
  4100. DeleteFile (UncompressedFile);
  4101. rc = SetupDecompressOrCopyFile (CompressedFile, UncompressedFile, 0);
  4102. if (rc != ERROR_SUCCESS) {
  4103. DEBUGMSG ((DBG_WARNING, "pLocalGetFileNamesWorker: Could not decompress %s to %s", CompressedFile, UncompressedFile));
  4104. fprintf (
  4105. stderr,
  4106. "Could not copy %s to %s. Error %u.",
  4107. CompressedFile,
  4108. UncompressedFile,
  4109. GetLastError()
  4110. );
  4111. break;
  4112. }
  4113. } else {
  4114. CopyFile (CompressedFile, UncompressedFile, FALSE);
  4115. }
  4116. //
  4117. // Determine if this is an NT 4 INF
  4118. //
  4119. if (!SetupGetInfInformation (
  4120. UncompressedFile,
  4121. INFINFO_INF_NAME_IS_ABSOLUTE,
  4122. psp,
  4123. sizeof (BufForSp),
  4124. NULL) ||
  4125. psp->InfStyle != INF_STYLE_WIN4
  4126. ) {
  4127. //DEBUGMSG ((DBG_WARNING, "%s is not a WIN4 INF file", UncompressedFile));
  4128. if (!QueryFlag) {
  4129. DeleteFile (UncompressedFile);
  4130. }
  4131. StringCopy (UncompressedFile, S_IGNORE_THIS_FILE);
  4132. }
  4133. }
  4134. //
  4135. // Add file to grow buffer
  4136. //
  4137. MemDbSetValueEx (MEMDB_CATEGORY_INF_FILES, UncompressedFile, NULL, NULL, 0, NULL);
  4138. }
  4139. MYASSERT (rc == ERROR_SUCCESS);
  4140. } while (EnumNextFileInTree (&e));
  4141. }
  4142. if (rc != ERROR_SUCCESS) {
  4143. SetLastError (rc);
  4144. DEBUGMSG ((DBG_WARNING, "pLocalGetFileNamesWorker: Error encountered in loop"));
  4145. __leave;
  4146. }
  4147. result = TRUE;
  4148. }
  4149. __finally {
  4150. FreeText (key);
  4151. FreeText (ActualFile);
  4152. FreeText (AnsiFileName);
  4153. FreeText (UncompressedFile);
  4154. FreeText (CompressedFile);
  4155. }
  4156. return result;
  4157. }
  4158. VOID
  4159. LocalFreeFileNames (
  4160. IN BOOL QueryFlag
  4161. )
  4162. /*++
  4163. Routine Description:
  4164. LocalFreeFileNames cleans up the list generated by LocalGetFileNames. If
  4165. QueryFlag is set to PERFORMCOMPLETEOP, all temporary decompressed
  4166. files are deleted.
  4167. Arguments:
  4168. FileNames - The same grow buffer passed to LocalGetFileNames
  4169. QueryFlag - The same flag passed to LocalGetFileNames
  4170. Return Value:
  4171. none
  4172. --*/
  4173. {
  4174. MEMDB_ENUM enumFiles;
  4175. if (MemDbEnumFirstValue (
  4176. &enumFiles,
  4177. MEMDB_CATEGORY_INF_FILES TEXT("\\*"),
  4178. MEMDB_ALL_SUBLEVELS,
  4179. MEMDB_ENDPOINTS_ONLY
  4180. )) {
  4181. do {
  4182. if (StringIMatchCharCount (enumFiles.szName, g_TempDirWack, g_TempDirWackChars)) {
  4183. SetFileAttributes (enumFiles.szName, FILE_ATTRIBUTE_NORMAL);
  4184. DeleteFile (enumFiles.szName);
  4185. }
  4186. } while (MemDbEnumNextValue (&enumFiles));
  4187. }
  4188. MemDbDeleteTree (MEMDB_CATEGORY_INF_FILES);
  4189. }