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

1855 lines
55 KiB

  1. #include "pch.h"
  2. #include <advpub.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <wchar.h>
  6. #include <tchar.h>
  7. #include <locale.h>
  8. #include <winnt32p.h>
  9. #include <init9x.h>
  10. #include <migdb.h>
  11. #include <sysmig.h>
  12. #include "..\..\w95upg\migapp\migdbp.h"
  13. typedef BOOL (WINAPI INITROUTINE_PROTOTYPE)(HINSTANCE, DWORD, LPVOID);
  14. INITROUTINE_PROTOTYPE MigUtil_Entry;
  15. INITROUTINE_PROTOTYPE MemDb_Entry;
  16. INITROUTINE_PROTOTYPE MigApp_Entry;
  17. INITROUTINE_PROTOTYPE FileEnum_Entry;
  18. HINSTANCE g_hInst;
  19. HANDLE g_hHeap;
  20. BOOL g_CancelFlag = FALSE;
  21. #define ATTR_FILESIZE 0x1
  22. #define ATTR_CHECKSUM 0x2
  23. #define ATTR_COMPNAME 0x4
  24. #define ATTR_FILEDESC 0x8
  25. #define ATTR_FILEVER 0x10
  26. #define ATTR_INTNAME 0x20
  27. #define ATTR_LEGAL 0x40
  28. #define ATTR_ORIGNAME 0x80
  29. #define ATTR_PRODNAME 0x100
  30. #define ATTR_PRODVER 0x200
  31. #define ATTR_EXETYPE 0x400
  32. #define ATTR_DESCR16 0x800
  33. #ifdef DEBUG
  34. extern BOOL g_DoLog;
  35. #endif
  36. extern POOLHANDLE g_MigDbPool;
  37. extern PMIGDB_CONTEXT g_ContextList;
  38. extern VOID *g_FileTable;
  39. extern BOOL *g_CancelFlagPtr = &g_CancelFlag;
  40. extern POOLHANDLE g_PathsPool;
  41. extern PMIGDB_HOOK_PROTOTYPE g_MigDbHook;
  42. typedef struct _PATTERN_FILE {
  43. PCTSTR Pattern;
  44. PMIGDB_ATTRIB PatternAttr;
  45. struct _PATTERN_FILE *Next;
  46. } PATTERN_FILE, *PPATTERN_FILE;
  47. PPATTERN_FILE g_AttrPatterns = NULL;
  48. BOOL
  49. pReadNtFilesEx (
  50. IN PCSTR FileListName
  51. );
  52. BOOL
  53. pScanForFile (
  54. IN PINFCONTEXT Context,
  55. IN DWORD FieldIndex
  56. );
  57. PMIGDB_ATTRIB
  58. pLoadAttribData (
  59. IN PCSTR MultiSzStr
  60. );
  61. BOOL
  62. CallAttribute (
  63. IN PMIGDB_ATTRIB MigDbAttrib,
  64. IN PDBATTRIB_PARAMS AttribParams
  65. );
  66. BOOL
  67. pWorkerFn (
  68. VOID
  69. );
  70. BOOL
  71. pLoadGoodFiles (
  72. IN HINF ConfigHandle
  73. );
  74. BOOL
  75. pLoadAttributes (
  76. IN HINF ConfigHandle
  77. );
  78. BOOL
  79. pLoadPatterns (
  80. IN HINF ConfigHandle
  81. );
  82. BOOL
  83. pHandleSection (
  84. IN PCTSTR SectionName,
  85. IN HINF ConfigHandle
  86. );
  87. BOOL
  88. pWriteMemdbSection (
  89. IN PCTSTR FileName,
  90. IN PCTSTR MemDbCategory,
  91. IN PCTSTR SectName,
  92. IN BOOL WriteByValue
  93. );
  94. BOOL
  95. pArrangeMigDbFile (
  96. IN PCTSTR SrcFile,
  97. IN PCTSTR DestFile
  98. );
  99. VOID
  100. pUsage (
  101. VOID
  102. )
  103. {
  104. _tprintf (TEXT ("\nCommand line syntax:\n\n"
  105. "MigUpd [/B:BaseDir] [/O:OutputFile] [/T:TempDir]\n\n"
  106. " /B Specifies the directory where source files are located (defaults to current dir)\n"
  107. " /O Specifies the name of the output file (defaults to .\\MIGDB.ADD)\n"
  108. " /T Specifies the temporary directory used for unpacking\n"
  109. " cabinet files (defaults to temp dir)\n"
  110. ));
  111. }
  112. PTSTR g_TempDir = NULL;
  113. PTSTR g_BaseDir = NULL;
  114. PTSTR g_ConfigFile = NULL;
  115. PTSTR g_MessageFile= NULL;
  116. PTSTR g_MigdbSrc = NULL;
  117. PTSTR g_MigdbDest = NULL;
  118. PTSTR g_MigdbDump = NULL;
  119. PTSTR g_InfTemplate = NULL;
  120. PTSTR g_FileListName = NULL;
  121. extern HINF g_MigDbInf;
  122. GROWBUFFER g_SectFiles = GROWBUF_INIT;
  123. #define MEMDB_CATEGORY_SECTFILES TEXT("SectFiles")
  124. #define MEMDB_CATEGORY_GOODFILES TEXT("GoodFiles")
  125. #define MEMDB_CATEGORY_WARNFILES TEXT("WarnFiles")
  126. #define MEMDB_CATEGORY_DUPLFILES TEXT("DuplFiles")
  127. #define MEMDB_CATEGORY_ACTION TEXT("Action")
  128. #define MEMDB_CATEGORY_ATTRIBUTES TEXT("Attributes")
  129. #define MEMDB_CATEGORY_RENAME_SRC TEXT("RenameSrc")
  130. #define MEMDB_CATEGORY_RENAME_DEST TEXT("RenameDest")
  131. #define MEMDB_CATEGORY_REQFILES TEXT("RequiredFiles")
  132. INT
  133. __cdecl
  134. main (
  135. int argc,
  136. CHAR *argv[]
  137. )
  138. {
  139. INT argidx, index;
  140. INT nextArg = 0;
  141. LONG rc;
  142. BOOL b = FALSE;
  143. BOOL b2 = FALSE;
  144. BOOL b3 = FALSE;
  145. TCHAR dirUpgInfs[MAX_PATH];
  146. TCHAR dirUpgInfs2[MAX_PATH];
  147. DWORD attrib;
  148. PTSTR p;
  149. TCHAR buf[12];
  150. DWORD seq;
  151. INT retcode = 1;
  152. #ifdef DEBUG
  153. g_DoLog = TRUE;
  154. #endif
  155. g_hInst = GetModuleHandle (NULL);
  156. g_hHeap = GetProcessHeap();
  157. if (!MigUtil_Entry (g_hInst, DLL_PROCESS_ATTACH, NULL)) {
  158. _tprintf (TEXT("MigUtil failed initializing\n"));
  159. exit (1);
  160. }
  161. if (!MemDb_Entry (g_hInst, DLL_PROCESS_ATTACH, NULL)) {
  162. _tprintf (TEXT("MemDb failed initializing\n"));
  163. exit(1);
  164. }
  165. if (!MigApp_Entry (g_hInst, DLL_PROCESS_ATTACH, NULL)) {
  166. _tprintf (TEXT("MigApp failed initializing\n"));
  167. exit (1);
  168. }
  169. for (argidx = 1; argidx < argc; argidx++) {
  170. if ((argv[argidx][0] != '-') &&
  171. (argv[argidx][0] != '/')
  172. ) {
  173. if (nextArg == 0) {
  174. pUsage ();
  175. exit (1);
  176. }
  177. switch (nextArg) {
  178. case 1:
  179. index = 0;
  180. goto label1;
  181. case 2:
  182. index = 0;
  183. goto label2;
  184. case 3:
  185. index = 0;
  186. goto label3;
  187. }
  188. }
  189. switch (toupper(argv[argidx][1])) {
  190. case 'B':
  191. if (argv[argidx][2] == 0) {
  192. nextArg = 1;
  193. }
  194. else {
  195. if (argv[argidx][2] != ':') {
  196. index = 2;
  197. }
  198. else {
  199. index = 3;
  200. }
  201. label1:
  202. nextArg = 0;
  203. g_BaseDir = argv[argidx]+index;
  204. }
  205. break;
  206. case 'O':
  207. if (argv[argidx][2] == 0) {
  208. nextArg = 2;
  209. }
  210. else {
  211. if (argv[argidx][2] != ':') {
  212. index = 2;
  213. }
  214. else {
  215. index = 3;
  216. }
  217. label2:
  218. nextArg = 0;
  219. g_MigdbDest = argv[argidx]+index;
  220. }
  221. break;
  222. case 'T':
  223. if (argv[argidx][2] == 0) {
  224. nextArg = 3;
  225. }
  226. else {
  227. if (argv[argidx][2] != ':') {
  228. index = 2;
  229. }
  230. else {
  231. index = 3;
  232. }
  233. label3:
  234. nextArg = 0;
  235. g_TempDir = argv[argidx]+index;
  236. }
  237. break;
  238. default:
  239. pUsage ();
  240. exit (1);
  241. }
  242. }
  243. if (g_TempDir == NULL) {
  244. g_TempDir = AllocPathString (MAX_TCHAR_PATH);
  245. if (GetEnvironmentVariable (TEXT("TEMP"), g_TempDir, MAX_TCHAR_PATH) == 0) {
  246. GetTempPath (MAX_TCHAR_PATH, g_TempDir);
  247. }
  248. b = TRUE;
  249. }
  250. if (!g_BaseDir) {
  251. g_BaseDir = TEXT(".");
  252. }
  253. if (!g_MigdbDest) {
  254. g_MigdbDest = JoinPaths (g_BaseDir, TEXT("migdb.add"));
  255. b2 = TRUE;
  256. }
  257. g_ConfigFile = JoinPaths (g_BaseDir, TEXT("migdb.cfg"));
  258. g_MessageFile = JoinPaths (g_BaseDir, TEXT("migdb.msg"));
  259. g_MigdbSrc = JoinPaths (g_BaseDir, TEXT("migdb.inf"));
  260. g_MigdbDump = JoinPaths (g_BaseDir, TEXT("migdb.dmp"));
  261. g_InfTemplate = JoinPaths (g_BaseDir, TEXT("header.inf"));
  262. g_FileListName = JoinPaths (g_BaseDir, TEXT("filelist.dat"));
  263. try {
  264. if (!DoesFileExist (g_FileListName)) {
  265. _tprintf (TEXT("\nNT file list file not found (%s). Exiting.\n"), g_FileListName);
  266. __leave;
  267. }
  268. if (!DoesFileExist (g_MigdbSrc)) {
  269. _tprintf (TEXT("\nSource file not found (%s). Exiting.\n"), g_MigdbSrc);
  270. __leave;
  271. }
  272. if (!DoesFileExist (g_ConfigFile)) {
  273. _tprintf (TEXT("\nConfiguration file not found (%s). Exiting.\n"), g_ConfigFile);
  274. __leave;
  275. }
  276. if (SearchPath (NULL, TEXT("expand.exe"), NULL, 0, NULL, NULL) == 0) {
  277. _tprintf (TEXT("\nCannot find expand.exe in path. Assuming there are no compressed files.\n"));
  278. }
  279. if (!CopyFile (g_InfTemplate, g_MigdbDest, FALSE)) {
  280. printf ("Could not copy %s to %s. Error Code: %x\n", g_InfTemplate, g_MigdbDest, GetLastError ());
  281. __leave;
  282. }
  283. DeleteFile (g_MessageFile);
  284. DeleteFile (g_MigdbDump);
  285. DISABLETRACKCOMMENT();
  286. g_InAnyDir = TRUE;
  287. if (!GetWindowsDirectory (dirUpgInfs, MAX_PATH)) {
  288. __leave;
  289. }
  290. StringCat (dirUpgInfs, TEXT("\\UpgInfs"));
  291. StringCopy (dirUpgInfs2, dirUpgInfs);
  292. seq = 2;
  293. p = GetEndOfString (dirUpgInfs2);
  294. do {
  295. wsprintf (p, TEXT("%u"), seq++);
  296. } while (GetFileAttributes (dirUpgInfs2) != -1);
  297. attrib = GetFileAttributes (dirUpgInfs);
  298. if (attrib != -1 && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0) {
  299. b3 = MoveFile (dirUpgInfs, dirUpgInfs2);
  300. }
  301. _tprintf (TEXT("\nReading NT file list: %s"), g_FileListName);
  302. if (!pReadNtFilesEx (g_FileListName)) {
  303. rc = GetLastError();
  304. printf ("Could not read %s. Win32 Error Code: %x\n", g_FileListName, rc);
  305. __leave;
  306. }
  307. _tprintf (TEXT("\nReading configuration files..."));
  308. if (!InitMigDbEx (g_MigdbSrc)) {
  309. rc = GetLastError();
  310. printf ("Could not read %s. Win32 Error Code: %x\n", g_MigdbSrc, rc);
  311. __leave;
  312. }
  313. if (!pWorkerFn ()) {
  314. __leave;
  315. }
  316. retcode = 0;
  317. }
  318. __finally {
  319. if (g_MigDbInf != INVALID_HANDLE_VALUE) {
  320. SetupCloseInfFile (g_MigDbInf);
  321. }
  322. pWriteMemdbSection (g_MessageFile, MEMDB_CATEGORY_GOODFILES, TEXT("KNOWN GOOD - FILES FOUND"), FALSE);
  323. pWriteMemdbSection (g_MessageFile, MEMDB_CATEGORY_WARNFILES, TEXT("KNOWN GOOD - NAME COLLISIONS"), FALSE);
  324. pWriteMemdbSection (g_MessageFile, MEMDB_CATEGORY_DUPLFILES, TEXT("DUPLICATE FILES"), FALSE);
  325. if (g_FileTable != NULL) {
  326. HtFree (g_FileTable);
  327. }
  328. if (g_MigDbPool != NULL) {
  329. PoolMemDestroyPool (g_MigDbPool);
  330. }
  331. FreePathString (g_ConfigFile);
  332. FreePathString (g_MessageFile);
  333. FreePathString (g_MigdbSrc);
  334. FreePathString (g_MigdbDump);
  335. FreePathString (g_InfTemplate);
  336. FreePathString (g_FileListName);
  337. if (b2) {
  338. FreePathString (g_MigdbDest);
  339. }
  340. if (b) {
  341. FreePathString (g_TempDir);
  342. }
  343. if (b3) {
  344. MoveFile (dirUpgInfs2, dirUpgInfs);
  345. }
  346. g_InAnyDir = FALSE;
  347. ENABLETRACKCOMMENT();
  348. MigApp_Entry (g_hInst, DLL_PROCESS_DETACH, NULL);
  349. MemDb_Entry (g_hInst, DLL_PROCESS_DETACH, NULL);
  350. MigUtil_Entry (g_hInst, DLL_PROCESS_DETACH, NULL);
  351. }
  352. return retcode;
  353. }
  354. UINT CALLBACK
  355. pCabinetCallback (
  356. IN PVOID Context, //context used by the callback routine
  357. IN UINT Notification, //notification sent to callback routine
  358. IN UINT Param1, //additional notification information
  359. IN UINT Param2 //additional notification information );
  360. )
  361. {
  362. PCTSTR tempDir = Context;
  363. PCTSTR fileName = (PCTSTR)Param2 ;
  364. PFILE_IN_CABINET_INFO fileInfo = (PFILE_IN_CABINET_INFO)Param1;
  365. PCTSTR fromPtr, toPtr;
  366. TCHAR tempStr [MEMDB_MAX];
  367. if (Notification == SPFILENOTIFY_FILEINCABINET) {
  368. if (toPtr = _tcschr (fileInfo->NameInCabinet, TEXT('\\'))) {
  369. _tcscpy (fileInfo->FullTargetName, tempDir);
  370. fromPtr = fileInfo->NameInCabinet;
  371. while (toPtr) {
  372. StringCopyAB (tempStr, fromPtr, toPtr);
  373. _tcscat (fileInfo->FullTargetName, TEXT("\\"));
  374. _tcscat (fileInfo->FullTargetName, tempStr);
  375. CreateDirectory (fileInfo->FullTargetName, NULL);
  376. toPtr = _tcsinc (toPtr);
  377. fromPtr = toPtr;
  378. toPtr = _tcschr (toPtr, TEXT('\\'));
  379. }
  380. }
  381. _stprintf (fileInfo->FullTargetName, TEXT("%s\\%s"), tempDir, fileInfo->NameInCabinet);
  382. return FILEOP_DOIT;
  383. }
  384. return NO_ERROR;
  385. }
  386. BOOL
  387. pWorkerFn (
  388. VOID
  389. )
  390. {
  391. HINF configHandle = INVALID_HANDLE_VALUE;
  392. INFCONTEXT context;
  393. TCHAR fileName [MAX_TCHAR_PATH] = "";
  394. TCHAR sectName [MAX_TCHAR_PATH];
  395. PTSTR dontCare;
  396. configHandle = SetupOpenInfFile (g_ConfigFile, NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
  397. if (configHandle == INVALID_HANDLE_VALUE) {
  398. SearchPath (NULL, g_ConfigFile, NULL, MAX_TCHAR_PATH, fileName, &dontCare);
  399. configHandle = SetupOpenInfFile (fileName, NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
  400. if (configHandle == INVALID_HANDLE_VALUE) {
  401. _tprintf (TEXT("\nCannot open configuration file %s. Exiting.\n"), g_ConfigFile);
  402. return FALSE;
  403. }
  404. }
  405. g_ContextList = (PMIGDB_CONTEXT) PoolMemGetMemory (g_MigDbPool, sizeof (MIGDB_CONTEXT));
  406. if (g_ContextList == NULL) {
  407. DEBUGMSG ((DBG_ERROR, "Unable to create empty context"));
  408. return FALSE;
  409. }
  410. ZeroMemory (g_ContextList, sizeof (MIGDB_CONTEXT));
  411. if (!pLoadGoodFiles (configHandle)) {
  412. _tprintf (TEXT("\nUnable to load good files section. Exiting.\n"));
  413. return FALSE;
  414. }
  415. if (!pLoadAttributes (configHandle)) {
  416. _tprintf (TEXT("\nUnable to load attributes section.\n"));
  417. }
  418. if (!pLoadPatterns (configHandle)) {
  419. _tprintf (TEXT("\nUnable to load patterns section.\n"));
  420. }
  421. else {
  422. _tprintf (TEXT("done\n\n"));
  423. }
  424. if (SetupFindFirstLine (configHandle, TEXT("sections"), NULL, &context)) {
  425. do {
  426. if (!SetupGetStringField (&context, 1, sectName, MAX_TCHAR_PATH, NULL)) {
  427. _tprintf (TEXT("\nBad section [SECTIONS] in %s. Exiting.\n"), g_ConfigFile);
  428. return FALSE;
  429. }
  430. if (!pHandleSection (sectName, configHandle)) {
  431. return FALSE;
  432. }
  433. }
  434. while (SetupFindNextLine (&context, &context));
  435. }
  436. return TRUE;
  437. }
  438. BOOL
  439. pLoadGoodFiles (
  440. IN HINF ConfigHandle
  441. )
  442. {
  443. INFCONTEXT context;
  444. if (SetupFindFirstLine (ConfigHandle, TEXT("good files"), NULL, &context)) {
  445. do {
  446. if (!pScanForFile (&context, 1)) {
  447. DEBUGMSG ((DBG_WARNING, "Scan for file failed:%d", GetLastError()));
  448. return FALSE;
  449. }
  450. }
  451. while (SetupFindNextLine (&context, &context));
  452. }
  453. return TRUE;
  454. }
  455. BOOL
  456. pLoadAttributes (
  457. IN HINF ConfigHandle
  458. )
  459. {
  460. TCHAR fileName [MEMDB_MAX];
  461. TCHAR attribStr [MEMDB_MAX];
  462. PCTSTR currAttr;
  463. DWORD attributes;
  464. DWORD dontCare;
  465. INFCONTEXT context;
  466. if (SetupFindFirstLine (ConfigHandle, TEXT("Attributes"), NULL, &context)) {
  467. do {
  468. if (SetupGetStringField (&context, 1, fileName, MAX_TCHAR_PATH, NULL)) {
  469. if (!SetupGetStringField (&context, 2, attribStr, MAX_TCHAR_PATH, NULL)) {
  470. attribStr [0] = 0;
  471. }
  472. currAttr = attribStr;
  473. attributes = 0;
  474. while (*currAttr) {
  475. switch (toupper(*currAttr)) {
  476. case 'S':
  477. attributes |= ATTR_FILESIZE;
  478. break;
  479. case 'C':
  480. attributes |= ATTR_CHECKSUM;
  481. break;
  482. case 'N':
  483. attributes |= ATTR_COMPNAME;
  484. break;
  485. case 'F':
  486. attributes |= ATTR_FILEDESC;
  487. break;
  488. case 'V':
  489. attributes |= ATTR_FILEVER;
  490. break;
  491. case 'I':
  492. attributes |= ATTR_INTNAME;
  493. break;
  494. case 'L':
  495. attributes |= ATTR_LEGAL;
  496. break;
  497. case 'O':
  498. attributes |= ATTR_ORIGNAME;
  499. break;
  500. case 'P':
  501. attributes |= ATTR_PRODNAME;
  502. break;
  503. case 'E':
  504. attributes |= ATTR_PRODVER;
  505. break;
  506. case 'T':
  507. attributes |= ATTR_EXETYPE;
  508. break;
  509. case 'D':
  510. attributes |= ATTR_DESCR16;
  511. break;
  512. default:
  513. _tprintf (TEXT("\nInvalid attributes:%s\n"), currAttr);
  514. }
  515. currAttr = _tcsinc (currAttr);
  516. }
  517. MemDbSetValueEx (
  518. MEMDB_CATEGORY_ATTRIBUTES,
  519. fileName,
  520. NULL,
  521. NULL,
  522. attributes,
  523. &dontCare
  524. );
  525. }
  526. }
  527. while (SetupFindNextLine (&context, &context));
  528. }
  529. return TRUE;
  530. }
  531. BOOL
  532. pLoadPatterns (
  533. IN HINF ConfigHandle
  534. )
  535. {
  536. TCHAR patternFile [MEMDB_MAX];
  537. TCHAR patternStr [MEMDB_MAX];
  538. INFCONTEXT context;
  539. PPATTERN_FILE fileStruct;
  540. if (SetupFindFirstLine (ConfigHandle, TEXT("Patterns"), NULL, &context)) {
  541. do {
  542. if (SetupGetStringField (&context, 1, patternFile, MAX_TCHAR_PATH, NULL) &&
  543. SetupGetMultiSzField (&context, 2, patternStr, MAX_TCHAR_PATH, NULL)
  544. ) {
  545. fileStruct = (PPATTERN_FILE) PoolMemGetMemory (g_MigDbPool, sizeof (PATTERN_FILE));
  546. fileStruct->Pattern = PoolMemDuplicateString (g_MigDbPool, patternFile);
  547. fileStruct->PatternAttr = pLoadAttribData (patternStr);
  548. fileStruct->Next = g_AttrPatterns;
  549. g_AttrPatterns = fileStruct;
  550. }
  551. }
  552. while (SetupFindNextLine (&context, &context));
  553. }
  554. return TRUE;
  555. }
  556. BOOL
  557. pDeleteAllFiles (
  558. IN PCTSTR DirPath
  559. )
  560. {
  561. TREE_ENUM e;
  562. BOOL dirsFirst = FALSE;
  563. if (EnumFirstFileInTree (&e, DirPath, TEXT("*"), dirsFirst)) {
  564. do {
  565. if (e.Directory) {
  566. pDeleteAllFiles (e.FullPath);
  567. SetFileAttributes (e.FullPath, FILE_ATTRIBUTE_NORMAL);
  568. RemoveDirectory (e.FullPath);
  569. }
  570. else {
  571. SetFileAttributes (e.FullPath, FILE_ATTRIBUTE_NORMAL);
  572. DeleteFile (e.FullPath);
  573. }
  574. } while (EnumNextFileInTree (&e));
  575. }
  576. return TRUE;
  577. }
  578. BOOL
  579. pSelected (
  580. IN PCTSTR FileName
  581. )
  582. {
  583. MULTISZ_ENUM patternEnum;
  584. if (EnumFirstMultiSz (&patternEnum, g_SectFiles.Buf)) {
  585. do {
  586. if (IsPatternMatch (patternEnum.CurrentString, FileName)) {
  587. return TRUE;
  588. }
  589. }
  590. while (EnumNextMultiSz (&patternEnum));
  591. }
  592. return FALSE;
  593. }
  594. BOOL
  595. pSpecialSelected (
  596. IN PCTSTR FileName,
  597. OUT PTSTR NewName
  598. )
  599. {
  600. MULTISZ_ENUM patternEnum;
  601. PTSTR endPtr, endPtr1;
  602. TCHAR savedVal;
  603. if (EnumFirstMultiSz (&patternEnum, g_SectFiles.Buf)) {
  604. do {
  605. endPtr = _tcsdec (patternEnum.CurrentString, GetEndOfString (patternEnum.CurrentString));
  606. savedVal = *endPtr;
  607. *endPtr = TEXT('_');
  608. if (IsPatternMatch (patternEnum.CurrentString, FileName)) {
  609. StringCopy (NewName, FileName);
  610. endPtr1 = _tcsdec (NewName, GetEndOfString (NewName));
  611. *endPtr1 = savedVal;
  612. *endPtr = savedVal;
  613. return TRUE;
  614. }
  615. *endPtr = savedVal;
  616. }
  617. while (EnumNextMultiSz (&patternEnum));
  618. }
  619. StringCopy (NewName, FileName);
  620. endPtr = _tcsdec (NewName, GetEndOfString (NewName));
  621. *endPtr = TEXT('-');
  622. return FALSE;
  623. }
  624. DWORD g_DirSequencer = 0;
  625. DWORD g_FileSequencer = 0;
  626. BOOL
  627. pCabinetFile (
  628. IN PCTSTR FileName
  629. )
  630. {
  631. PCTSTR extPtr;
  632. extPtr = GetFileExtensionFromPath (FileName);
  633. if ((extPtr != NULL) &&
  634. StringIMatch (extPtr, TEXT("CAB"))
  635. ) {
  636. return TRUE;
  637. }
  638. return FALSE;
  639. }
  640. #define ATTR_FILESIZE 0x1
  641. #define ATTR_CHECKSUM 0x2
  642. #define ATTR_COMPNAME 0x4
  643. #define ATTR_FILEDESC 0x8
  644. #define ATTR_FILEVER 0x10
  645. #define ATTR_INTNAME 0x20
  646. #define ATTR_LEGAL 0x40
  647. #define ATTR_ORIGNAME 0x80
  648. #define ATTR_PRODNAME 0x100
  649. #define ATTR_PRODVER 0x200
  650. #define ATTR_EXETYPE 0x400
  651. #define ATTR_DESCR16 0x800
  652. typedef struct _VERSION_DATA {
  653. PCSTR versionValue;
  654. PCSTR versionName;
  655. DWORD attrib;
  656. } VERSION_DATA, *PVERSION_DATA;
  657. VERSION_DATA verData [] = {{NULL, "COMPANYNAME", ATTR_COMPNAME},
  658. {NULL, "FILEDESCRIPTION", ATTR_FILEDESC},
  659. {NULL, "FILEVERSION", ATTR_FILEVER},
  660. {NULL, "INTERNALNAME", ATTR_INTNAME},
  661. {NULL, "LEGALCOPYRIGHT", ATTR_LEGAL},
  662. {NULL, "ORIGINALFILENAME", ATTR_ORIGNAME},
  663. {NULL, "PRODUCTNAME", ATTR_PRODNAME},
  664. {NULL, "PRODUCTVERSION", ATTR_PRODVER},
  665. {NULL, NULL, 0}};
  666. extern PSTR g_ExeTypes[4];
  667. BOOL
  668. pCheckForPattern (
  669. IN PCTSTR FileName,
  670. PFILE_HELPER_PARAMS Params,
  671. OUT PTSTR FileAttr,
  672. IN OUT PGROWBUFFER AttrList
  673. )
  674. {
  675. PPATTERN_FILE patternFile;
  676. PMIGDB_ATTRIB migDbAttrib;
  677. DBATTRIB_PARAMS attribParams;
  678. BOOL fileSelected;
  679. BOOL found;
  680. TCHAR temp [MEMDB_MAX];
  681. MULTISZ_ENUMA multiSzEnum;
  682. BOOL first;
  683. patternFile = g_AttrPatterns;
  684. found = FALSE;
  685. while (patternFile) {
  686. if (IsPatternMatch (patternFile->Pattern, FileName)) {
  687. fileSelected = TRUE;
  688. migDbAttrib = patternFile->PatternAttr;
  689. while (migDbAttrib) {
  690. attribParams.FileParams = Params;
  691. attribParams.ExtraData = NULL;
  692. if (!CallAttribute (migDbAttrib, &attribParams)) {
  693. fileSelected = FALSE;
  694. break;
  695. }
  696. migDbAttrib = migDbAttrib->Next;
  697. }
  698. if (fileSelected) {
  699. found = TRUE;
  700. break;
  701. }
  702. }
  703. patternFile = patternFile->Next;
  704. }
  705. if (found) {
  706. migDbAttrib = patternFile->PatternAttr;
  707. while (migDbAttrib) {
  708. _tcscpy (temp, MigDb_GetAttributeName (migDbAttrib->AttribIndex));
  709. first = TRUE;
  710. if (EnumFirstMultiSz (&multiSzEnum, migDbAttrib->Arguments)) {
  711. _tcscat (temp, TEXT("("));
  712. do {
  713. if (!first) {
  714. _tcscat (FileAttr, TEXT(","));
  715. _tcscat (FileAttr, temp);
  716. if (AttrList) {
  717. MultiSzAppend (AttrList, temp);
  718. }
  719. *temp = 0;
  720. }
  721. first = FALSE;
  722. _tcscat (temp, TEXT("\""));
  723. _tcscat (temp, multiSzEnum.CurrentString);
  724. _tcscat (temp, TEXT("\""));
  725. }
  726. while (EnumNextMultiSz (&multiSzEnum));
  727. _tcscat (temp, TEXT(")"));
  728. }
  729. _tcscat (FileAttr, TEXT(","));
  730. _tcscat (FileAttr, temp);
  731. if (AttrList) {
  732. MultiSzAppend (AttrList, temp);
  733. }
  734. migDbAttrib = migDbAttrib->Next;
  735. }
  736. return TRUE;
  737. }
  738. return FALSE;
  739. }
  740. BOOL
  741. pPrintLine (
  742. IN PTREE_ENUM e,
  743. OUT PTSTR FileAttr,
  744. IN OUT PGROWBUFFER AttrList
  745. )
  746. {
  747. FILE_HELPER_PARAMS Params;
  748. UINT checkSum;
  749. DWORD exeType;
  750. PCSTR fileDesc16;
  751. INT numAttribs;
  752. DWORD listedAttr;
  753. TCHAR ekey [MEMDB_MAX];
  754. TCHAR temp [MEMDB_MAX];
  755. PVERSION_DATA p;
  756. Params.Handled = 0;
  757. Params.FullFileSpec = e->FullPath;
  758. _tcsncpy (Params.DirSpec, e->RootPath, MAX_TCHAR_PATH);
  759. Params.IsDirectory = FALSE;
  760. Params.Extension = GetFileExtensionFromPath (e->Name);
  761. Params.FindData = e->FindData;
  762. Params.VirtualFile = FALSE;
  763. FileAttr [0] = 0;
  764. if (!StringIMatch (e->Name, TEXT("kernel32.dll"))) {
  765. if (pCheckForPattern (e->Name, &Params, FileAttr, AttrList)) {
  766. return TRUE;
  767. }
  768. }
  769. numAttribs = 0;
  770. MemDbBuildKey (ekey, MEMDB_CATEGORY_ATTRIBUTES, e->Name, NULL, NULL);
  771. if (!MemDbGetPatternValue (ekey, &listedAttr)) {
  772. listedAttr = ATTR_COMPNAME | ATTR_PRODVER;
  773. }
  774. if (listedAttr & ATTR_FILESIZE) {
  775. _stprintf (
  776. temp,
  777. TEXT(",FILESIZE(0x%08lX)"),
  778. e->FindData->nFileSizeLow);
  779. _tcscat (FileAttr, temp);
  780. if (AttrList) {
  781. _stprintf (
  782. temp,
  783. TEXT("FILESIZE(0x%08lX)"),
  784. e->FindData->nFileSizeLow);
  785. MultiSzAppend (AttrList, temp);
  786. }
  787. numAttribs ++;
  788. }
  789. if (listedAttr & ATTR_CHECKSUM) {
  790. checkSum = ComputeCheckSum (&Params);
  791. _stprintf (
  792. temp,
  793. TEXT(",CHECKSUM(0x%08lX)"),
  794. checkSum);
  795. _tcscat (FileAttr, temp);
  796. if (AttrList) {
  797. _stprintf (
  798. temp,
  799. TEXT("CHECKSUM(0x%08lX)"),
  800. checkSum);
  801. MultiSzAppend (AttrList, temp);
  802. }
  803. numAttribs ++;
  804. }
  805. if (listedAttr & ATTR_EXETYPE) {
  806. exeType = GetModuleType (e->FullPath);
  807. _stprintf (
  808. temp,
  809. TEXT(",EXETYPE(\"%s\")"),
  810. g_ExeTypes[exeType]);
  811. _tcscat (FileAttr, temp);
  812. if (AttrList) {
  813. _stprintf (
  814. temp,
  815. TEXT("EXETYPE(%s)"),
  816. g_ExeTypes[exeType]);
  817. MultiSzAppend (AttrList, temp);
  818. }
  819. numAttribs ++;
  820. }
  821. if (listedAttr & ATTR_DESCR16) {
  822. fileDesc16 = Get16ModuleDescription (e->FullPath);
  823. if (fileDesc16 != NULL) {
  824. _stprintf (
  825. temp,
  826. TEXT(",DESCRIPTION(\"%s\")"),
  827. fileDesc16);
  828. _tcscat (FileAttr, temp);
  829. if (AttrList) {
  830. _stprintf (
  831. temp,
  832. TEXT("DESCRIPTION(%s)"),
  833. fileDesc16);
  834. MultiSzAppend (AttrList, temp);
  835. }
  836. numAttribs ++;
  837. FreePathString (fileDesc16);
  838. }
  839. }
  840. p = verData;
  841. while (p->versionName) {
  842. if (listedAttr & p->attrib) {
  843. p->versionValue = QueryVersionEntry (e->FullPath, p->versionName);
  844. }
  845. p++;
  846. }
  847. p = verData;
  848. while (p->versionName) {
  849. if ((listedAttr & p->attrib) && (p->versionValue)) {
  850. _stprintf (
  851. temp,
  852. TEXT(",%s(\"%s\")"),
  853. p->versionName,
  854. p->versionValue);
  855. _tcscat (FileAttr, temp);
  856. if (AttrList) {
  857. _stprintf (
  858. temp,
  859. TEXT("%s(%s)"),
  860. p->versionName,
  861. p->versionValue);
  862. MultiSzAppend (AttrList, temp);
  863. }
  864. FreePathString (p->versionValue);
  865. numAttribs ++;
  866. }
  867. p++;
  868. }
  869. if (numAttribs == 0) {
  870. checkSum = ComputeCheckSum (&Params);
  871. _stprintf (
  872. temp,
  873. TEXT(",FC(%ld,%lX)"),
  874. e->FindData->nFileSizeLow,
  875. checkSum
  876. );
  877. _tcscat (FileAttr, temp);
  878. if (AttrList) {
  879. _stprintf (
  880. temp,
  881. TEXT("FC(%ld"),
  882. e->FindData->nFileSizeLow
  883. );
  884. MultiSzAppend (AttrList, temp);
  885. _stprintf (
  886. temp,
  887. TEXT("%lX)"),
  888. checkSum
  889. );
  890. MultiSzAppend (AttrList, temp);
  891. }
  892. }
  893. return TRUE;
  894. }
  895. BOOL
  896. pHandleAppFile (
  897. IN PTREE_ENUM e,
  898. IN PCTSTR Action,
  899. IN PCTSTR Section,
  900. IN PCTSTR Message,
  901. IN PCTSTR SrcPath
  902. )
  903. {
  904. TCHAR msgStr [MEMDB_MAX] = "";
  905. FILE_HELPER_PARAMS Params;
  906. TCHAR line [MEMDB_MAX];
  907. TCHAR key [MEMDB_MAX] = "";
  908. DWORD offset;
  909. Params.Handled = 0;
  910. Params.FullFileSpec = e->FullPath;
  911. _tcsncpy (Params.DirSpec, SrcPath, MAX_TCHAR_PATH);
  912. Params.IsDirectory = FALSE;
  913. Params.Extension = GetFileExtensionFromPath (e->Name);
  914. Params.FindData = e->FindData;
  915. Params.VirtualFile = FALSE;
  916. pPrintLine (e, line, NULL);
  917. MemDbBuildKey (key, MEMDB_CATEGORY_RENAME_SRC, e->Name, NULL, NULL);
  918. if (MemDbGetValue (key, &offset)) {
  919. if (!MemDbBuildKeyFromOffset (offset, key, 1, NULL)) {
  920. *key = 0;
  921. }
  922. } else {
  923. *key = 0;
  924. }
  925. _stprintf (
  926. msgStr,
  927. TEXT("%s\\%s%s)"),
  928. MEMDB_CATEGORY_SECTFILES,
  929. *key?key:e->Name,
  930. line);
  931. MemDbSetValue (msgStr, 0);
  932. return TRUE;
  933. }
  934. BOOL
  935. pHandleSysFile (
  936. IN PTREE_ENUM e,
  937. IN PCTSTR Action,
  938. IN PCTSTR Section,
  939. IN PCTSTR Message,
  940. IN PCTSTR SrcPath
  941. )
  942. {
  943. TCHAR msgStr [MEMDB_MAX] = "";
  944. FILE_HELPER_PARAMS Params;
  945. HASHITEM stringId;
  946. PMIGDB_FILE migDbFile;
  947. FILE_LIST_STRUCT fileList;
  948. PMIGDB_ATTRIB migDbAttrib;
  949. DBATTRIB_PARAMS attribParams;
  950. BOOL fileSelected = FALSE;
  951. PCTSTR actionTmp;
  952. TCHAR line [MEMDB_MAX];
  953. TCHAR key [MEMDB_MAX] = "";
  954. DWORD offset;
  955. GROWBUFFER attrList = GROWBUF_INIT;
  956. // this is not a cabinet file, let's do something with it.
  957. Params.Handled = 0;
  958. Params.FullFileSpec = e->FullPath;
  959. _tcsncpy (Params.DirSpec, SrcPath, MAX_TCHAR_PATH);
  960. Params.IsDirectory = FALSE;
  961. Params.Extension = GetFileExtensionFromPath (e->Name);
  962. Params.FindData = e->FindData;
  963. Params.VirtualFile = FALSE;
  964. pPrintLine (e, line, &attrList);
  965. if (StringIMatch (e->Name, TEXT("kernel32.dll"))) {
  966. _stprintf (
  967. msgStr,
  968. TEXT("%s\\%s%s"),
  969. MEMDB_CATEGORY_REQFILES,
  970. e->Name,
  971. line);
  972. MemDbSetValue (msgStr, fileSelected);
  973. };
  974. // first check if this file is in "known good" list or is already listed in migdb.inf
  975. // with same action
  976. stringId = HtFindString (g_FileTable, e->Name);
  977. if (stringId) {
  978. //The string table has extra data (a pointer to a FILE_LIST_STRUCT node)
  979. HtCopyStringData (g_FileTable, stringId, &fileList);
  980. migDbFile = fileList.First;
  981. while (migDbFile) {
  982. //check all attributes for this file
  983. migDbAttrib = migDbFile->Attributes;
  984. fileSelected = TRUE;
  985. while (migDbAttrib != NULL) {
  986. attribParams.FileParams = &Params;
  987. attribParams.ExtraData = NULL;
  988. if (!CallAttribute (migDbAttrib, &attribParams)) {
  989. fileSelected = FALSE;
  990. break;
  991. }
  992. migDbAttrib = migDbAttrib->Next;
  993. }
  994. if ((!fileSelected) &&
  995. (migDbFile->Section == NULL)
  996. ) {
  997. // there was a name collision with a "known good" file. We will send a message
  998. _stprintf (msgStr, TEXT("%s\\%s"), MEMDB_CATEGORY_WARNFILES, e->Name);
  999. MemDbSetValue (msgStr, 0);
  1000. }
  1001. if ((fileSelected) &&
  1002. (migDbFile->Section == NULL)
  1003. ) {
  1004. // this file is "known good". We will send a message
  1005. _stprintf (msgStr, TEXT("%s\\%s"), MEMDB_CATEGORY_GOODFILES, e->Name);
  1006. MemDbSetValue (msgStr, 0);
  1007. break;
  1008. }
  1009. if ((fileSelected) && (!StringIMatch (Section, migDbFile->Section->Context->SectName))){
  1010. actionTmp = MigDb_GetActionName (migDbFile->Section->Context->ActionIndex);
  1011. if ((actionTmp != NULL) && StringIMatch (actionTmp, Action)) {
  1012. // this file was already listed in migdb.inf with the same action
  1013. _stprintf (
  1014. msgStr,
  1015. TEXT("%s\\%s\\%-14s%s"),
  1016. MEMDB_CATEGORY_DUPLFILES,
  1017. Action,
  1018. e->Name,
  1019. line);
  1020. MemDbSetValue (msgStr, 0);
  1021. break;
  1022. }
  1023. }
  1024. fileSelected = FALSE;
  1025. migDbFile = migDbFile->Next;
  1026. }
  1027. }
  1028. if (!fileSelected) {
  1029. // one more check. If this file is in FILELIST.DAT (but not in the EXCEPTED section)
  1030. // and COMPANYNAME attribute has Microsoft somewhere inside we'll put it in a different
  1031. // place
  1032. MemDbBuildKey (key, MEMDB_CATEGORY_NT_FILES, e->Name, NULL, NULL);
  1033. if (MemDbGetValue (key, NULL)) {
  1034. MemDbBuildKey (key, MEMDB_CATEGORY_NT_FILES_EXCEPT, e->Name, NULL, NULL);
  1035. if (!MemDbGetValue (key, NULL)) {
  1036. if (GlobalVersionCheck (e->FullPath, "COMPANYNAME", "*MICROSOFT*")) {
  1037. fileSelected = TRUE;
  1038. }
  1039. }
  1040. }
  1041. // this file is not in the list or attributes do not match
  1042. // we will add in incompatibility list.
  1043. //creating MIGDB_FILE structure for current file
  1044. migDbFile = (PMIGDB_FILE) PoolMemGetMemory (g_MigDbPool, sizeof (MIGDB_FILE));
  1045. if (migDbFile != NULL) {
  1046. ZeroMemory (migDbFile, sizeof (MIGDB_FILE));
  1047. migDbFile->Section = g_ContextList->Sections;
  1048. migDbFile->Attributes = pLoadAttribData (attrList.Buf);
  1049. if (g_MigDbHook != NULL) {
  1050. migDbAttrib = migDbFile->Attributes;
  1051. while (migDbAttrib) {
  1052. g_MigDbHook (e->Name, g_ContextList, g_ContextList->Sections, migDbFile, migDbAttrib);
  1053. migDbAttrib = migDbAttrib->Next;
  1054. }
  1055. }
  1056. //adding this file into string table and create a MIGDB_FILE node. If file
  1057. //already exists in string table then just create another MIGDB_FILE node
  1058. //chained with already existing ones.
  1059. stringId = HtFindString (g_FileTable, e->Name);
  1060. if (stringId) {
  1061. HtCopyStringData (g_FileTable, stringId, &fileList);
  1062. fileList.Last->Next = migDbFile;
  1063. fileList.Last = migDbFile;
  1064. HtSetStringData (g_FileTable, stringId, &fileList);
  1065. }
  1066. else {
  1067. fileList.First = fileList.Last = migDbFile;
  1068. HtAddStringAndData (g_FileTable, e->Name, &fileList);
  1069. }
  1070. }
  1071. else {
  1072. DEBUGMSG ((DBG_ERROR, "Unable to allocate file node for %s", e->Name));
  1073. }
  1074. MemDbBuildKey (key, MEMDB_CATEGORY_RENAME_SRC, e->Name, NULL, NULL);
  1075. if (MemDbGetValue (key, &offset)) {
  1076. if (!MemDbBuildKeyFromOffset (offset, key, 1, NULL)) {
  1077. *key = 0;
  1078. }
  1079. } else {
  1080. *key = 0;
  1081. }
  1082. _stprintf (
  1083. msgStr,
  1084. TEXT("%s\\%s%s"),
  1085. MEMDB_CATEGORY_SECTFILES,
  1086. *key?key:e->Name,
  1087. line);
  1088. MemDbSetValue (msgStr, fileSelected);
  1089. }
  1090. FreeGrowBuffer (&attrList);
  1091. return TRUE;
  1092. }
  1093. BOOL
  1094. pCompressedFile (
  1095. IN PTREE_ENUM e
  1096. )
  1097. {
  1098. PCTSTR extPtr;
  1099. extPtr = GetFileExtensionFromPath (e->FullPath);
  1100. if (extPtr == NULL) {
  1101. return FALSE;
  1102. }
  1103. if (_tcslen (extPtr) != 3) {
  1104. return FALSE;
  1105. }
  1106. return (extPtr [2] == TEXT('_'));
  1107. }
  1108. BOOL
  1109. pExeFile (
  1110. IN PTREE_ENUM e
  1111. )
  1112. {
  1113. PCTSTR extPtr;
  1114. extPtr = GetFileExtensionFromPath (e->FullPath);
  1115. if ((extPtr != NULL) &&
  1116. (StringIMatch (extPtr, TEXT("EXE")))
  1117. ) {
  1118. return TRUE;
  1119. }
  1120. return FALSE;
  1121. }
  1122. BOOL
  1123. pCopyAndHandleCabResource (
  1124. IN PVOID Source,
  1125. IN DWORD Size,
  1126. IN PCTSTR DirName
  1127. )
  1128. {
  1129. TCHAR cabDir [MAX_TCHAR_PATH] = "";
  1130. HANDLE hFile;
  1131. DWORD dontCare;
  1132. if (Size < 4) {
  1133. return TRUE;
  1134. }
  1135. if (*((PDWORD)Source) != 0x4643534D) {
  1136. return TRUE;
  1137. }
  1138. g_FileSequencer ++;
  1139. _stprintf (cabDir, TEXT("%s\\MIGDB%03u.CAB"), DirName, g_FileSequencer);
  1140. hFile = CreateFile (cabDir, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  1141. if (hFile == INVALID_HANDLE_VALUE) {
  1142. DEBUGMSG ((DBG_ERROR, "Cannot create file %s", cabDir));
  1143. return FALSE;
  1144. }
  1145. if (!WriteFile (hFile, Source, Size, &dontCare, NULL)) {
  1146. DEBUGMSG ((DBG_ERROR, "Cannot write to file %s", cabDir));
  1147. return FALSE;
  1148. }
  1149. CloseHandle (hFile);
  1150. return TRUE;
  1151. }
  1152. BOOL CALLBACK
  1153. EnumResNameProc (
  1154. IN HANDLE hModule, // module handle
  1155. IN LPCTSTR lpszType, // pointer to resource type
  1156. IN LPTSTR lpszName, // pointer to resource name
  1157. IN LONG lParam // application-defined parameter
  1158. )
  1159. {
  1160. HRSRC hResource;
  1161. DWORD size;
  1162. HGLOBAL hGlobal;
  1163. PVOID srcBytes;
  1164. hResource = FindResource (hModule, lpszName, lpszType);
  1165. if (hResource) {
  1166. size = SizeofResource (hModule, hResource);
  1167. if (size) {
  1168. hGlobal = LoadResource (hModule, hResource);
  1169. if (hGlobal) {
  1170. srcBytes = LockResource (hGlobal);
  1171. if (srcBytes) {
  1172. pCopyAndHandleCabResource (srcBytes, size, (PCTSTR)lParam);
  1173. }
  1174. }
  1175. }
  1176. }
  1177. return TRUE;
  1178. }
  1179. BOOL CALLBACK
  1180. EnumResTypeProc (
  1181. IN HANDLE hModule, // resource-module handle
  1182. IN LPTSTR lpszType, // pointer to resource type
  1183. IN LONG lParam // application-defined parameter
  1184. )
  1185. {
  1186. if ((lpszType != RT_ACCELERATOR ) &&
  1187. (lpszType != RT_ANICURSOR ) &&
  1188. (lpszType != RT_ANIICON ) &&
  1189. (lpszType != RT_BITMAP ) &&
  1190. (lpszType != RT_CURSOR ) &&
  1191. (lpszType != RT_DIALOG ) &&
  1192. (lpszType != RT_FONT ) &&
  1193. (lpszType != RT_FONTDIR ) &&
  1194. (lpszType != RT_GROUP_CURSOR ) &&
  1195. (lpszType != RT_GROUP_ICON ) &&
  1196. (lpszType != RT_HTML ) &&
  1197. (lpszType != RT_ICON ) &&
  1198. (lpszType != RT_MENU ) &&
  1199. (lpszType != RT_MESSAGETABLE ) &&
  1200. (lpszType != RT_PLUGPLAY ) &&
  1201. (lpszType != RT_STRING ) &&
  1202. (lpszType != RT_VERSION ) &&
  1203. (lpszType != RT_VXD ) &&
  1204. (lpszType != RT_HTML )
  1205. ) {
  1206. // we found an unknown type. Let's enumerate all resources of this type
  1207. if (EnumResourceNames (hModule, lpszType, EnumResNameProc, lParam) == 0) {
  1208. DEBUGMSG ((DBG_ERROR, "Error enumerating names:%ld", GetLastError ()));
  1209. }
  1210. }
  1211. return TRUE;
  1212. }
  1213. BOOL
  1214. pHandleAllFiles (
  1215. IN BOOL AppMode,
  1216. IN PCTSTR Action,
  1217. IN PCTSTR Section,
  1218. IN PCTSTR Message,
  1219. IN PCTSTR SrcPath
  1220. )
  1221. {
  1222. TCHAR tempDir [MAX_TCHAR_PATH] = "";
  1223. TCHAR cmdLine [MAX_TCHAR_PATH] = "";
  1224. TCHAR newName [MAX_TCHAR_PATH] = "";
  1225. TREE_ENUM e;
  1226. DWORD error;
  1227. HMODULE exeModule;
  1228. PROCESS_INFORMATION processInfo;
  1229. STARTUPINFO startupInfo;
  1230. if (EnumFirstFileInTree (&e, SrcPath, TEXT("*"), FALSE)) {
  1231. do {
  1232. if (!e.Directory) {
  1233. if (pCabinetFile (e.Name)) {
  1234. if ((AppMode) ||
  1235. (!pSelected (e.Name))
  1236. ) {
  1237. // cabinet file
  1238. g_DirSequencer++;
  1239. _stprintf (tempDir, TEXT("%s\\MIGDB%03u"), g_TempDir, g_DirSequencer);
  1240. if (CreateDirectory (tempDir, NULL) == 0) {
  1241. error = GetLastError ();
  1242. if (error == ERROR_ALREADY_EXISTS) {
  1243. pDeleteAllFiles (tempDir);
  1244. }
  1245. ELSE_DEBUGMSG ((DBG_ERROR, "Cannot create directory %s", tempDir));
  1246. }
  1247. _tprintf (TEXT(" Extracting cabinet file ... %s"), e.Name);
  1248. // we need to expand the cabinet file
  1249. SetLastError (0);
  1250. if (!SetupIterateCabinet (e.FullPath, 0, pCabinetCallback, tempDir)) {
  1251. _tprintf (TEXT("...error %ld\n"), GetLastError());
  1252. DEBUGMSG((DBG_ERROR, "Could not iterate cabinet file:%s\nError:%ld", e.FullPath, GetLastError ()));
  1253. }
  1254. else {
  1255. _tprintf (TEXT("...done\n"));
  1256. }
  1257. if (!pHandleAllFiles (AppMode, Action, Section, Message, tempDir)) {
  1258. return FALSE;
  1259. }
  1260. pDeleteAllFiles (tempDir);
  1261. RemoveDirectory (tempDir);
  1262. g_DirSequencer--;
  1263. }
  1264. }
  1265. else if (pCompressedFile (&e)) {
  1266. if (AppMode) {
  1267. if (!pSpecialSelected (e.Name, newName)) {
  1268. continue;
  1269. }
  1270. }
  1271. else {
  1272. if (pSpecialSelected (e.Name, newName)) {
  1273. continue;
  1274. }
  1275. }
  1276. // compressed file
  1277. g_DirSequencer++;
  1278. _stprintf (tempDir, TEXT("%s\\MIGDB%03u"), g_TempDir, g_DirSequencer);
  1279. if (CreateDirectory (tempDir, NULL) == 0) {
  1280. error = GetLastError ();
  1281. if (error == ERROR_ALREADY_EXISTS) {
  1282. pDeleteAllFiles (tempDir);
  1283. }
  1284. ELSE_DEBUGMSG ((DBG_ERROR, "Cannot create directory %s", tempDir));
  1285. }
  1286. _stprintf (cmdLine, TEXT("expand /r \"%s\" \"%s\""), e.FullPath, tempDir);
  1287. ZeroMemory (&startupInfo, sizeof (STARTUPINFO));
  1288. startupInfo.cb = sizeof (STARTUPINFO);
  1289. if (CreateProcess (NULL, cmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &startupInfo, &processInfo)) {
  1290. WaitForSingleObject (processInfo.hProcess, INFINITE);
  1291. CloseHandle (processInfo.hProcess);
  1292. CloseHandle (processInfo.hThread);
  1293. if (!pHandleAllFiles (AppMode, Action, Section, Message, tempDir)) {
  1294. return FALSE;
  1295. }
  1296. pDeleteAllFiles (tempDir);
  1297. }
  1298. else {
  1299. DEBUGMSG ((DBG_ERROR, "Could not decompress:%s, Error:%ld", e.Name, GetLastError()));
  1300. }
  1301. RemoveDirectory (tempDir);
  1302. g_DirSequencer--;
  1303. }
  1304. else {
  1305. if (pExeFile (&e)) {
  1306. g_FileSequencer = 0;
  1307. g_DirSequencer++;
  1308. _stprintf (tempDir, TEXT("%s\\MIGDB%03u"), g_TempDir, g_DirSequencer);
  1309. if (CreateDirectory (tempDir, NULL) == 0) {
  1310. error = GetLastError ();
  1311. if (error == ERROR_ALREADY_EXISTS) {
  1312. pDeleteAllFiles (tempDir);
  1313. }
  1314. ELSE_DEBUGMSG ((DBG_ERROR, "Cannot create directory %s", tempDir));
  1315. }
  1316. exeModule = LoadLibraryEx (e.FullPath, NULL, LOAD_LIBRARY_AS_DATAFILE);
  1317. EnumResourceTypes (exeModule, EnumResTypeProc, (LONG)tempDir);
  1318. FreeLibrary (exeModule);
  1319. if (!pHandleAllFiles (AppMode, Action, Section, Message, tempDir)) {
  1320. return FALSE;
  1321. }
  1322. pDeleteAllFiles (tempDir);
  1323. RemoveDirectory (tempDir);
  1324. g_DirSequencer--;
  1325. }
  1326. if (AppMode) {
  1327. if (pSelected (e.Name)) {
  1328. if (!pHandleAppFile (&e, Action, Section, Message, SrcPath)) {
  1329. return FALSE;
  1330. }
  1331. }
  1332. }
  1333. else {
  1334. if (!pSelected (e.Name)) {
  1335. if (!pHandleSysFile (&e, Action, Section, Message, SrcPath)) {
  1336. return FALSE;
  1337. }
  1338. }
  1339. }
  1340. }
  1341. }
  1342. } while (EnumNextFileInTree (&e));
  1343. }
  1344. return TRUE;
  1345. }
  1346. BOOL
  1347. pHandleSection (
  1348. IN PCTSTR SectionName,
  1349. IN HINF ConfigHandle
  1350. )
  1351. {
  1352. PMIGDB_CONTEXT migDbContext = NULL;
  1353. INFCONTEXT context;
  1354. TCHAR action [MAX_TCHAR_PATH] = "";
  1355. TCHAR section [MAX_TCHAR_PATH] = "";
  1356. TCHAR message [MAX_TCHAR_PATH] = "";
  1357. TCHAR srcPath [MAX_TCHAR_PATH] = "";
  1358. TCHAR msgStr [MAX_TCHAR_PATH] = "";
  1359. TCHAR sectTmp [MAX_TCHAR_PATH] = "";
  1360. TCHAR renSect [MAX_TCHAR_PATH] = "";
  1361. TCHAR srcFile [MAX_TCHAR_PATH] = "";
  1362. TCHAR destFile[MAX_TCHAR_PATH] = "";
  1363. BOOL forced = FALSE;
  1364. INT field;
  1365. TCHAR excludePattern [MAX_TCHAR_PATH] = "";
  1366. BOOL appMode = FALSE;
  1367. TCHAR sectPatterns [MAX_TCHAR_PATH] = "";
  1368. DWORD offset;
  1369. _tprintf (TEXT("Processing section : %s ... "), SectionName);
  1370. if (!SetupFindFirstLine (ConfigHandle, SectionName, TEXT("action"), &context)) {
  1371. _tprintf (TEXT("\nCannot find Action= line in %s.\n"), SectionName);
  1372. return FALSE;
  1373. }
  1374. if (!SetupGetStringField (&context, 1, action, MAX_TCHAR_PATH, NULL)) {
  1375. _tprintf (TEXT("\nCannot read action name in %s.\n"), SectionName);
  1376. return FALSE;
  1377. }
  1378. if (!SetupFindFirstLine (ConfigHandle, SectionName, TEXT("section"), &context)) {
  1379. _tprintf (TEXT("\nCannot find Section= line in %s.\n"), SectionName);
  1380. return FALSE;
  1381. }
  1382. if (!SetupGetStringField (&context, 1, section, MAX_TCHAR_PATH, NULL)) {
  1383. _tprintf (TEXT("\nCannot read section name in %s.\n"), SectionName);
  1384. return FALSE;
  1385. }
  1386. if (!SetupFindFirstLine (ConfigHandle, SectionName, TEXT("sourcepath"), &context)) {
  1387. _tprintf (TEXT("\nCannot find SourcePath= line in %s.\n"), SectionName);
  1388. return FALSE;
  1389. }
  1390. if (!SetupGetStringField (&context, 1, srcPath, MAX_TCHAR_PATH, NULL)) {
  1391. _tprintf (TEXT("\nCannot read source path name in %s.\n"), SectionName);
  1392. return FALSE;
  1393. }
  1394. if (SetupFindFirstLine (ConfigHandle, SectionName, TEXT("message"), &context)) {
  1395. SetupGetStringField (&context, 1, message, MAX_TCHAR_PATH, NULL);
  1396. }
  1397. if (SetupFindFirstLine (ConfigHandle, SectionName, TEXT("RenameSection"), &context)) {
  1398. SetupGetStringField (&context, 1, renSect, MAX_TCHAR_PATH, NULL);
  1399. }
  1400. g_SectFiles.Buf = NULL;
  1401. g_SectFiles.Size = 0;
  1402. g_SectFiles.End = 0;
  1403. g_SectFiles.GrowSize = 0;
  1404. g_SectFiles.UserIndex = 0;
  1405. if (SetupFindFirstLine (ConfigHandle, SectionName, TEXT("ExcludeFiles"), &context)) {
  1406. field = 1;
  1407. while (SetupGetStringField (&context, field, excludePattern, MAX_TCHAR_PATH, NULL)) {
  1408. MultiSzAppend (&g_SectFiles, excludePattern);
  1409. field ++;
  1410. }
  1411. appMode = FALSE;
  1412. }
  1413. if (SetupFindFirstLine (ConfigHandle, SectionName, TEXT("SpecifiedFiles"), &context)) {
  1414. field = 1;
  1415. while (SetupGetStringField (&context, field, excludePattern, MAX_TCHAR_PATH, NULL)) {
  1416. MultiSzAppend (&g_SectFiles, excludePattern);
  1417. field ++;
  1418. }
  1419. appMode = TRUE;
  1420. }
  1421. // let's try to find if this section was already processed in migdb.inf
  1422. if (SetupFindFirstLine (g_MigDbInf, action, NULL, &context)) {
  1423. do {
  1424. if (SetupGetStringField (&context, 1, sectTmp, MAX_TCHAR_PATH, NULL) &&
  1425. (StringIMatch (section, sectTmp))
  1426. ) {
  1427. _tprintf (TEXT("\n Section already present in %s; please choose another name\n"));
  1428. return FALSE;
  1429. }
  1430. }
  1431. while (SetupFindNextLine (&context, &context));
  1432. }
  1433. if (SetupFindFirstLine (ConfigHandle, renSect, NULL, &context)) {
  1434. do {
  1435. if (SetupGetStringField (&context, 0, srcFile, MAX_TCHAR_PATH, NULL) &&
  1436. SetupGetStringField (&context, 1, destFile, MAX_TCHAR_PATH, NULL)
  1437. ) {
  1438. MemDbSetValueEx (MEMDB_CATEGORY_RENAME_DEST, destFile, NULL, NULL, 0, &offset);
  1439. MemDbSetValueEx (MEMDB_CATEGORY_RENAME_SRC, srcFile, NULL, NULL, offset, NULL);
  1440. }
  1441. } while (SetupFindNextLine (&context, &context));
  1442. }
  1443. _tprintf (TEXT("\n"));
  1444. migDbContext = (PMIGDB_CONTEXT) PoolMemGetMemory (g_MigDbPool, sizeof (MIGDB_CONTEXT));
  1445. if (migDbContext == NULL) {
  1446. DEBUGMSG ((DBG_ERROR, "Unable to create context for %s", action));
  1447. return FALSE;
  1448. }
  1449. ZeroMemory (migDbContext, sizeof (MIGDB_CONTEXT));
  1450. migDbContext->Next = g_ContextList;
  1451. g_ContextList = migDbContext;
  1452. // update ActionIndex with known value
  1453. migDbContext->ActionIndex = MigDb_GetActionIdx (action);
  1454. DEBUGMSG_IF(((migDbContext->ActionIndex == -1), DBG_ERROR, "Unable to identify action index for %s", action));
  1455. // update SectName field
  1456. migDbContext->SectName = PoolMemDuplicateString (g_MigDbPool, section);
  1457. if (!pHandleAllFiles (appMode, action, section, message, srcPath)) {
  1458. return FALSE;
  1459. }
  1460. FreeGrowBuffer (&g_SectFiles);
  1461. if (!forced) {
  1462. // now let's add the action section and the line within it
  1463. _stprintf (msgStr, TEXT("%s\\%s,%s"),
  1464. MEMDB_CATEGORY_ACTION,
  1465. section,
  1466. message);
  1467. MemDbSetValue (msgStr, 0);
  1468. pWriteMemdbSection (g_MigdbDest, MEMDB_CATEGORY_ACTION, action, FALSE);
  1469. }
  1470. pWriteMemdbSection (g_MigdbDest, MEMDB_CATEGORY_SECTFILES, section, TRUE);
  1471. pWriteMemdbSection (g_MigdbDest, MEMDB_CATEGORY_REQFILES, TEXT("Windows 9x Required Files"), TRUE);
  1472. MemDbDeleteTree (MEMDB_CATEGORY_SECTFILES);
  1473. MemDbDeleteTree (MEMDB_CATEGORY_ACTION);
  1474. MemDbDeleteTree (MEMDB_CATEGORY_RENAME_SRC);
  1475. MemDbDeleteTree (MEMDB_CATEGORY_RENAME_DEST);
  1476. MemDbDeleteTree (MEMDB_CATEGORY_REQFILES);
  1477. return TRUE;
  1478. }
  1479. BOOL
  1480. pWriteMemdbSection (
  1481. IN PCTSTR FileName,
  1482. IN PCTSTR MemDbCategory,
  1483. IN PCTSTR SectName,
  1484. IN BOOL WriteByValue
  1485. )
  1486. {
  1487. HANDLE fileHandle = INVALID_HANDLE_VALUE;
  1488. TCHAR line [MAX_TCHAR_PATH] = "";
  1489. DWORD dontCare;
  1490. MEMDB_ENUM e;
  1491. PCTSTR pattern;
  1492. fileHandle = CreateFile (FileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL);
  1493. if (fileHandle == INVALID_HANDLE_VALUE) {
  1494. _tprintf (TEXT("\nCannot open %s.\n"), FileName);
  1495. return FALSE;
  1496. }
  1497. SetFilePointer (fileHandle, 0, 0, FILE_END);
  1498. _stprintf (line, TEXT("[%s]\r\n"), SectName);
  1499. WriteFile (fileHandle, line, GetEndOfString (line) - line, &dontCare, NULL);
  1500. pattern = JoinPaths (MemDbCategory, TEXT("\\*"));
  1501. if (MemDbEnumFirstValue (&e, pattern, MEMDB_ALL_SUBLEVELS, MEMDB_ENDPOINTS_ONLY)) {
  1502. do {
  1503. if (!WriteByValue || !e.dwValue) {
  1504. _stprintf (line, TEXT("%s\r\n"), e.szName);
  1505. if (!WriteFile (fileHandle, line, GetEndOfString (line) - line, &dontCare, NULL)) {
  1506. DEBUGMSG ((DBG_ERROR, "Error while writing information."));
  1507. }
  1508. }
  1509. }
  1510. while (MemDbEnumNextValue (&e));
  1511. }
  1512. _stprintf (line, TEXT("\r\n\r\n"), SectName);
  1513. WriteFile (fileHandle, line, GetEndOfString (line) - line, &dontCare, NULL);
  1514. if (!CloseHandle (fileHandle)) {
  1515. DEBUGMSG ((DBG_ERROR, "Error while closing file %s.", FileName));
  1516. }
  1517. if (WriteByValue) {
  1518. fileHandle = CreateFile (g_MigdbDump, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL);
  1519. if (fileHandle == INVALID_HANDLE_VALUE) {
  1520. _tprintf (TEXT("\nCannot open %s.\n"), g_MigdbDump);
  1521. return FALSE;
  1522. }
  1523. SetFilePointer (fileHandle, 0, 0, FILE_END);
  1524. _stprintf (line, TEXT("\n[%s.obsolete]\r\n"), SectName);
  1525. WriteFile (fileHandle, line, GetEndOfString (line) - line, &dontCare, NULL);
  1526. if (MemDbEnumFirstValue (&e, pattern, MEMDB_ALL_SUBLEVELS, MEMDB_ENDPOINTS_ONLY)) {
  1527. do {
  1528. if (e.dwValue) {
  1529. _stprintf (line, TEXT("%s\r\n"), e.szName);
  1530. if (!WriteFile (fileHandle, line, GetEndOfString (line) - line, &dontCare, NULL)) {
  1531. DEBUGMSG ((DBG_ERROR, "Error while writing information."));
  1532. }
  1533. }
  1534. }
  1535. while (MemDbEnumNextValue (&e));
  1536. }
  1537. if (!CloseHandle (fileHandle)) {
  1538. DEBUGMSG ((DBG_ERROR, "Error while closing file %s.", FileName));
  1539. }
  1540. }
  1541. FreePathString (pattern);
  1542. return TRUE;
  1543. }
  1544. BOOL
  1545. pArrangeMigDbFile (
  1546. IN PCTSTR SrcFile,
  1547. IN PCTSTR DestFile
  1548. )
  1549. {
  1550. return CopyFile (SrcFile, DestFile, FALSE);
  1551. }
  1552. BOOL
  1553. pReadNtFilesEx (
  1554. IN PCSTR FileListName
  1555. )
  1556. {
  1557. PCSTR fileListName = NULL;
  1558. PCSTR fileListTmp = NULL;
  1559. HANDLE fileHandle = NULL;
  1560. HANDLE mapHandle = NULL;
  1561. PCSTR filePointer = NULL;
  1562. PCSTR filePtr = NULL;
  1563. DWORD offset;
  1564. DWORD version;
  1565. BOOL result = TRUE;
  1566. CHAR dirName [MEMDB_MAX];
  1567. __try {
  1568. //
  1569. // add to this list the dirs listed in [WinntDirectories] section of txtsetup.sif
  1570. //
  1571. if (FileListName != NULL) {
  1572. filePointer = MapFileIntoMemory (FileListName, &fileHandle, &mapHandle);
  1573. }
  1574. filePtr = filePointer;
  1575. if (filePointer == NULL) {
  1576. result = FALSE;
  1577. __leave;
  1578. }
  1579. version = *((PDWORD) filePointer);
  1580. filePointer += sizeof (DWORD);
  1581. __try {
  1582. if (version >= 1) {
  1583. while (*filePointer != 0) {
  1584. StringCopy (dirName, filePointer);
  1585. MemDbSetValueEx (
  1586. MEMDB_CATEGORY_NT_DIRS,
  1587. dirName,
  1588. NULL,
  1589. NULL,
  1590. 0,
  1591. &offset
  1592. );
  1593. filePointer = _mbsinc (GetEndOfString (filePointer));
  1594. MemDbSetValueEx (
  1595. MEMDB_CATEGORY_NT_FILES,
  1596. filePointer,
  1597. NULL,
  1598. NULL,
  1599. offset,
  1600. NULL
  1601. );
  1602. filePointer = _mbsinc( GetEndOfString (filePointer));
  1603. }
  1604. if (version >= 2) {
  1605. filePointer ++;
  1606. while (*filePointer != 0) {
  1607. MemDbSetValueEx (
  1608. MEMDB_CATEGORY_NT_FILES_EXCEPT,
  1609. filePointer,
  1610. NULL,
  1611. NULL,
  1612. 0,
  1613. NULL
  1614. );
  1615. filePointer = _mbsinc (GetEndOfString (filePointer));
  1616. }
  1617. }
  1618. }
  1619. }
  1620. __except (EXCEPTION_EXECUTE_HANDLER){
  1621. LOG ((LOG_ERROR, "Access violation while reading NT file list."));
  1622. }
  1623. }
  1624. __finally {
  1625. UnmapFile ((PVOID)filePtr, fileHandle, mapHandle);
  1626. if (fileListTmp) {
  1627. DeleteFile (fileListTmp);
  1628. FreePathString (fileListTmp);
  1629. fileListTmp = NULL;
  1630. }
  1631. }
  1632. return result;
  1633. }