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.

1386 lines
42 KiB

  1. #include "pch.h"
  2. typedef BOOL (WINAPI INITROUTINE_PROTOTYPE)(HINSTANCE, DWORD, LPVOID);
  3. INITROUTINE_PROTOTYPE MigUtil_Entry;
  4. INITROUTINE_PROTOTYPE MemDb_Entry;
  5. INITROUTINE_PROTOTYPE FileEnum_Entry;
  6. #define DBG_MODULES "MODULES"
  7. #define FLAG_BAD_FUNCTION 1
  8. #define FLAG_BAD_INDEX 2
  9. HINSTANCE g_hInst;
  10. HANDLE g_hHeap;
  11. BOOL g_CancelFlag = FALSE;
  12. DWORD g_DirSequencer = 0;
  13. DWORD g_FileSequencer = 0;
  14. #ifdef DEBUG
  15. extern BOOL g_DoLog;
  16. #endif
  17. extern BOOL *g_CancelFlagPtr = &g_CancelFlag;
  18. extern POOLHANDLE g_PathsPool;
  19. BOOL
  20. WriteE95Only (
  21. VOID
  22. );
  23. BOOL
  24. ReadNtFilesEx (
  25. IN PCSTR FileListName, //optional, if null default is opened
  26. IN BOOL ConvertPath
  27. );
  28. BOOL
  29. pHandleFile (
  30. IN PCTSTR FileName,
  31. IN BOOL Win95Side
  32. );
  33. BOOL
  34. pHandleAllFiles (
  35. IN PCTSTR SrcPath,
  36. IN BOOL Win95Side
  37. );
  38. BOOL
  39. pDeleteAllFiles (
  40. IN PCTSTR DirPath
  41. );
  42. BOOL
  43. pProcessExportModule (
  44. IN PCTSTR ModuleName,
  45. IN BOOL Win95Side
  46. );
  47. BOOL
  48. pLoadKnownGoodExports (
  49. IN HINF ConfigHandle
  50. );
  51. BOOL
  52. pLoadIgnoredFiles (
  53. IN HINF ConfigHandle
  54. );
  55. BOOL
  56. pLocalLoadNTFilesData (
  57. IN PCTSTR FilePath,
  58. IN HINF ConfigHandle
  59. );
  60. BOOL
  61. pCompressedFile (
  62. IN PTREE_ENUM e
  63. );
  64. BOOL
  65. pWorkerFn (
  66. IN HINF ConfigHandle
  67. );
  68. BOOL
  69. pHandleSection (
  70. IN PCTSTR SectionName,
  71. IN HINF ConfigHandle
  72. );
  73. VOID
  74. pInitProgBarVars (
  75. VOID
  76. );
  77. VOID
  78. pUsage (
  79. VOID
  80. )
  81. {
  82. _tprintf (TEXT ("\nCommand line syntax:\n\n"
  83. "exports [/B:BaseDir] [/T:TempDir] [/F[:SectionName]]\n\n"
  84. "/B Specifies the base directory where all exports files are\n"
  85. " located. (e95only.dat, exports.cfg)\n"
  86. "/T Specifies the temporary directory used for unpacking\n"
  87. " cabinet files\n"
  88. "/F Forces rescanning a particular section or all sections\n"
  89. "/I Specifies path to NTFILES (default %NTTREE%)\n"));
  90. }
  91. PTSTR g_ConfigFile = NULL;
  92. PTSTR g_TempDir = NULL;
  93. PTSTR g_BaseDir = NULL;
  94. PTSTR g_ExportDest = NULL;
  95. PTSTR g_TxtSetupPath = NULL;
  96. PTSTR g_RescanSect = NULL;
  97. BOOL g_RescanFlag = FALSE;
  98. extern HINF g_MigDbInf;
  99. GROWBUFFER g_SectFiles = GROWBUF_INIT;
  100. #define MEMDB_CATEGORY_WNT_EXPORTS TEXT("WNtExports")
  101. #define MEMDB_CATEGORY_W95_SECTIONS TEXT("W95Sections")
  102. void
  103. __cdecl
  104. main (
  105. int argc,
  106. CHAR *argv[]
  107. )
  108. {
  109. INT argidx, index;
  110. INT nextArg = 0;
  111. HINF configHandle = INVALID_HANDLE_VALUE;
  112. TCHAR fileName [MAX_TCHAR_PATH] = "";
  113. PTSTR dontCare;
  114. #ifdef DEBUG
  115. g_DoLog = TRUE;
  116. #endif
  117. g_hInst = GetModuleHandle (NULL);
  118. g_hHeap = GetProcessHeap();
  119. if (!MigUtil_Entry (g_hInst, DLL_PROCESS_ATTACH, NULL)) {
  120. _tprintf (TEXT("MigUtil failed initializing\n"));
  121. exit (1);
  122. }
  123. if (!MemDb_Entry (g_hInst, DLL_PROCESS_ATTACH, NULL)) {
  124. _tprintf (TEXT("MemDb failed initializing\n"));
  125. exit(1);
  126. }
  127. for (argidx = 1; argidx < argc; argidx++) {
  128. if ((argv[argidx][0] != '-') &&
  129. (argv[argidx][0] != '/')
  130. ) {
  131. if (nextArg == 0) {
  132. pUsage ();
  133. exit (1);
  134. }
  135. switch (nextArg) {
  136. case 1:
  137. index = 0;
  138. goto label1;
  139. case 2:
  140. index = 0;
  141. goto label2;
  142. case 3:
  143. index = 0;
  144. goto label3;
  145. case 4:
  146. index = 0;
  147. goto label4;
  148. }
  149. }
  150. switch (toupper(argv[argidx][1])) {
  151. case 'B':
  152. if (argv[argidx][2] == 0) {
  153. nextArg = 1;
  154. }
  155. else {
  156. if (argv[argidx][2] != ':') {
  157. index = 2;
  158. }
  159. else {
  160. index = 3;
  161. }
  162. label1:
  163. nextArg = 0;
  164. g_BaseDir = AllocPathString (MAX_TCHAR_PATH);
  165. #ifdef UNICODE
  166. MultiByteToWideChar(CP_ACP, 0, argv[argidx]+index, -1, g_BaseDir, MAX_TCHAR_PATH);
  167. #else
  168. _tcsncpy (g_BaseDir, argv[argidx]+index, MAX_TCHAR_PATH);
  169. #endif
  170. }
  171. break;
  172. case 'T':
  173. if (argv[argidx][2] == 0) {
  174. nextArg = 2;
  175. }
  176. else {
  177. if (argv[argidx][2] != ':') {
  178. index = 2;
  179. }
  180. else {
  181. index = 3;
  182. }
  183. label2:
  184. nextArg = 0;
  185. g_TempDir = AllocPathString (MAX_TCHAR_PATH);
  186. #ifdef UNICODE
  187. MultiByteToWideChar(CP_ACP, 0, argv[argidx]+index, -1, g_TempDir, MAX_TCHAR_PATH);
  188. #else
  189. _tcsncpy (g_TempDir, argv[argidx]+index, MAX_TCHAR_PATH);
  190. #endif
  191. }
  192. break;
  193. case 'I':
  194. if (argv[argidx][2] == 0) {
  195. nextArg = 3;
  196. }
  197. else {
  198. if (argv[argidx][2] != ':') {
  199. index = 2;
  200. }
  201. else {
  202. index = 3;
  203. }
  204. label3:
  205. nextArg = 0;
  206. g_TxtSetupPath = AllocPathString (MAX_TCHAR_PATH);
  207. #ifdef UNICODE
  208. MultiByteToWideChar(CP_ACP, 0, argv[argidx]+index, -1, g_TxtSetupPath, MAX_TCHAR_PATH);
  209. #else
  210. _tcsncpy (g_TxtSetupPath, argv[argidx]+index, MAX_TCHAR_PATH);
  211. #endif
  212. }
  213. break;
  214. case 'F':
  215. g_RescanFlag = TRUE;
  216. if (argv[argidx][2] == 0) {
  217. nextArg = 4;
  218. }
  219. else {
  220. if (argv[argidx][2] != ':') {
  221. index = 2;
  222. }
  223. else {
  224. index = 3;
  225. }
  226. label4:
  227. nextArg = 0;
  228. g_RescanSect = AllocPathString (MAX_TCHAR_PATH);
  229. #ifdef UNICODE
  230. MultiByteToWideChar(CP_ACP, 0, argv[argidx]+index, -1, g_RescanSect, MAX_TCHAR_PATH);
  231. #else
  232. _tcsncpy (g_RescanSect, argv[argidx]+index, MAX_TCHAR_PATH);
  233. #endif
  234. }
  235. break;
  236. default:
  237. pUsage ();
  238. exit (1);
  239. }
  240. }
  241. if (g_BaseDir == NULL) {
  242. g_BaseDir = AllocPathString (MAX_TCHAR_PATH);
  243. _tcsncpy (g_BaseDir, TEXT(".\\"), MAX_TCHAR_PATH);
  244. }
  245. if (g_TempDir == NULL) {
  246. g_TempDir = AllocPathString (MAX_TCHAR_PATH);
  247. if (GetEnvironmentVariable (TEXT("TEMP"), g_TempDir, MAX_TCHAR_PATH) == 0) {
  248. _tcsncpy (g_TempDir, TEXT("C:\\TEMP"), MAX_TCHAR_PATH);
  249. }
  250. }
  251. if (g_TxtSetupPath == NULL) {
  252. g_TxtSetupPath = AllocPathString (MAX_TCHAR_PATH);
  253. if ((GetEnvironmentVariable (TEXT("_NTTREE" ), g_TxtSetupPath, MAX_TCHAR_PATH) == 0) &&
  254. (GetEnvironmentVariable (TEXT("_NT386TREE"), g_TxtSetupPath, MAX_TCHAR_PATH) == 0)
  255. ) {
  256. _tcsncpy (g_TxtSetupPath, TEXT("."), MAX_TCHAR_PATH);
  257. }
  258. }
  259. g_ConfigFile = JoinPaths (g_BaseDir, TEXT("exports.cfg"));
  260. g_ExportDest = JoinPaths (g_BaseDir, TEXT("e95only.dat"));
  261. if (!DoesFileExist (g_ConfigFile)) {
  262. _tprintf (TEXT("\nConfiguration file not found. Exiting.\n"));
  263. exit (1);
  264. }
  265. if (SearchPath (NULL, TEXT("extract.exe"), NULL, 0, NULL, NULL) == 0) {
  266. _tprintf (TEXT("\nCannot find extract.exe. Exiting.\n"));
  267. exit (1);
  268. }
  269. configHandle = SetupOpenInfFile (g_ConfigFile, NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
  270. if (configHandle == INVALID_HANDLE_VALUE) {
  271. SearchPath (NULL, g_ConfigFile, NULL, MAX_TCHAR_PATH, fileName, &dontCare);
  272. configHandle = SetupOpenInfFile (fileName, NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
  273. if (configHandle == INVALID_HANDLE_VALUE) {
  274. _tprintf (TEXT("\nCannot open configuration file %s. Exiting.\n"), g_ConfigFile);
  275. exit (1);
  276. }
  277. }
  278. if (!pLoadKnownGoodExports (configHandle)) {
  279. _tprintf (TEXT("\nCannot load known good exports. Exiting.\n"));
  280. exit (1);
  281. }
  282. if (!pLocalLoadNTFilesData (g_TxtSetupPath, configHandle)) {
  283. _tprintf (TEXT("\nCannot load NT file list. Exiting.\n"));
  284. exit (1);
  285. }
  286. if (!pLoadIgnoredFiles (configHandle)) {
  287. _tprintf (TEXT("\nCannot load ignored files. Exiting.\n"));
  288. exit (1);
  289. }
  290. pWorkerFn (configHandle);
  291. WriteE95Only ();
  292. FreePathString (g_ConfigFile);
  293. FreePathString (g_TempDir);
  294. FreePathString (g_BaseDir);
  295. FreePathString (g_ExportDest);
  296. if (!MemDb_Entry (g_hInst, DLL_PROCESS_DETACH, NULL)) {
  297. _tprintf (TEXT("MemDb failed initializing\n"));
  298. exit(1);
  299. }
  300. if (!MigUtil_Entry (g_hInst, DLL_PROCESS_DETACH, NULL)) {
  301. _tprintf (TEXT("MigUtil failed initializing\n"));
  302. exit (1);
  303. }
  304. }
  305. BOOL
  306. WriteE95Only (
  307. VOID
  308. )
  309. {
  310. return MemDbExportA (MEMDB_CATEGORY_WIN9X_APIS, g_ExportDest, TRUE);
  311. }
  312. BOOL
  313. pLoadKnownGoodExports (
  314. IN HINF ConfigHandle
  315. )
  316. {
  317. INFCONTEXT context;
  318. TCHAR goodExport [MAX_TCHAR_PATH];
  319. INT goodExportIdx;
  320. if (SetupFindFirstLine (ConfigHandle, TEXT("KnownGood"), NULL, &context)) {
  321. do {
  322. if (!SetupGetStringField (&context, 0, goodExport, MAX_TCHAR_PATH, NULL)) {
  323. _tprintf (TEXT("\nBad section [KnownGood] in %s. Exiting.\n"), g_ConfigFile);
  324. return FALSE;
  325. }
  326. if (!SetupGetIntField (&context, 1, &goodExportIdx)) {
  327. _tprintf (TEXT("\nBad section [KnownGood] in %s. Exiting.\n"), g_ConfigFile);
  328. return FALSE;
  329. }
  330. MemDbSetValueEx (MEMDB_CATEGORY_WNT_EXPORTS, goodExport, NULL, NULL, goodExportIdx, NULL);
  331. }
  332. while (SetupFindNextLine (&context, &context));
  333. }
  334. return TRUE;
  335. }
  336. BOOL
  337. pLoadIgnoredFiles (
  338. IN HINF ConfigHandle
  339. )
  340. {
  341. INFCONTEXT context;
  342. TCHAR ignoredFile [MAX_TCHAR_PATH];
  343. TCHAR key [MEMDB_MAX];
  344. if (SetupFindFirstLine (ConfigHandle, TEXT("IgnoredFiles"), NULL, &context)) {
  345. do {
  346. if (!SetupGetStringField (&context, 0, ignoredFile, MAX_TCHAR_PATH, NULL)) {
  347. _tprintf (TEXT("\nBad section [IgnoredFiles] in %s. Exiting.\n"), g_ConfigFile);
  348. return FALSE;
  349. }
  350. MemDbBuildKey (key, MEMDB_CATEGORY_NT_FILES, ignoredFile, NULL, NULL);
  351. MemDbDeleteTree (key);
  352. }
  353. while (SetupFindNextLine (&context, &context));
  354. }
  355. return TRUE;
  356. }
  357. BOOL
  358. pLocalLoadNTFilesData (
  359. IN PCTSTR FilePath,
  360. IN HINF ConfigHandle
  361. )
  362. {
  363. PCSTR fileListName = NULL;
  364. PCSTR fileListNameTmp = NULL;
  365. //first let's read FILELIST.DAT
  366. fileListName = JoinPaths (g_TxtSetupPath, S_FILELIST_UNCOMPRESSED);
  367. if (!DoesFileExist (fileListName)) {
  368. fileListName = JoinPaths (g_TxtSetupPath, S_FILELIST_COMPRESSED);
  369. if (!DoesFileExist (fileListName)) {
  370. _tprintf (TEXT("Could not find FILELIST.DAT."));
  371. FreePathString (fileListName);
  372. return FALSE;
  373. }
  374. fileListNameTmp = JoinPaths (g_TempDir, S_FILELIST_UNCOMPRESSED);
  375. if (SetupDecompressOrCopyFile (fileListName, fileListNameTmp, 0) != NO_ERROR) {
  376. _tprintf (TEXT("Could not decompress FILELIST.DAT."));
  377. FreePathString (fileListName);
  378. FreePathString (fileListNameTmp);
  379. return FALSE;
  380. }
  381. FreePathString (fileListNameTmp);
  382. }
  383. if (!ReadNtFilesEx (fileListNameTmp?fileListNameTmp:fileListName, FALSE)) {
  384. _tprintf (TEXT("Could not read FILELIST.DAT."));
  385. if (fileListName) {
  386. FreePathString (fileListName);
  387. }
  388. if (fileListNameTmp) {
  389. DeleteFile (fileListNameTmp);
  390. FreePathString (fileListNameTmp);
  391. }
  392. return FALSE;
  393. }
  394. if (fileListName) {
  395. FreePathString (fileListName);
  396. }
  397. if (fileListNameTmp) {
  398. DeleteFile (fileListNameTmp);
  399. FreePathString (fileListNameTmp);
  400. }
  401. _tprintf (TEXT("Processing NT files ... \n"));
  402. if (!pHandleAllFiles (FilePath, FALSE)) {
  403. return FALSE;
  404. }
  405. return TRUE;
  406. }
  407. UINT
  408. pCabinetCallback (
  409. IN PVOID Context, //context used by the callback routine
  410. IN UINT Notification, //notification sent to callback routine
  411. IN UINT Param1, //additional notification information
  412. IN UINT Param2 //additional notification information );
  413. )
  414. {
  415. PCTSTR tempDir = Context;
  416. PCTSTR fileName = (PCTSTR)Param2 ;
  417. PFILE_IN_CABINET_INFO fileInfo = (PFILE_IN_CABINET_INFO)Param1;
  418. switch (Notification) {
  419. case SPFILENOTIFY_FILEEXTRACTED :
  420. case SPFILENOTIFY_NEEDNEWCABINET :
  421. return NO_ERROR;
  422. case SPFILENOTIFY_FILEINCABINET :
  423. _stprintf (fileInfo->FullTargetName, TEXT("%s\\%s"), tempDir, fileInfo->NameInCabinet);
  424. return FILEOP_DOIT;
  425. }
  426. return NO_ERROR;
  427. }
  428. BOOL
  429. pWorkerFn (
  430. HINF ConfigHandle
  431. )
  432. {
  433. INFCONTEXT context;
  434. TCHAR sectName [MAX_TCHAR_PATH];
  435. if (SetupFindFirstLine (ConfigHandle, TEXT("sections"), NULL, &context)) {
  436. do {
  437. if (!SetupGetStringField (&context, 1, sectName, MAX_TCHAR_PATH, NULL)) {
  438. _tprintf (TEXT("\nBad section [SECTIONS] in %s. Exiting.\n"), g_ConfigFile);
  439. return FALSE;
  440. }
  441. if (!pHandleSection (sectName, ConfigHandle)) {
  442. return FALSE;
  443. }
  444. }
  445. while (SetupFindNextLine (&context, &context));
  446. }
  447. return TRUE;
  448. }
  449. BOOL
  450. pDeleteAllFiles (
  451. IN PCTSTR DirPath
  452. )
  453. {
  454. TREE_ENUM e;
  455. TCHAR tempFile [MAX_TCHAR_PATH] = "";
  456. BOOL dirsFirst = FALSE;
  457. if (EnumFirstFileInTree (&e, DirPath, TEXT("*"), dirsFirst)) {
  458. do {
  459. if (e.Directory) {
  460. DEBUGMSG((DBG_ERROR, "Unexpected directory in temporary area."));
  461. return FALSE;
  462. }
  463. _stprintf (tempFile, TEXT("%s\\%s"), DirPath, e.Name);
  464. if (!DeleteFile (tempFile)) {
  465. return FALSE;
  466. }
  467. } while (EnumNextFileInTree (&e));
  468. }
  469. return TRUE;
  470. }
  471. BOOL
  472. pSelected (
  473. IN PCTSTR FileName
  474. )
  475. {
  476. TCHAR key[MEMDB_MAX];
  477. DWORD dontCare;
  478. MemDbBuildKey (key, MEMDB_CATEGORY_NT_FILES, FileName, NULL, NULL);
  479. return MemDbGetValue (key, &dontCare);
  480. }
  481. BOOL
  482. pCabinetFile (
  483. IN PCTSTR FileName
  484. )
  485. {
  486. PCTSTR extPtr;
  487. extPtr = GetFileExtensionFromPath (FileName);
  488. if ((extPtr != NULL) &&
  489. (_tcsicmp (extPtr, TEXT("CAB")) == 0)
  490. ) {
  491. return TRUE;
  492. }
  493. return FALSE;
  494. }
  495. BOOL
  496. pHandleFile (
  497. IN PCTSTR FileName,
  498. IN BOOL Win95Side
  499. )
  500. {
  501. pProcessExportModule (FileName, Win95Side);
  502. return TRUE;
  503. }
  504. BOOL
  505. pCompressedFile (
  506. IN PTREE_ENUM e
  507. )
  508. {
  509. PCTSTR extPtr;
  510. extPtr = GetFileExtensionFromPath (e->FullPath);
  511. if (extPtr == NULL) {
  512. return FALSE;
  513. }
  514. if (_tcslen (extPtr) != 3) {
  515. return FALSE;
  516. }
  517. return (extPtr [2] == TEXT('_'));
  518. }
  519. BOOL
  520. pExeFile (
  521. IN PTREE_ENUM e
  522. )
  523. {
  524. PCTSTR extPtr;
  525. extPtr = GetFileExtensionFromPath (e->FullPath);
  526. if ((extPtr != NULL) &&
  527. (StringIMatch (extPtr, TEXT("EXE")))
  528. ) {
  529. return TRUE;
  530. }
  531. return FALSE;
  532. }
  533. BOOL
  534. pCopyAndHandleCabResource (
  535. IN PVOID Source,
  536. IN DWORD Size,
  537. IN PCTSTR DirName
  538. )
  539. {
  540. TCHAR cabDir [MAX_TCHAR_PATH] = "";
  541. HANDLE hFile;
  542. DWORD dontCare;
  543. if (Size < 4) {
  544. return TRUE;
  545. }
  546. if (*((PDWORD)Source) != 0x4643534D) {
  547. return TRUE;
  548. }
  549. g_FileSequencer ++;
  550. _stprintf (cabDir, TEXT("%s\\MIGDB%03u.CAB"), DirName, g_FileSequencer);
  551. hFile = CreateFile (cabDir, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  552. if (hFile == INVALID_HANDLE_VALUE) {
  553. DEBUGMSG ((DBG_ERROR, "Cannot create file %s", cabDir));
  554. return FALSE;
  555. }
  556. if (!WriteFile (hFile, Source, Size, &dontCare, NULL)) {
  557. DEBUGMSG ((DBG_ERROR, "Cannot write to file %s", cabDir));
  558. return FALSE;
  559. }
  560. CloseHandle (hFile);
  561. return TRUE;
  562. }
  563. BOOL CALLBACK
  564. EnumResNameProc (
  565. IN HANDLE hModule, // module handle
  566. IN LPCTSTR lpszType, // pointer to resource type
  567. IN LPTSTR lpszName, // pointer to resource name
  568. IN LONG lParam // application-defined parameter
  569. )
  570. {
  571. HRSRC hResource;
  572. DWORD size;
  573. HGLOBAL hGlobal;
  574. PVOID srcBytes;
  575. hResource = FindResource (hModule, lpszName, lpszType);
  576. if (hResource) {
  577. size = SizeofResource (hModule, hResource);
  578. if (size) {
  579. hGlobal = LoadResource (hModule, hResource);
  580. if (hGlobal) {
  581. srcBytes = LockResource (hGlobal);
  582. if (srcBytes) {
  583. pCopyAndHandleCabResource (srcBytes, size, (PCTSTR)lParam);
  584. }
  585. }
  586. }
  587. }
  588. return TRUE;
  589. }
  590. BOOL CALLBACK
  591. EnumResTypeProc (
  592. IN HANDLE hModule, // resource-module handle
  593. IN LPTSTR lpszType, // pointer to resource type
  594. IN LONG lParam // application-defined parameter
  595. )
  596. {
  597. if ((lpszType != RT_ACCELERATOR ) &&
  598. (lpszType != RT_ANICURSOR ) &&
  599. (lpszType != RT_ANIICON ) &&
  600. (lpszType != RT_BITMAP ) &&
  601. (lpszType != RT_CURSOR ) &&
  602. (lpszType != RT_DIALOG ) &&
  603. (lpszType != RT_FONT ) &&
  604. (lpszType != RT_FONTDIR ) &&
  605. (lpszType != RT_GROUP_CURSOR ) &&
  606. (lpszType != RT_GROUP_ICON ) &&
  607. (lpszType != RT_HTML ) &&
  608. (lpszType != RT_ICON ) &&
  609. (lpszType != RT_MENU ) &&
  610. (lpszType != RT_MESSAGETABLE ) &&
  611. (lpszType != RT_PLUGPLAY ) &&
  612. (lpszType != RT_STRING ) &&
  613. (lpszType != RT_VERSION ) &&
  614. (lpszType != RT_VXD ) &&
  615. (lpszType != RT_HTML )
  616. ) {
  617. // we found an unknown type. Let's enumerate all resources of this type
  618. if (EnumResourceNames (hModule, lpszType, EnumResNameProc, lParam) == 0) {
  619. DEBUGMSG ((DBG_ERROR, "Error enumerating names:%ld", GetLastError ()));
  620. }
  621. }
  622. return TRUE;
  623. }
  624. BOOL
  625. pHandleAllFiles (
  626. IN PCTSTR SrcPath,
  627. IN BOOL Win95Side
  628. )
  629. {
  630. TCHAR tempDir [MAX_TCHAR_PATH] = "";
  631. TCHAR cmdLine [MAX_TCHAR_PATH] = "";
  632. TREE_ENUM e;
  633. DWORD error;
  634. HMODULE exeModule;
  635. PROCESS_INFORMATION processInfo;
  636. STARTUPINFO startupInfo;
  637. if (EnumFirstFileInTree (&e, SrcPath, TEXT("*"), FALSE)) {
  638. do {
  639. if (!e.Directory) {
  640. if (pCabinetFile (e.Name)) {
  641. // cabinet file
  642. g_DirSequencer++;
  643. _stprintf (tempDir, TEXT("%s\\MIGDB%03u"), g_TempDir, g_DirSequencer);
  644. if (CreateDirectory (tempDir, NULL) == 0) {
  645. error = GetLastError ();
  646. if (error == ERROR_ALREADY_EXISTS) {
  647. pDeleteAllFiles (tempDir);
  648. }
  649. ELSE_DEBUGMSG ((DBG_ERROR, "Cannot create directory %s", tempDir));
  650. }
  651. _tprintf (TEXT(" Extracting cabinet file ... %s"), e.Name);
  652. // we need to expand the cabinet file
  653. SetLastError (0);
  654. if (!SetupIterateCabinet (e.FullPath, 0, pCabinetCallback, tempDir)) {
  655. _tprintf (TEXT("...error %ld\n"), GetLastError());
  656. DEBUGMSG((DBG_ERROR, "Could not iterate cabinet file:%s\nError:%ld", e.FullPath, GetLastError ()));
  657. }
  658. else {
  659. _tprintf (TEXT("...done\n"));
  660. }
  661. if (!pHandleAllFiles (tempDir, Win95Side)) {
  662. return FALSE;
  663. }
  664. pDeleteAllFiles (tempDir);
  665. RemoveDirectory (tempDir);
  666. g_DirSequencer--;
  667. }
  668. else if (pCompressedFile (&e)) {
  669. // compressed file
  670. g_DirSequencer++;
  671. _stprintf (tempDir, TEXT("%s\\MIGDB%03u"), g_TempDir, g_DirSequencer);
  672. if (CreateDirectory (tempDir, NULL) == 0) {
  673. error = GetLastError ();
  674. if (error == ERROR_ALREADY_EXISTS) {
  675. pDeleteAllFiles (tempDir);
  676. }
  677. ELSE_DEBUGMSG ((DBG_ERROR, "Cannot create directory %s", tempDir));
  678. }
  679. _stprintf (cmdLine, TEXT("expand /r %s %s"), e.FullPath, tempDir);
  680. ZeroMemory (&startupInfo, sizeof (STARTUPINFO));
  681. startupInfo.cb = sizeof (STARTUPINFO);
  682. if (CreateProcess (NULL, cmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &startupInfo, &processInfo)) {
  683. WaitForSingleObject (processInfo.hProcess, INFINITE);
  684. CloseHandle (processInfo.hProcess);
  685. CloseHandle (processInfo.hThread);
  686. if (!pHandleAllFiles (tempDir, Win95Side)) {
  687. return FALSE;
  688. }
  689. pDeleteAllFiles (tempDir);
  690. }
  691. else {
  692. DEBUGMSG ((DBG_ERROR, "Could not decompress:%s, Error:%ld", e.Name, GetLastError()));
  693. }
  694. RemoveDirectory (tempDir);
  695. g_DirSequencer--;
  696. }
  697. else {
  698. if (pExeFile (&e)) {
  699. g_FileSequencer = 0;
  700. g_DirSequencer++;
  701. _stprintf (tempDir, TEXT("%s\\MIGDB%03u"), g_TempDir, g_DirSequencer);
  702. if (CreateDirectory (tempDir, NULL) == 0) {
  703. error = GetLastError ();
  704. if (error == ERROR_ALREADY_EXISTS) {
  705. pDeleteAllFiles (tempDir);
  706. }
  707. ELSE_DEBUGMSG ((DBG_ERROR, "Cannot create directory %s", tempDir));
  708. }
  709. exeModule = LoadLibraryEx (e.FullPath, NULL, LOAD_LIBRARY_AS_DATAFILE);
  710. EnumResourceTypes (exeModule, EnumResTypeProc, (LONG)tempDir);
  711. FreeLibrary (exeModule);
  712. if (!pHandleAllFiles (tempDir, Win95Side)) {
  713. return FALSE;
  714. }
  715. pDeleteAllFiles (tempDir);
  716. RemoveDirectory (tempDir);
  717. g_DirSequencer--;
  718. }
  719. if (pSelected (e.Name)) {
  720. if (!pHandleFile (e.FullPath, Win95Side)) {
  721. return FALSE;
  722. }
  723. }
  724. }
  725. } else {
  726. if (!Win95Side) {
  727. if ((StringIMatch (e.SubPath, TEXT("Win9xMig"))) ||
  728. (StringIMatch (e.SubPath, TEXT("\\Win9xMig"))) ||
  729. (StringIMatch (e.SubPath, TEXT("Winnt32"))) ||
  730. (StringIMatch (e.SubPath, TEXT("\\Winnt32"))) ||
  731. (StringIMatch (e.SubPath, TEXT("System32"))) ||
  732. (StringIMatch (e.SubPath, TEXT("\\System32")))
  733. ) {
  734. AbortEnumFileInTree (&e);
  735. }
  736. }
  737. }
  738. } while (EnumNextFileInTree (&e));
  739. }
  740. return TRUE;
  741. }
  742. BOOL
  743. pHandleSection (
  744. IN PCTSTR SectionName,
  745. IN HINF ConfigHandle
  746. )
  747. {
  748. INFCONTEXT context;
  749. TCHAR srcPath [MAX_TCHAR_PATH] = "";
  750. TCHAR key [MEMDB_MAX] = "";
  751. BOOL forced = FALSE;
  752. INT field;
  753. TCHAR includePattern [MAX_TCHAR_PATH] = "";
  754. DWORD dontCare;
  755. _tprintf (TEXT("Processing section : %s ... "), SectionName);
  756. if (!SetupFindFirstLine (ConfigHandle, SectionName, TEXT("sourcepath"), &context)) {
  757. _tprintf (TEXT("\nCannot find SourcePath= line in %s.\n"), SectionName);
  758. return FALSE;
  759. }
  760. if (!SetupGetStringField (&context, 1, srcPath, MAX_TCHAR_PATH, NULL)) {
  761. _tprintf (TEXT("\nCannot read source path name in %s.\n"), SectionName);
  762. return FALSE;
  763. }
  764. g_SectFiles.Buf = NULL;
  765. g_SectFiles.Size = 0;
  766. g_SectFiles.End = 0;
  767. g_SectFiles.GrowSize = 0;
  768. g_SectFiles.UserIndex = 0;
  769. if (SetupFindFirstLine (ConfigHandle, SectionName, TEXT("IncludeFiles"), &context)) {
  770. field = 1;
  771. while (SetupGetStringField (&context, field, includePattern, MAX_TCHAR_PATH, NULL)) {
  772. MultiSzAppend (&g_SectFiles, includePattern);
  773. field ++;
  774. }
  775. }
  776. // let's try to find if this section was already processed in migdb.inx
  777. MemDbBuildKey (key, MEMDB_CATEGORY_W95_SECTIONS, SectionName, NULL, NULL);
  778. if (MemDbGetValue (key, &dontCare)) {
  779. FreeGrowBuffer (&g_SectFiles);
  780. _tprintf (TEXT("skipped\n"));
  781. return TRUE;
  782. }
  783. _tprintf (TEXT("\n"));
  784. MemDbSetValue (key, 0);
  785. if (!pHandleAllFiles (srcPath, TRUE)) {
  786. FreeGrowBuffer (&g_SectFiles);
  787. return FALSE;
  788. }
  789. FreeGrowBuffer (&g_SectFiles);
  790. return TRUE;
  791. }
  792. //from here we are dealing with 16 bit and 32 bit modules decompiling code
  793. //since we are reading from a file we need that sizeof to give us the accurate result
  794. #pragma pack(push,1)
  795. typedef struct _NE_HEADER {
  796. WORD Magic;
  797. BYTE MajorLinkerVersion;
  798. BYTE MinorLinkerVersion;
  799. WORD EntryTableOff;
  800. WORD EntryTableLen;
  801. ULONG Reserved;
  802. WORD Flags;
  803. WORD NumberOfDataSeg;
  804. WORD SizeOfHeap;
  805. WORD SizeOfStack;
  806. ULONG CS_IP;
  807. ULONG SS_SP;
  808. WORD NumEntriesSegTable;
  809. WORD NumEntriesModuleTable;
  810. WORD NonResNameTableSize;
  811. WORD SegTableOffset;
  812. WORD ResTableOffset;
  813. WORD ResNameTableOffset;
  814. WORD ModuleTableOffset;
  815. WORD ImportedTableOffset;
  816. ULONG NonResNameTableOffset;
  817. WORD NumberOfMovableEntryPoints;
  818. WORD ShiftCount;
  819. WORD NumberOfResourceSegments;
  820. BYTE TargetOS;
  821. BYTE AdditionalInfo;
  822. WORD FastLoadOffset;
  823. WORD FastLoadSize;
  824. WORD Reserved1;
  825. WORD WinVersionExpected;
  826. } NE_HEADER, *PNE_HEADER;
  827. typedef struct _NE_SEGMENT_ENTRY {
  828. WORD SegmentOffset;
  829. WORD SegmentLen;
  830. WORD SegmentFlags;
  831. WORD SegMinAlloc;
  832. } NE_SEGMENT_ENTRY, *PNE_SEGMENT_ENTRY;
  833. typedef struct _NE_RELOC_ITEM {
  834. BYTE AddressType;
  835. BYTE RelocType;
  836. WORD RelocOffset;
  837. WORD ModuleOffset;
  838. WORD FunctionOffset;
  839. } NE_RELOC_ITEM, *PNE_RELOC_ITEM;
  840. #define SEG_CODE_MASK 0x0001
  841. #define SEG_CODE 0x0000
  842. #define SEG_PRELOAD_MASK 0x0040
  843. #define SEG_PRELOAD 0x0040
  844. #define SEG_RELOC_MASK 0x0100
  845. #define SEG_RELOC 0x0100
  846. #define RELOC_IMPORTED_ORDINAL 0x01
  847. #define RELOC_IMPORTED_NAME 0x02
  848. #define IMAGE_DOS_SIGNATURE 0x5A4D // MZ
  849. #define IMAGE_NE_SIGNATURE 0x454E // NE
  850. #define IMAGE_PE_SIGNATURE 0x00004550l // PE00
  851. #pragma pack(pop)
  852. typedef struct _EXPORT_ENUM32 {
  853. /*user area - BEGIN*/
  854. PCSTR ExportFunction;
  855. DWORD ExportFunctionOrd;
  856. /*user area - END*/
  857. PLOADED_IMAGE Image;
  858. PIMAGE_EXPORT_DIRECTORY ImageDescriptor;
  859. PDWORD ExportNamesAddr;
  860. PUSHORT ExportOrdAddr;
  861. DWORD CurrExportNr;
  862. } EXPORT_ENUM32, *PEXPORT_ENUM32;
  863. typedef struct _EXPORT_ENUM16 {
  864. /*user area - BEGIN*/
  865. CHAR ExportFunction[MAX_MBCHAR_PATH];
  866. PUSHORT ExportFunctionOrd;
  867. /*user area - END*/
  868. BOOL ResTable;
  869. PCSTR Image;
  870. PDOS_HEADER DosHeader;
  871. PNE_HEADER NeHeader;
  872. PCSTR NamesEntry;
  873. } EXPORT_ENUM16, *PEXPORT_ENUM16;
  874. #define UNKNOWN_MODULE 0
  875. #define DOS_MODULE 1
  876. #define W16_MODULE 2
  877. #define W32_MODULE 3
  878. typedef struct _MODULE_IMAGE {
  879. UINT ModuleType;
  880. union {
  881. struct {
  882. LOADED_IMAGE Image;
  883. } W32Data;
  884. struct {
  885. PCSTR Image;
  886. HANDLE FileHandle;
  887. HANDLE MapHandle;
  888. } W16Data;
  889. } ModuleData;
  890. } MODULE_IMAGE, *PMODULE_IMAGE;
  891. BOOL
  892. pLoadModuleData (
  893. IN PCSTR ModuleName,
  894. IN OUT PMODULE_IMAGE ModuleImage
  895. )
  896. {
  897. HANDLE fileHandle;
  898. DWORD bytesRead;
  899. DOS_HEADER dh;
  900. DWORD sign;
  901. PWORD signNE = (PWORD)&sign;
  902. BOOL result = FALSE;
  903. ZeroMemory (ModuleImage, sizeof (MODULE_IMAGE));
  904. fileHandle = CreateFile (ModuleName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
  905. if (fileHandle == INVALID_HANDLE_VALUE) {
  906. ModuleImage->ModuleType = UNKNOWN_MODULE;
  907. return FALSE;
  908. }
  909. __try {
  910. __try {
  911. if ((!ReadFile (fileHandle, &dh, sizeof (DOS_HEADER), &bytesRead, NULL)) ||
  912. (bytesRead != sizeof (DOS_HEADER))
  913. ) {
  914. __leave;
  915. }
  916. result = TRUE;
  917. if (dh.e_magic != IMAGE_DOS_SIGNATURE) {
  918. ModuleImage->ModuleType = UNKNOWN_MODULE;
  919. __leave;
  920. }
  921. ModuleImage->ModuleType = DOS_MODULE;
  922. if (SetFilePointer (fileHandle, dh.e_lfanew, NULL, FILE_BEGIN) != (DWORD)dh.e_lfanew) {
  923. __leave;
  924. }
  925. if ((!ReadFile (fileHandle, &sign, sizeof (DWORD), &bytesRead, NULL)) ||
  926. (bytesRead != sizeof (DWORD))
  927. ) {
  928. __leave;
  929. }
  930. CloseHandle (fileHandle);
  931. fileHandle = INVALID_HANDLE_VALUE;
  932. if (sign == IMAGE_PE_SIGNATURE) {
  933. ModuleImage->ModuleType = W32_MODULE;
  934. result = MapAndLoad ((PSTR)ModuleName, NULL, &ModuleImage->ModuleData.W32Data.Image, FALSE, TRUE);
  935. }
  936. if (*signNE == IMAGE_NE_SIGNATURE) {
  937. ModuleImage->ModuleType = W16_MODULE;
  938. ModuleImage->ModuleData.W16Data.Image = MapFileIntoMemory (
  939. ModuleName,
  940. &ModuleImage->ModuleData.W16Data.FileHandle,
  941. &ModuleImage->ModuleData.W16Data.MapHandle
  942. );
  943. result = (ModuleImage->ModuleData.W16Data.Image != NULL);
  944. }
  945. }
  946. __finally {
  947. if (fileHandle != INVALID_HANDLE_VALUE) {
  948. CloseHandle (fileHandle);
  949. }
  950. }
  951. }
  952. __except (EXCEPTION_EXECUTE_HANDLER) {
  953. CloseHandle (fileHandle);
  954. }
  955. return result;
  956. }
  957. BOOL
  958. pUnloadModuleData (
  959. IN OUT PMODULE_IMAGE ModuleImage
  960. )
  961. {
  962. switch (ModuleImage->ModuleType) {
  963. case W32_MODULE:
  964. UnMapAndLoad (&ModuleImage->ModuleData.W32Data.Image);
  965. break;
  966. case W16_MODULE:
  967. UnmapFile (
  968. (PVOID) ModuleImage->ModuleData.W16Data.Image,
  969. ModuleImage->ModuleData.W16Data.FileHandle,
  970. ModuleImage->ModuleData.W16Data.MapHandle
  971. );
  972. break;
  973. default:;
  974. }
  975. return TRUE;
  976. }
  977. BOOL
  978. EnumNextExportFunction16 (
  979. IN OUT PEXPORT_ENUM16 ModuleExports
  980. )
  981. {
  982. ModuleExports->NamesEntry += ModuleExports->NamesEntry [0] + 3;
  983. if (ModuleExports->NamesEntry [0] == 0) {
  984. if (!ModuleExports->ResTable) {
  985. return FALSE;
  986. }
  987. else {
  988. ModuleExports->ResTable = FALSE;
  989. ModuleExports->NamesEntry = ModuleExports->Image +
  990. ModuleExports->NeHeader->NonResNameTableOffset;
  991. return EnumNextExportFunction16 (ModuleExports);
  992. }
  993. }
  994. strncpy (ModuleExports->ExportFunction, ModuleExports->NamesEntry + 1, ModuleExports->NamesEntry [0]);
  995. ModuleExports->ExportFunction [ModuleExports->NamesEntry [0]] = 0;
  996. ModuleExports->ExportFunctionOrd = (PUSHORT) (ModuleExports->NamesEntry + ModuleExports->NamesEntry [0] + 1);
  997. return TRUE;
  998. }
  999. BOOL
  1000. EnumFirstExportFunction16 (
  1001. IN PCSTR ModuleImage,
  1002. IN OUT PEXPORT_ENUM16 ModuleExports
  1003. )
  1004. {
  1005. ZeroMemory (ModuleExports, sizeof (EXPORT_ENUM16));
  1006. ModuleExports->Image = ModuleImage;
  1007. ModuleExports->ResTable = TRUE;
  1008. ModuleExports->DosHeader = (PDOS_HEADER) (ModuleExports->Image);
  1009. ModuleExports->NeHeader = (PNE_HEADER) (ModuleExports->Image + ModuleExports->DosHeader->e_lfanew);
  1010. ModuleExports->NamesEntry = ModuleExports->Image +
  1011. ModuleExports->DosHeader->e_lfanew +
  1012. ModuleExports->NeHeader->ResNameTableOffset;
  1013. return EnumNextExportFunction16 (ModuleExports);
  1014. }
  1015. BOOL
  1016. EnumNextExportFunction32 (
  1017. IN OUT PEXPORT_ENUM32 ModuleExports
  1018. )
  1019. {
  1020. if (ModuleExports->CurrExportNr >= ModuleExports->ImageDescriptor->NumberOfNames) {
  1021. return FALSE;
  1022. }
  1023. if (*ModuleExports->ExportNamesAddr == 0) {
  1024. return FALSE;
  1025. }
  1026. ModuleExports->ExportFunction = ImageRvaToVa (
  1027. ModuleExports->Image->FileHeader,
  1028. ModuleExports->Image->MappedAddress,
  1029. *ModuleExports->ExportNamesAddr,
  1030. NULL
  1031. );
  1032. ModuleExports->ExportFunctionOrd = *ModuleExports->ExportOrdAddr + ModuleExports->ImageDescriptor->Base;
  1033. ModuleExports->ExportNamesAddr ++;
  1034. ModuleExports->ExportOrdAddr ++;
  1035. ModuleExports->CurrExportNr ++;
  1036. return (ModuleExports->ExportFunction != NULL);
  1037. }
  1038. BOOL
  1039. EnumFirstExportFunction32 (
  1040. IN PLOADED_IMAGE ModuleImage,
  1041. IN OUT PEXPORT_ENUM32 ModuleExports
  1042. )
  1043. {
  1044. ULONG imageSize;
  1045. ZeroMemory (ModuleExports, sizeof (EXPORT_ENUM32));
  1046. ModuleExports->Image = ModuleImage;
  1047. ModuleExports->ImageDescriptor = (PIMAGE_EXPORT_DIRECTORY)
  1048. ImageDirectoryEntryToData (
  1049. ModuleImage->MappedAddress,
  1050. FALSE,
  1051. IMAGE_DIRECTORY_ENTRY_EXPORT,
  1052. &imageSize
  1053. );
  1054. if (!ModuleExports->ImageDescriptor) {
  1055. DEBUGMSG((DBG_MODULES, ":Cannot load export directory for %s", ModuleImage->ModuleName));
  1056. return FALSE;
  1057. }
  1058. if (ModuleExports->ImageDescriptor->NumberOfNames == 0) {
  1059. return FALSE;
  1060. }
  1061. ModuleExports->ExportNamesAddr = (PDWORD) ImageRvaToVa (
  1062. ModuleExports->Image->FileHeader,
  1063. ModuleExports->Image->MappedAddress,
  1064. ModuleExports->ImageDescriptor->AddressOfNames,
  1065. NULL
  1066. );
  1067. ModuleExports->ExportOrdAddr = (PUSHORT) ImageRvaToVa (
  1068. ModuleExports->Image->FileHeader,
  1069. ModuleExports->Image->MappedAddress,
  1070. ModuleExports->ImageDescriptor->AddressOfNameOrdinals,
  1071. NULL
  1072. );
  1073. ModuleExports->CurrExportNr = 0;
  1074. return EnumNextExportFunction32 (ModuleExports);
  1075. }
  1076. DWORD
  1077. pProcessPEModule (
  1078. IN PCSTR CurrentPath,
  1079. IN PLOADED_IMAGE ModuleImage,
  1080. IN BOOL Win95Side
  1081. )
  1082. {
  1083. EXPORT_ENUM32 e;
  1084. CHAR key[MEMDB_MAX];
  1085. MEMDB_ENUM me;
  1086. DWORD memDbValue;
  1087. if (EnumFirstExportFunction32 (ModuleImage, &e)) {
  1088. do {
  1089. DEBUGMSG((DBG_MODULES, "%s 32exports %s", ModuleImage->ModuleName, e.ExportFunction));
  1090. if (Win95Side) {
  1091. MemDbBuildKey (key, MEMDB_CATEGORY_WNT_EXPORTS, GetFileNameFromPath (ModuleImage->ModuleName), e.ExportFunction, NULL);
  1092. if (!MemDbGetValue (key, &memDbValue)) {
  1093. if (MemDbEnumFirstValue (&me, MEMDB_CATEGORY_WIN9X_APIS TEXT("\\*"), MEMDB_ALL_SUBLEVELS, MEMDB_ALL_MATCHES)) {
  1094. MemDbBuildKey (key, MEMDB_CATEGORY_WIN9X_APIS, GetFileNameFromPath (ModuleImage->ModuleName), e.ExportFunction, NULL);
  1095. MemDbSetValue (key, 0);
  1096. _stprintf (key, TEXT("%s\\%s\\%ld"), MEMDB_CATEGORY_WIN9X_APIS, GetFileNameFromPath (ModuleImage->ModuleName), e.ExportFunctionOrd);
  1097. MemDbSetValue (key, 0);
  1098. }
  1099. }
  1100. else {
  1101. if ((USHORT)memDbValue != e.ExportFunctionOrd) {
  1102. _stprintf (key, TEXT("%s\\%s\\%ld"), MEMDB_CATEGORY_WIN9X_APIS, GetFileNameFromPath (ModuleImage->ModuleName), e.ExportFunctionOrd);
  1103. MemDbSetValue (key, 0);
  1104. }
  1105. }
  1106. }
  1107. else {
  1108. MemDbBuildKey (key, MEMDB_CATEGORY_WNT_EXPORTS, GetFileNameFromPath (ModuleImage->ModuleName), e.ExportFunction, NULL);
  1109. if (!MemDbGetValue (key, NULL)) {
  1110. MemDbSetValue (key, e.ExportFunctionOrd);
  1111. }
  1112. }
  1113. }
  1114. while (EnumNextExportFunction32 (&e));
  1115. }
  1116. return TRUE;
  1117. }
  1118. DWORD
  1119. pProcessNEModule (
  1120. IN PCSTR ModuleName,
  1121. IN PCSTR ModuleImage,
  1122. IN BOOL Win95Side
  1123. )
  1124. {
  1125. EXPORT_ENUM16 e;
  1126. CHAR key[MEMDB_MAX];
  1127. CHAR fileName[MEMDB_MAX];
  1128. PSTR extPtr;
  1129. MEMDB_ENUM me;
  1130. DWORD memDbValue;
  1131. //since this is a NT module whenever some other module imports something from this one we will not have the
  1132. //extension so let's get the extension out
  1133. StringCopy (fileName, GetFileNameFromPath (ModuleName));
  1134. extPtr = (PSTR)GetFileExtensionFromPath (fileName);
  1135. if (extPtr) {
  1136. extPtr = _mbsdec (fileName, extPtr);
  1137. if (extPtr) {
  1138. *extPtr = 0;
  1139. }
  1140. }
  1141. if (EnumFirstExportFunction16 (ModuleImage, &e)) {
  1142. do {
  1143. DEBUGMSG((DBG_MODULES, "%s 16exports %s", ModuleName, e.ExportFunction));
  1144. if (Win95Side) {
  1145. MemDbBuildKey (key, MEMDB_CATEGORY_WNT_EXPORTS, fileName, e.ExportFunction, NULL);
  1146. if (!MemDbGetValue (key, &memDbValue)) {
  1147. if (MemDbEnumFirstValue (&me, MEMDB_CATEGORY_WIN9X_APIS TEXT("\\*"), MEMDB_ALL_SUBLEVELS, MEMDB_ALL_MATCHES)) {
  1148. MemDbBuildKey (key, MEMDB_CATEGORY_WIN9X_APIS, fileName, e.ExportFunction, NULL);
  1149. MemDbSetValue (key, 0);
  1150. _stprintf (key, TEXT("%s\\%s\\%ld"), MEMDB_CATEGORY_WIN9X_APIS, fileName, *e.ExportFunctionOrd);
  1151. MemDbSetValue (key, 0);
  1152. }
  1153. }
  1154. else {
  1155. if ((USHORT)memDbValue != (*e.ExportFunctionOrd)) {
  1156. _stprintf (key, TEXT("%s\\%s\\%ld"), MEMDB_CATEGORY_WIN9X_APIS, fileName, *e.ExportFunctionOrd);
  1157. MemDbSetValue (key, 0);
  1158. }
  1159. }
  1160. }
  1161. else {
  1162. MemDbBuildKey (key, MEMDB_CATEGORY_WNT_EXPORTS, fileName, e.ExportFunction, NULL);
  1163. if (!MemDbGetValue (key, NULL)) {
  1164. MemDbSetValue (key, *e.ExportFunctionOrd);
  1165. }
  1166. }
  1167. }
  1168. while (EnumNextExportFunction16 (&e));
  1169. }
  1170. return TRUE;
  1171. }
  1172. BOOL
  1173. pProcessExportModule (
  1174. IN PCTSTR ModuleName,
  1175. IN BOOL Win95Side
  1176. )
  1177. {
  1178. MODULE_IMAGE moduleImage;
  1179. DWORD result = TRUE;
  1180. PCSTR fileName = GetFileNameFromPath (ModuleName);
  1181. if (_stricmp (fileName, "COMCTL32.DLL") == 0) {
  1182. result = TRUE;
  1183. }
  1184. __try {
  1185. if (!pLoadModuleData (ModuleName, &moduleImage)) {
  1186. DEBUGMSG((DBG_MODULES, ":Cannot load image for %s. Error:%ld", ModuleName, GetLastError()));
  1187. __leave;
  1188. }
  1189. __try {
  1190. switch (moduleImage.ModuleType) {
  1191. case DOS_MODULE:
  1192. DEBUGMSG((DBG_MODULES, "Examining %s : DOS module.", ModuleName));
  1193. break;
  1194. case W16_MODULE:
  1195. DEBUGMSG((DBG_MODULES, "Examining %s : W16 module.", ModuleName));
  1196. result = pProcessNEModule (ModuleName, moduleImage.ModuleData.W16Data.Image, Win95Side);
  1197. break;
  1198. case W32_MODULE:
  1199. DEBUGMSG((DBG_MODULES, "Examining %s : W32 module.", ModuleName));
  1200. result = pProcessPEModule (ModuleName, &moduleImage.ModuleData.W32Data.Image, Win95Side);
  1201. break;
  1202. default:
  1203. DEBUGMSG((DBG_MODULES, "Examining %s : Unknown module type.", ModuleName));
  1204. }
  1205. }
  1206. __except (EXCEPTION_EXECUTE_HANDLER) {
  1207. DEBUGMSG((DBG_WARNING, DBG_MODULES":Access violation while checking %s", ModuleName));
  1208. result = TRUE;
  1209. }
  1210. }
  1211. __finally {
  1212. pUnloadModuleData (&moduleImage);
  1213. }
  1214. return result;
  1215. }