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.

1366 lines
42 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. modules.c
  5. Abstract:
  6. Implements a function that checkes every module listed in MEMDB_CATEGORY_MODULE_CHECK
  7. trying to see if all modules listed in IMPORT section are going to be available on NT.
  8. The entry point is ProcessModules
  9. Author:
  10. Calin Negreanu (calinn) 27-Nov-1997
  11. Revision History:
  12. mvander 26-Map-1999 Moved MODULESTATUS defines to fileops.h
  13. calinn 23-Sep-1998 Added support for NT installed files
  14. --*/
  15. #include "pch.h"
  16. #include "migdbp.h"
  17. #include "migappp.h"
  18. #define DBG_MODULES "Modules"
  19. #ifdef DEBUG
  20. DWORD g_NumEXEs = 0;
  21. #endif
  22. DWORD g_ModuleRecursionLevel = 0;
  23. #define MAX_MODULE_RECURSION_LEVEL 50
  24. #define WIN32_EXE_SET_BITS (IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_32BIT_MACHINE)
  25. #define WIN32_EXE_CLEAR_BITS (IMAGE_FILE_DLL)
  26. #define WIN32_DLL_SET_BITS (WIN32_EXE_SET_BITS | IMAGE_FILE_DLL)
  27. #define WIN32_DLL_CLEAR_BITS 0
  28. #define WIN16_LIBRARY 0x8000
  29. //since we are reading from a file we need that sizeof to give us the accurate result
  30. #pragma pack(push,1)
  31. typedef struct _NE_HEADER {
  32. WORD Magic;
  33. BYTE MajorLinkerVersion;
  34. BYTE MinorLinkerVersion;
  35. WORD EntryTableOff;
  36. WORD EntryTableLen;
  37. ULONG Reserved;
  38. WORD Flags;
  39. WORD NumberOfDataSeg;
  40. WORD SizeOfHeap;
  41. WORD SizeOfStack;
  42. ULONG CS_IP;
  43. ULONG SS_SP;
  44. WORD NumEntriesSegTable;
  45. WORD NumEntriesModuleTable;
  46. WORD NonResNameTableSize;
  47. WORD SegTableOffset;
  48. WORD ResTableOffset;
  49. WORD ResNameTableOffset;
  50. WORD ModuleTableOffset;
  51. WORD ImportedTableOffset;
  52. ULONG NonResNameTableOffset;
  53. WORD NumberOfMovableEntryPoints;
  54. WORD ShiftCount;
  55. WORD NumberOfResourceSegments;
  56. BYTE TargetOS;
  57. BYTE AdditionalInfo;
  58. WORD FastLoadOffset;
  59. WORD FastLoadSize;
  60. WORD Reserved1;
  61. WORD WinVersionExpected;
  62. } NE_HEADER, *PNE_HEADER;
  63. typedef struct _NE_SEGMENT_ENTRY {
  64. WORD SegmentOffset;
  65. WORD SegmentLen;
  66. WORD SegmentFlags;
  67. WORD SegMinAlloc;
  68. } NE_SEGMENT_ENTRY, *PNE_SEGMENT_ENTRY;
  69. typedef struct _NE_RELOC_ITEM {
  70. BYTE AddressType;
  71. BYTE RelocType;
  72. WORD RelocOffset;
  73. WORD ModuleOffset;
  74. WORD FunctionOffset;
  75. } NE_RELOC_ITEM, *PNE_RELOC_ITEM;
  76. #define SEG_CODE_MASK 0x0001
  77. #define SEG_CODE 0x0000
  78. #define SEG_PRELOAD_MASK 0x0040
  79. #define SEG_PRELOAD 0x0040
  80. #define SEG_RELOC_MASK 0x0100
  81. #define SEG_RELOC 0x0100
  82. #define RELOC_IMPORTED_ORDINAL 0x01
  83. #define RELOC_IMPORTED_NAME 0x02
  84. #define RELOC_ADDR_TYPE 0x03
  85. #pragma pack(pop)
  86. typedef struct _IMPORT_ENUM32 {
  87. /*user area - BEGIN*/
  88. PCSTR ImportModule;
  89. PCSTR ImportFunction;
  90. ULONG ImportFunctionOrd;
  91. /*user area - END*/
  92. PLOADED_IMAGE Image;
  93. PIMAGE_IMPORT_DESCRIPTOR ImageDescriptor;
  94. DWORD ImportFunctionAddr;
  95. PIMAGE_THUNK_DATA ImageData;
  96. PIMAGE_IMPORT_BY_NAME ImageName;
  97. } IMPORT_ENUM32, *PIMPORT_ENUM32;
  98. typedef struct _IMPORT_ENUM16 {
  99. /*user area - BEGIN*/
  100. CHAR ImportModule[MAX_MBCHAR_PATH];
  101. CHAR ImportFunction[MAX_MBCHAR_PATH];
  102. ULONG ImportFunctionOrd;
  103. /*user area - END*/
  104. PCSTR Image;
  105. PDOS_HEADER DosHeader;
  106. PNE_HEADER NeHeader;
  107. PNE_SEGMENT_ENTRY SegmentEntry;
  108. WORD CurrSegEntry;
  109. PWORD CurrNrReloc;
  110. PNE_RELOC_ITEM RelocItem;
  111. WORD CurrRelocItem;
  112. } IMPORT_ENUM16, *PIMPORT_ENUM16;
  113. typedef struct _MODULE_IMAGE {
  114. UINT ModuleType;
  115. union {
  116. struct {
  117. LOADED_IMAGE Image;
  118. } W32Data;
  119. struct {
  120. PCSTR Image;
  121. HANDLE FileHandle;
  122. HANDLE MapHandle;
  123. NE_HEADER Neh;
  124. } W16Data;
  125. } ModuleData;
  126. } MODULE_IMAGE, *PMODULE_IMAGE;
  127. static CHAR g_TempKey[MEMDB_MAX];
  128. #define CLEARBUFFER() g_TempKey[0] = 0
  129. #define ISBUFFEREMPTY() (g_TempKey[0] == 0)
  130. BOOL
  131. LoadModuleData (
  132. IN PCSTR ModuleName,
  133. IN OUT PMODULE_IMAGE ModuleImage
  134. )
  135. {
  136. HANDLE fileHandle;
  137. DWORD bytesRead;
  138. DOS_HEADER dh;
  139. DWORD sign;
  140. PWORD signNE = (PWORD)&sign;
  141. BOOL result = FALSE;
  142. ZeroMemory (ModuleImage, sizeof (MODULE_IMAGE));
  143. ModuleImage->ModuleType = UNKNOWN_MODULE;
  144. fileHandle = CreateFile (ModuleName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
  145. if (fileHandle == INVALID_HANDLE_VALUE) {
  146. return FALSE;
  147. }
  148. __try {
  149. __try {
  150. if ((!ReadFile (fileHandle, &dh, sizeof (DOS_HEADER), &bytesRead, NULL)) ||
  151. (bytesRead != sizeof (DOS_HEADER))
  152. ) {
  153. __leave;
  154. }
  155. result = TRUE;
  156. if (dh.e_magic != IMAGE_DOS_SIGNATURE) {
  157. ModuleImage->ModuleType = UNKNOWN_MODULE;
  158. __leave;
  159. }
  160. ModuleImage->ModuleType = DOS_MODULE;
  161. if (SetFilePointer (fileHandle, dh.e_lfanew, NULL, FILE_BEGIN) != (DWORD)dh.e_lfanew) {
  162. __leave;
  163. }
  164. if ((!ReadFile (fileHandle, &sign, sizeof (DWORD), &bytesRead, NULL)) ||
  165. (bytesRead != sizeof (DWORD))
  166. ) {
  167. __leave;
  168. }
  169. if (sign == IMAGE_PE_SIGNATURE) {
  170. ModuleImage->ModuleType = W32_MODULE;
  171. result = MapAndLoad ((PSTR)ModuleName, NULL, &ModuleImage->ModuleData.W32Data.Image, FALSE, TRUE);
  172. }
  173. if (*signNE == IMAGE_NE_SIGNATURE) {
  174. ModuleImage->ModuleType = W16_MODULE;
  175. ModuleImage->ModuleData.W16Data.Image = MapFileIntoMemory (
  176. ModuleName,
  177. &ModuleImage->ModuleData.W16Data.FileHandle,
  178. &ModuleImage->ModuleData.W16Data.MapHandle
  179. );
  180. if (SetFilePointer (fileHandle, dh.e_lfanew, NULL, FILE_BEGIN) != (DWORD)dh.e_lfanew) {
  181. __leave;
  182. }
  183. if ((!ReadFile (fileHandle, &ModuleImage->ModuleData.W16Data.Neh, sizeof (NE_HEADER), &bytesRead, NULL)) ||
  184. (bytesRead != sizeof (NE_HEADER))
  185. ) {
  186. __leave;
  187. }
  188. MYASSERT (ModuleImage->ModuleData.W16Data.Neh.Magic == IMAGE_NE_SIGNATURE);
  189. result = (ModuleImage->ModuleData.W16Data.Image != NULL);
  190. }
  191. }
  192. __finally {
  193. if (fileHandle != INVALID_HANDLE_VALUE) {
  194. CloseHandle (fileHandle);
  195. }
  196. }
  197. }
  198. __except (EXCEPTION_EXECUTE_HANDLER) {
  199. CloseHandle (fileHandle);
  200. }
  201. return result;
  202. }
  203. BOOL
  204. UnloadModuleData (
  205. IN OUT PMODULE_IMAGE ModuleImage
  206. )
  207. {
  208. switch (ModuleImage->ModuleType) {
  209. case W32_MODULE:
  210. UnMapAndLoad (&ModuleImage->ModuleData.W32Data.Image);
  211. break;
  212. case W16_MODULE:
  213. UnmapFile (
  214. (PVOID) ModuleImage->ModuleData.W16Data.Image,
  215. ModuleImage->ModuleData.W16Data.FileHandle,
  216. ModuleImage->ModuleData.W16Data.MapHandle
  217. );
  218. break;
  219. default:;
  220. }
  221. return TRUE;
  222. }
  223. DWORD
  224. GetExeType (
  225. IN PCTSTR ModuleName
  226. )
  227. {
  228. MODULE_IMAGE moduleImage;
  229. DWORD result = EXE_UNKNOWN;
  230. DWORD d;
  231. __try {
  232. if (!LoadModuleData (ModuleName, &moduleImage)) {
  233. LOG ((LOG_WARNING, DBG_MODULES":Cannot load image for %s. Error:%ld", ModuleName, GetLastError()));
  234. __leave;
  235. }
  236. if (moduleImage.ModuleType == W32_MODULE) {
  237. d = moduleImage.ModuleData.W32Data.Image.Characteristics;
  238. result = (d & IMAGE_FILE_DLL) ? EXE_WIN32_DLL : EXE_WIN32_APP;
  239. } else if (moduleImage.ModuleType == W16_MODULE) {
  240. result = (moduleImage.ModuleData.W16Data.Neh.Flags & WIN16_LIBRARY) ? EXE_WIN16_DLL : EXE_WIN16_APP;
  241. }
  242. }
  243. __finally {
  244. UnloadModuleData (&moduleImage);
  245. }
  246. return result;
  247. }
  248. BOOL
  249. IsNtCompatibleModule (
  250. IN PCTSTR ModuleName
  251. )
  252. {
  253. if (CheckModule (ModuleName, NULL) == MODULESTATUS_BAD) {
  254. return FALSE;
  255. }
  256. //
  257. // other tests?
  258. //
  259. return TRUE;
  260. }
  261. PTSTR
  262. pBuildModulePaths (
  263. IN PCTSTR ModuleName,
  264. IN PCTSTR AppPaths OPTIONAL
  265. )
  266. {
  267. PTSTR currentPaths;
  268. HKEY appPathsKey, currentAppKey;
  269. REGKEY_ENUM appPathsEnum;
  270. PCTSTR appPathsValue;
  271. PTSTR appPathValueExp;
  272. PATH_ENUM pathEnum;
  273. DWORD attrib;
  274. PTSTR pathsPtr;
  275. TCHAR modulePath[MAX_PATH];
  276. BOOL b;
  277. StringCopy (modulePath, ModuleName);
  278. pathsPtr = (PTSTR)GetFileNameFromPath (modulePath);
  279. MYASSERT (pathsPtr && *(pathsPtr - 1) == TEXT('\\'));
  280. *(pathsPtr - 1) = 0;
  281. if (AppPaths) {
  282. currentPaths = DuplicateText (AppPaths);
  283. b = FALSE;
  284. if (EnumFirstPathEx (&pathEnum, currentPaths, NULL, NULL, FALSE)) {
  285. do {
  286. if (StringIMatch (pathEnum.PtrCurrPath, modulePath)) {
  287. b = TRUE;
  288. break;
  289. }
  290. } while (EnumNextPath (&pathEnum));
  291. }
  292. if (!b) {
  293. pathsPtr = JoinTextEx (NULL, modulePath, currentPaths, ";", 0, NULL);
  294. FreeText (currentPaths);
  295. currentPaths = pathsPtr;
  296. }
  297. } else {
  298. currentPaths = DuplicateText (modulePath);
  299. }
  300. appPathsKey = OpenRegKeyStr (S_SKEY_APP_PATHS);
  301. if (appPathsKey != NULL) {
  302. currentAppKey = OpenRegKey (appPathsKey, GetFileNameFromPath (ModuleName));
  303. if (currentAppKey != NULL) {
  304. appPathsValue = GetRegValueString (currentAppKey, TEXT("Path"));
  305. if (appPathsValue) {
  306. if (EnumFirstPathEx (&pathEnum, appPathsValue, NULL, NULL, FALSE)) {
  307. do {
  308. MYASSERT (*pathEnum.PtrCurrPath != 0);
  309. appPathValueExp = ExpandEnvironmentTextA(pathEnum.PtrCurrPath);
  310. _mbsctrim (appPathValueExp, '\\');
  311. attrib = QuietGetFileAttributes (appPathValueExp);
  312. if ((attrib != INVALID_ATTRIBUTES) &&
  313. ((attrib & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY)
  314. ) {
  315. continue;
  316. }
  317. pathsPtr = JoinTextEx (NULL, currentPaths, appPathValueExp, ";", 0, NULL);
  318. FreeText (currentPaths);
  319. currentPaths = pathsPtr;
  320. FreeText (appPathValueExp);
  321. }
  322. while (EnumNextPath (&pathEnum));
  323. }
  324. MemFree (g_hHeap, 0, appPathsValue);
  325. }
  326. appPathsValue = GetRegValueString (currentAppKey, TEXT("UpdatesPath"));
  327. if (appPathsValue) {
  328. if (EnumFirstPathEx (&pathEnum, appPathsValue, NULL, NULL, FALSE)) {
  329. do {
  330. MYASSERT (*pathEnum.PtrCurrPath != 0);
  331. appPathValueExp = ExpandEnvironmentTextA(pathEnum.PtrCurrPath);
  332. _mbsctrim (appPathValueExp, '\\');
  333. attrib = QuietGetFileAttributes (appPathValueExp);
  334. if ((attrib != INVALID_ATTRIBUTES) &&
  335. ((attrib & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY)
  336. ) {
  337. continue;
  338. }
  339. pathsPtr = JoinTextEx (NULL, currentPaths, appPathValueExp, ";", 0, NULL);
  340. FreeText (currentPaths);
  341. currentPaths = pathsPtr;
  342. FreeText (appPathValueExp);
  343. }
  344. while (EnumNextPath (&pathEnum));
  345. }
  346. MemFree (g_hHeap, 0, appPathsValue);
  347. }
  348. CloseRegKey (currentAppKey);
  349. }
  350. CloseRegKey (appPathsKey);
  351. }
  352. return currentPaths;
  353. }
  354. BOOL
  355. EnumNextImport16 (
  356. IN OUT PIMPORT_ENUM16 ModuleImports
  357. )
  358. {
  359. PCSTR currSegmentOffset,importPtr;
  360. PWORD moduleNameOffset;
  361. BOOL itemFound;
  362. ModuleImports->RelocItem ++;
  363. ModuleImports->CurrRelocItem ++;
  364. itemFound = FALSE;
  365. while ((ModuleImports->CurrSegEntry <= ModuleImports->NeHeader->NumEntriesSegTable) && (!itemFound)) {
  366. if (((ModuleImports->SegmentEntry->SegmentFlags & SEG_CODE_MASK ) == SEG_CODE ) &&
  367. ((ModuleImports->SegmentEntry->SegmentFlags & SEG_RELOC_MASK ) == SEG_RELOC ) &&
  368. ((ModuleImports->SegmentEntry->SegmentFlags & SEG_PRELOAD_MASK) == SEG_PRELOAD)
  369. ) {
  370. __try {
  371. while ((ModuleImports->CurrRelocItem <= *(ModuleImports->CurrNrReloc)) && (!itemFound)) {
  372. if (((ModuleImports->RelocItem->AddressType == 0) ||
  373. (ModuleImports->RelocItem->AddressType == 2) ||
  374. (ModuleImports->RelocItem->AddressType == 3) ||
  375. (ModuleImports->RelocItem->AddressType == 5) ||
  376. (ModuleImports->RelocItem->AddressType == 11) ||
  377. (ModuleImports->RelocItem->AddressType == 13)
  378. ) &&
  379. ((ModuleImports->RelocItem->RelocType == RELOC_IMPORTED_ORDINAL) ||
  380. (ModuleImports->RelocItem->RelocType == RELOC_IMPORTED_NAME )
  381. )
  382. ) {
  383. itemFound = TRUE;
  384. moduleNameOffset = (PWORD) (ModuleImports->Image +
  385. ModuleImports->DosHeader->e_lfanew +
  386. ModuleImports->NeHeader->ModuleTableOffset +
  387. (ModuleImports->RelocItem->ModuleOffset - 1) * sizeof (WORD));
  388. importPtr = ModuleImports->Image +
  389. ModuleImports->DosHeader->e_lfanew +
  390. ModuleImports->NeHeader->ImportedTableOffset +
  391. *moduleNameOffset;
  392. strncpy (ModuleImports->ImportModule, importPtr + 1, (BYTE)importPtr[0]);
  393. ModuleImports->ImportModule[(BYTE)importPtr[0]] = 0;
  394. if (ModuleImports->RelocItem->RelocType == RELOC_IMPORTED_ORDINAL) {
  395. ModuleImports->ImportFunction[0] = 0;
  396. ModuleImports->ImportFunctionOrd = ModuleImports->RelocItem->FunctionOffset;
  397. }
  398. else {
  399. importPtr = ModuleImports->Image +
  400. ModuleImports->DosHeader->e_lfanew +
  401. ModuleImports->NeHeader->ImportedTableOffset +
  402. ModuleImports->RelocItem->FunctionOffset;
  403. strncpy (ModuleImports->ImportFunction, importPtr + 1, (BYTE)importPtr[0]);
  404. ModuleImports->ImportFunction[(BYTE)importPtr[0]] = 0;
  405. ModuleImports->ImportFunctionOrd = 0;
  406. }
  407. }
  408. if (!itemFound) {
  409. ModuleImports->RelocItem ++;
  410. ModuleImports->CurrRelocItem ++;
  411. }
  412. }
  413. }
  414. __except (1) {
  415. itemFound = FALSE;
  416. }
  417. }
  418. if (!itemFound) {
  419. ModuleImports->SegmentEntry ++;
  420. ModuleImports->CurrSegEntry ++;
  421. currSegmentOffset = ModuleImports->Image +
  422. (ModuleImports->SegmentEntry->SegmentOffset << ModuleImports->NeHeader->ShiftCount);
  423. if (ModuleImports->SegmentEntry->SegmentLen == 0) {
  424. currSegmentOffset += 65535;
  425. }
  426. else {
  427. currSegmentOffset += ModuleImports->SegmentEntry->SegmentLen;
  428. }
  429. ModuleImports->CurrNrReloc = (PWORD) currSegmentOffset;
  430. currSegmentOffset += sizeof(WORD);
  431. ModuleImports->RelocItem = (PNE_RELOC_ITEM) currSegmentOffset;
  432. ModuleImports->CurrRelocItem = 1;
  433. }
  434. }
  435. return itemFound;
  436. }
  437. BOOL
  438. EnumFirstImport16 (
  439. IN PCSTR ModuleImage,
  440. IN OUT PIMPORT_ENUM16 ModuleImports
  441. )
  442. {
  443. PCSTR currSegmentOffset;
  444. ZeroMemory (ModuleImports, sizeof (IMPORT_ENUM16));
  445. ModuleImports->Image = ModuleImage;
  446. ModuleImports->DosHeader = (PDOS_HEADER) (ModuleImports->Image);
  447. ModuleImports->NeHeader = (PNE_HEADER) (ModuleImports->Image + ModuleImports->DosHeader->e_lfanew);
  448. ModuleImports->SegmentEntry = (PNE_SEGMENT_ENTRY) (ModuleImports->Image +
  449. ModuleImports->DosHeader->e_lfanew +
  450. ModuleImports->NeHeader->SegTableOffset
  451. );
  452. ModuleImports->CurrSegEntry = 1;
  453. currSegmentOffset = ModuleImports->Image +
  454. (ModuleImports->SegmentEntry->SegmentOffset << ModuleImports->NeHeader->ShiftCount);
  455. if (ModuleImports->SegmentEntry->SegmentLen == 0) {
  456. currSegmentOffset += 65535;
  457. }
  458. else {
  459. currSegmentOffset += ModuleImports->SegmentEntry->SegmentLen;
  460. }
  461. ModuleImports->CurrNrReloc = (PWORD) currSegmentOffset;
  462. currSegmentOffset += sizeof(WORD);
  463. ModuleImports->RelocItem = (PNE_RELOC_ITEM) currSegmentOffset;
  464. ModuleImports->CurrRelocItem = 1;
  465. ModuleImports->RelocItem --;
  466. ModuleImports->CurrRelocItem --;
  467. return EnumNextImport16 (ModuleImports);
  468. }
  469. BOOL
  470. EnumNextImportFunction32 (
  471. IN OUT PIMPORT_ENUM32 ModuleImports
  472. )
  473. {
  474. if (ModuleImports->ImportFunctionAddr == 0) {
  475. return FALSE;
  476. }
  477. ModuleImports->ImageData = (PIMAGE_THUNK_DATA)
  478. ImageRvaToVa (
  479. ModuleImports->Image->FileHeader,
  480. ModuleImports->Image->MappedAddress,
  481. ModuleImports->ImportFunctionAddr,
  482. NULL
  483. );
  484. if (ModuleImports->ImageData->u1.AddressOfData) {
  485. ModuleImports->ImageName = (PIMAGE_IMPORT_BY_NAME)
  486. ImageRvaToVa (
  487. ModuleImports->Image->FileHeader,
  488. ModuleImports->Image->MappedAddress,
  489. (DWORD)ModuleImports->ImageData->u1.AddressOfData,
  490. NULL
  491. );
  492. if (ModuleImports->ImageName) { //import by name
  493. ModuleImports->ImportFunction = ModuleImports->ImageName->Name;
  494. ModuleImports->ImportFunctionOrd = 0;
  495. }
  496. else { //import by number
  497. ModuleImports->ImportFunction = NULL;
  498. ModuleImports->ImportFunctionOrd = ModuleImports->ImageData->u1.Ordinal & (~0x80000000);
  499. }
  500. ModuleImports->ImportFunctionAddr += 4;
  501. return TRUE;
  502. }
  503. else {
  504. ModuleImports->ImportFunctionAddr = 0;
  505. return FALSE;
  506. }
  507. }
  508. BOOL
  509. EnumFirstImportFunction32 (
  510. IN OUT PIMPORT_ENUM32 ModuleImports
  511. )
  512. {
  513. if ((ModuleImports->ImageDescriptor == NULL) ||
  514. (ModuleImports->ImportModule == NULL)
  515. ) {
  516. return FALSE;
  517. }
  518. ModuleImports->ImportFunctionAddr = ModuleImports->ImageDescriptor->OriginalFirstThunk;
  519. return EnumNextImportFunction32 (ModuleImports);
  520. }
  521. BOOL
  522. EnumNextImportModule32 (
  523. IN OUT PIMPORT_ENUM32 ModuleImports
  524. )
  525. {
  526. if (ModuleImports->ImageDescriptor == NULL) {
  527. return FALSE;
  528. }
  529. ModuleImports->ImageDescriptor ++;
  530. if (ModuleImports->ImageDescriptor->Name == 0) {
  531. return FALSE;
  532. }
  533. ModuleImports->ImportModule = (PCSTR) ImageRvaToVa (
  534. ModuleImports->Image->FileHeader,
  535. ModuleImports->Image->MappedAddress,
  536. ModuleImports->ImageDescriptor->Name,
  537. NULL
  538. );
  539. return (ModuleImports->ImportModule != NULL);
  540. }
  541. BOOL
  542. EnumFirstImportModule32 (
  543. IN PLOADED_IMAGE ModuleImage,
  544. IN OUT PIMPORT_ENUM32 ModuleImports
  545. )
  546. {
  547. ULONG imageSize;
  548. ZeroMemory (ModuleImports, sizeof (IMPORT_ENUM32));
  549. ModuleImports->Image = ModuleImage;
  550. ModuleImports->ImageDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)
  551. ImageDirectoryEntryToData (
  552. ModuleImage->MappedAddress,
  553. FALSE,
  554. IMAGE_DIRECTORY_ENTRY_IMPORT,
  555. &imageSize
  556. );
  557. if (!ModuleImports->ImageDescriptor) {
  558. LOG((LOG_WARNING, DBG_MODULES":Cannot load import directory for %s", ModuleImage->ModuleName));
  559. return FALSE;
  560. }
  561. if (ModuleImports->ImageDescriptor->Name == 0) {
  562. return FALSE;
  563. }
  564. ModuleImports->ImportModule = (PCSTR) ImageRvaToVa (
  565. ModuleImports->Image->FileHeader,
  566. ModuleImports->Image->MappedAddress,
  567. ModuleImports->ImageDescriptor->Name,
  568. NULL
  569. );
  570. return (ModuleImports->ImportModule != NULL);
  571. }
  572. DWORD
  573. pCheckDependency (
  574. IN PCSTR CurrentPaths,
  575. IN PCSTR ModuleImported)
  576. {
  577. PSTR tempName = NULL;
  578. DWORD memDbValue = 0;
  579. PATH_ENUM pathEnum;
  580. DWORD result = MODULESTATUS_FILENOTFOUND;
  581. DWORD moduleStatus;
  582. pathEnum.BufferPtr = NULL;
  583. if (EnumFirstPath (&pathEnum, CurrentPaths, g_WinDir, g_SystemDir)) {
  584. __try {
  585. do {
  586. if (*pathEnum.PtrCurrPath == 0) {
  587. continue;
  588. }
  589. tempName = JoinPathsA (pathEnum.PtrCurrPath, ModuleImported);
  590. if (SizeOfStringA (tempName) > MAX_PATH) {
  591. //
  592. // path too long, ignore it
  593. //
  594. FreePathStringA (tempName);
  595. tempName = NULL;
  596. continue;
  597. }
  598. MemDbBuildKey (g_TempKey, MEMDB_CATEGORY_MODULE_CHECK, tempName, NULL, NULL);
  599. if (MemDbGetValue (g_TempKey, &memDbValue)) {
  600. if ((memDbValue == MODULESTATUS_CHECKED ) ||
  601. (memDbValue == MODULESTATUS_CHECKING)) {
  602. result = MODULESTATUS_CHECKED;
  603. __leave;
  604. }
  605. if (memDbValue == MODULESTATUS_NT_MODULE){
  606. result = MODULESTATUS_NT_MODULE;
  607. __leave;
  608. }
  609. }
  610. moduleStatus = GetFileStatusOnNt (tempName);
  611. if ((moduleStatus & FILESTATUS_DELETED) == 0) {
  612. if ((moduleStatus & FILESTATUS_REPLACED) == FILESTATUS_REPLACED) {
  613. result = MODULESTATUS_NT_MODULE;
  614. __leave;
  615. }
  616. if (DoesFileExist (tempName)) {
  617. result = CheckModule (tempName, CurrentPaths);
  618. __leave;
  619. }
  620. }
  621. if (moduleStatus & FILESTATUS_NTINSTALLED) {
  622. result = MODULESTATUS_NT_MODULE;
  623. __leave;
  624. }
  625. }
  626. while (EnumNextPath (&pathEnum));
  627. }
  628. __finally {
  629. EnumPathAbort (&pathEnum);
  630. if (tempName) {
  631. FreePathStringA (tempName);
  632. }
  633. }
  634. }
  635. return result;
  636. }
  637. BOOL
  638. pIsWin9xModule (
  639. IN PCTSTR ModuleName
  640. )
  641. {
  642. MEMDB_ENUM me;
  643. MemDbBuildKey (g_TempKey, MEMDB_CATEGORY_WIN9X_APIS, ModuleName, TEXT("*"), NULL);
  644. return MemDbEnumFirstValue (&me, g_TempKey, MEMDB_ALL_SUBLEVELS, MEMDB_ENDPOINTS_ONLY);
  645. }
  646. DWORD
  647. pCheckPEModule (
  648. IN PCSTR CurrentPaths,
  649. IN PLOADED_IMAGE ModuleImage
  650. )
  651. {
  652. IMPORT_ENUM32 e;
  653. DWORD result;
  654. if (EnumFirstImportModule32 (ModuleImage, &e)) {
  655. do {
  656. result = pCheckDependency (CurrentPaths, e.ImportModule);
  657. if (result == MODULESTATUS_BAD) {
  658. LOG((
  659. LOG_WARNING,
  660. "%s will be incompatible because %s is incompatible",
  661. ModuleImage->ModuleName,
  662. e.ImportModule));
  663. return result;
  664. }
  665. if (result == MODULESTATUS_NT_MODULE) {
  666. if (pIsWin9xModule (e.ImportModule)) {
  667. if (EnumFirstImportFunction32 (&e)) {
  668. do {
  669. if (e.ImportFunction) {
  670. MemDbBuildKey (g_TempKey, MEMDB_CATEGORY_WIN9X_APIS, e.ImportModule, e.ImportFunction, NULL);
  671. if (MemDbGetValue (g_TempKey, NULL)) {
  672. LOG((
  673. LOG_WARNING,
  674. "%s will be incompatible because %s export will not be available in %s",
  675. ModuleImage->ModuleName,
  676. e.ImportFunction,
  677. e.ImportModule));
  678. return MODULESTATUS_BAD;
  679. }
  680. }
  681. else {
  682. wsprintf (g_TempKey, "%s\\%s\\%lu", MEMDB_CATEGORY_WIN9X_APIS, e.ImportModule, e.ImportFunctionOrd);
  683. if (MemDbGetValue (g_TempKey, NULL)) {
  684. LOG((
  685. LOG_WARNING,
  686. "%s will be incompatible because export index %lu will point to a different export in %s",
  687. ModuleImage->ModuleName,
  688. e.ImportFunctionOrd,
  689. e.ImportModule));
  690. return MODULESTATUS_BAD;
  691. }
  692. }
  693. }
  694. while (EnumNextImportFunction32 (&e));
  695. }
  696. }
  697. }
  698. if (result == MODULESTATUS_FILENOTFOUND) {
  699. LOG ((
  700. LOG_WARNING,
  701. "Dependency %s of %s not found",
  702. e.ImportModule,
  703. ModuleImage->ModuleName
  704. ));
  705. }
  706. }
  707. while (EnumNextImportModule32 (&e));
  708. }
  709. return MODULESTATUS_CHECKED;
  710. }
  711. DWORD
  712. pCheckDependency16 (
  713. IN PCSTR CurrentPaths,
  714. IN OUT PCSTR ModuleImported
  715. )
  716. {
  717. PCTSTR moduleImported;
  718. DWORD result = MODULESTATUS_BAD;
  719. DWORD memDbValue;
  720. MemDbBuildKey (g_TempKey, MEMDB_CATEGORY_MODULE_CHECK, ModuleImported, NULL, NULL);
  721. if (MemDbGetValue (g_TempKey, &memDbValue)) {
  722. if ((memDbValue == MODULESTATUS_CHECKED ) ||
  723. (memDbValue == MODULESTATUS_CHECKING)) {
  724. result = MODULESTATUS_CHECKED;
  725. }
  726. if (memDbValue == MODULESTATUS_NT_MODULE){
  727. result = MODULESTATUS_NT_MODULE;
  728. }
  729. }
  730. if (result != MODULESTATUS_BAD) {
  731. return result;
  732. }
  733. moduleImported = JoinText (ModuleImported, ".DLL");
  734. result = pCheckDependency (CurrentPaths, moduleImported);
  735. FreeText (moduleImported);
  736. if (result != MODULESTATUS_BAD) {
  737. return result;
  738. }
  739. moduleImported = JoinText (ModuleImported, ".EXE");
  740. result = pCheckDependency (CurrentPaths, moduleImported);
  741. FreeText (moduleImported);
  742. if (result != MODULESTATUS_BAD) {
  743. return result;
  744. }
  745. moduleImported = JoinText (ModuleImported, ".DRV");
  746. result = pCheckDependency (CurrentPaths, moduleImported);
  747. FreeText (moduleImported);
  748. if (result != MODULESTATUS_BAD) {
  749. return result;
  750. }
  751. return result;
  752. }
  753. DWORD
  754. pCheckNEModule (
  755. IN PCSTR CurrentPaths,
  756. IN PCSTR ModuleName,
  757. IN PCSTR ModuleImage
  758. )
  759. {
  760. IMPORT_ENUM16 e;
  761. DWORD result;
  762. DWORD memDbValue;
  763. if (EnumFirstImport16 (ModuleImage, &e)) {
  764. do {
  765. if (e.ImportModule [0] != 0) {
  766. result = pCheckDependency16 (CurrentPaths, e.ImportModule);
  767. if (result == MODULESTATUS_BAD) {
  768. LOG((
  769. LOG_WARNING,
  770. "%s will be incompatible because %s is incompatible",
  771. ModuleName,
  772. e.ImportModule));
  773. return result;
  774. }
  775. if (result == MODULESTATUS_NT_MODULE) {
  776. if (e.ImportFunctionOrd) {
  777. //import by ordinal
  778. wsprintf (g_TempKey, "%s\\%s\\%lu", MEMDB_CATEGORY_WIN9X_APIS, e.ImportModule, e.ImportFunctionOrd);
  779. if (MemDbGetValue (g_TempKey, NULL)) {
  780. LOG((
  781. LOG_WARNING,
  782. "%s will be incompatible because export index %lu will point to a different export in %s",
  783. ModuleName,
  784. e.ImportFunctionOrd,
  785. e.ImportModule));
  786. return MODULESTATUS_BAD;
  787. }
  788. }
  789. else {
  790. //import by name
  791. MemDbBuildKey (g_TempKey, MEMDB_CATEGORY_WIN9X_APIS, e.ImportModule, e.ImportFunction, NULL);
  792. if (MemDbGetValue (g_TempKey, &memDbValue)) {
  793. LOG((
  794. LOG_WARNING,
  795. "%s will be incompatible because %s export will not be available in %s",
  796. ModuleName,
  797. e.ImportFunction,
  798. e.ImportModule));
  799. return MODULESTATUS_BAD;
  800. }
  801. }
  802. }
  803. }
  804. }
  805. while (EnumNextImport16 (&e));
  806. }
  807. return MODULESTATUS_CHECKED;
  808. }
  809. DWORD
  810. pCheckModule (
  811. IN PCSTR ModuleName,
  812. IN PCSTR AppPaths OPTIONAL
  813. )
  814. {
  815. MODULE_IMAGE moduleImage;
  816. DWORD result = MODULESTATUS_CHECKED;
  817. PTSTR CurrentPaths = NULL;
  818. __try {
  819. if (!LoadModuleData (ModuleName, &moduleImage)) {
  820. LOG((LOG_WARNING, DBG_MODULES":Cannot load image for %s. Error:%ld", ModuleName, GetLastError()));
  821. __leave;
  822. }
  823. __try {
  824. CurrentPaths = pBuildModulePaths (ModuleName, AppPaths);
  825. switch (moduleImage.ModuleType) {
  826. case DOS_MODULE:
  827. DEBUGMSG((DBG_MODULES, "Examining %s : DOS module.", ModuleName));
  828. break;
  829. case W16_MODULE:
  830. DEBUGMSG((DBG_MODULES, "Examining %s : W16 module.", ModuleName));
  831. result = pCheckNEModule (CurrentPaths, ModuleName, moduleImage.ModuleData.W16Data.Image);
  832. break;
  833. case W32_MODULE:
  834. DEBUGMSG((DBG_MODULES, "Examining %s : W32 module.", ModuleName));
  835. result = pCheckPEModule (CurrentPaths, &moduleImage.ModuleData.W32Data.Image);
  836. break;
  837. default:
  838. DEBUGMSG((DBG_MODULES, "Examining %s : Unknown module type.", ModuleName));
  839. }
  840. }
  841. __except (EXCEPTION_EXECUTE_HANDLER) {
  842. DWORD rc = _exception_code();
  843. DEBUGMSG((DBG_WARNING, DBG_MODULES":Access violation while checking %s (ec=%#x)", ModuleName, rc));
  844. result = MODULESTATUS_CHECKED;
  845. }
  846. }
  847. __finally {
  848. UnloadModuleData (&moduleImage);
  849. if (CurrentPaths) {
  850. FreeText (CurrentPaths);
  851. }
  852. }
  853. return result;
  854. }
  855. DWORD
  856. GetModuleType (
  857. IN PCSTR ModuleName
  858. )
  859. {
  860. MODULE_IMAGE moduleImage;
  861. DWORD result = UNKNOWN_MODULE;
  862. __try {
  863. if (!LoadModuleData (ModuleName, &moduleImage)) {
  864. LOG((LOG_WARNING, DBG_MODULES":Cannot load image for %s. Error:%ld", ModuleName, GetLastError()));
  865. __leave;
  866. }
  867. result = moduleImage.ModuleType;
  868. }
  869. __finally {
  870. UnloadModuleData (&moduleImage);
  871. }
  872. return result;
  873. }
  874. PCSTR
  875. Get16ModuleDescription (
  876. IN PCSTR ModuleName
  877. )
  878. {
  879. MODULE_IMAGE moduleImage;
  880. PSTR result = NULL;
  881. PDOS_HEADER dosHeader;
  882. PNE_HEADER neHeader;
  883. PBYTE size;
  884. __try {
  885. if (!LoadModuleData (ModuleName, &moduleImage)) {
  886. LOG((LOG_WARNING, DBG_MODULES":Cannot load image for %s. Error:%ld", ModuleName, GetLastError()));
  887. __leave;
  888. }
  889. if (moduleImage.ModuleType != W16_MODULE) {
  890. __leave;
  891. }
  892. __try {
  893. dosHeader = (PDOS_HEADER) (moduleImage.ModuleData.W16Data.Image);
  894. neHeader = (PNE_HEADER) (moduleImage.ModuleData.W16Data.Image + dosHeader->e_lfanew);
  895. size = (PBYTE) (moduleImage.ModuleData.W16Data.Image + neHeader->NonResNameTableOffset);
  896. if (*size == 0) {
  897. __leave;
  898. }
  899. result = AllocPathString (*size + 1);
  900. strncpy (result, moduleImage.ModuleData.W16Data.Image + neHeader->NonResNameTableOffset + 1, *size);
  901. result [*size] = 0;
  902. }
  903. __except (1) {
  904. DEBUGMSG((DBG_WARNING, DBG_MODULES":Access violation while examining %s.", ModuleName));
  905. if (result != NULL) {
  906. FreePathString (result);
  907. result = NULL;
  908. }
  909. __leave;
  910. }
  911. }
  912. __finally {
  913. UnloadModuleData (&moduleImage);
  914. }
  915. return result;
  916. }
  917. PIMAGE_NT_HEADERS
  918. pGetImageNtHeader (
  919. IN PVOID Base
  920. )
  921. /*++
  922. Routine Description:
  923. This function returns the address of the NT Header.
  924. Arguments:
  925. Base - Supplies the base of the image.
  926. Return Value:
  927. Returns the address of the NT Header.
  928. --*/
  929. {
  930. PIMAGE_NT_HEADERS NtHeaders;
  931. if (Base != NULL && Base != (PVOID)-1) {
  932. if (((PIMAGE_DOS_HEADER)Base)->e_magic == IMAGE_DOS_SIGNATURE) {
  933. NtHeaders = (PIMAGE_NT_HEADERS)((PCHAR)Base + ((PIMAGE_DOS_HEADER)Base)->e_lfanew);
  934. if (NtHeaders->Signature == IMAGE_NT_SIGNATURE) {
  935. return NtHeaders;
  936. }
  937. }
  938. }
  939. return NULL;
  940. }
  941. ULONG
  942. GetPECheckSum (
  943. IN PCSTR ModuleName
  944. )
  945. {
  946. MODULE_IMAGE moduleImage;
  947. ULONG result = 0;
  948. PIMAGE_NT_HEADERS NtHeaders;
  949. __try {
  950. if (!LoadModuleData (ModuleName, &moduleImage)) {
  951. LOG((LOG_WARNING, DBG_MODULES":Cannot load image for %s. Error:%ld", ModuleName, GetLastError()));
  952. __leave;
  953. }
  954. if (moduleImage.ModuleType != W32_MODULE) {
  955. __leave;
  956. }
  957. __try {
  958. NtHeaders = pGetImageNtHeader(moduleImage.ModuleData.W32Data.Image.MappedAddress);
  959. if (NtHeaders) {
  960. if (NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
  961. result = ((PIMAGE_NT_HEADERS32)NtHeaders)->OptionalHeader.CheckSum;
  962. } else
  963. if (NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
  964. result = ((PIMAGE_NT_HEADERS64)NtHeaders)->OptionalHeader.CheckSum;
  965. }
  966. }
  967. }
  968. __except (1) {
  969. DEBUGMSG((DBG_WARNING, DBG_MODULES":Access violation while examining %s.", ModuleName));
  970. result = 0;
  971. __leave;
  972. }
  973. }
  974. __finally {
  975. UnloadModuleData (&moduleImage);
  976. }
  977. return result;
  978. }
  979. DWORD
  980. CheckModule (
  981. IN PCSTR ModuleName,
  982. IN PCSTR AppPaths OPTIONAL
  983. )
  984. {
  985. DWORD result;
  986. DWORD moduleStatus;
  987. MemDbSetValueEx (MEMDB_CATEGORY_MODULE_CHECK, ModuleName, NULL, NULL, MODULESTATUS_CHECKING, NULL);
  988. g_ModuleRecursionLevel++;
  989. if (g_ModuleRecursionLevel < MAX_MODULE_RECURSION_LEVEL) {
  990. result = pCheckModule (ModuleName, AppPaths);
  991. if (result == MODULESTATUS_BAD) {
  992. moduleStatus = GetFileStatusOnNt (ModuleName);
  993. if ((moduleStatus & FILESTATUS_NTINSTALLED) == FILESTATUS_NTINSTALLED) {
  994. MarkFileForDelete (ModuleName);
  995. result = MODULESTATUS_NT_MODULE;
  996. }
  997. }
  998. } else {
  999. result = MODULESTATUS_CHECKED;
  1000. }
  1001. g_ModuleRecursionLevel--;
  1002. MemDbSetValueEx (MEMDB_CATEGORY_MODULE_CHECK, ModuleName, NULL, NULL, result, NULL);
  1003. return result;
  1004. }
  1005. BOOL
  1006. pProcessModules (
  1007. VOID
  1008. )
  1009. {
  1010. MEMDB_ENUM enumItems;
  1011. PSTR pathsPtr;
  1012. DWORD moduleStatus;
  1013. DWORD attrib;
  1014. LONG stringId;
  1015. DWORD status;
  1016. DWORD Count = 0;
  1017. MemDbSetValueEx(MEMDB_CATEGORY_MODULE_CHECK,TEXT("KERNEL32"),NULL,NULL,MODULESTATUS_NT_MODULE,NULL);
  1018. MemDbSetValueEx(MEMDB_CATEGORY_MODULE_CHECK,TEXT("KERNEL" ),NULL,NULL,MODULESTATUS_NT_MODULE,NULL);
  1019. MemDbSetValueEx(MEMDB_CATEGORY_MODULE_CHECK,TEXT("USER32" ),NULL,NULL,MODULESTATUS_NT_MODULE,NULL);
  1020. MemDbSetValueEx(MEMDB_CATEGORY_MODULE_CHECK,TEXT("USER" ),NULL,NULL,MODULESTATUS_NT_MODULE,NULL);
  1021. MemDbSetValueEx(MEMDB_CATEGORY_MODULE_CHECK,TEXT("GDI32" ),NULL,NULL,MODULESTATUS_NT_MODULE,NULL);
  1022. MemDbSetValueEx(MEMDB_CATEGORY_MODULE_CHECK,TEXT("GDI" ),NULL,NULL,MODULESTATUS_NT_MODULE,NULL);
  1023. MemDbSetValueEx(MEMDB_CATEGORY_MODULE_CHECK,TEXT("SHELL32" ),NULL,NULL,MODULESTATUS_NT_MODULE,NULL);
  1024. MemDbSetValueEx(MEMDB_CATEGORY_MODULE_CHECK,TEXT("SHELL" ),NULL,NULL,MODULESTATUS_NT_MODULE,NULL);
  1025. MemDbSetValueEx(MEMDB_CATEGORY_MODULE_CHECK,TEXT("SOUND32" ),NULL,NULL,MODULESTATUS_NT_MODULE,NULL);
  1026. MemDbSetValueEx(MEMDB_CATEGORY_MODULE_CHECK,TEXT("SOUND" ),NULL,NULL,MODULESTATUS_NT_MODULE,NULL);
  1027. MemDbSetValueEx(MEMDB_CATEGORY_MODULE_CHECK,TEXT("DISPLAY" ),NULL,NULL,MODULESTATUS_NT_MODULE,NULL);
  1028. MemDbSetValueEx(MEMDB_CATEGORY_MODULE_CHECK,TEXT("KEYBOARD"),NULL,NULL,MODULESTATUS_NT_MODULE,NULL);
  1029. MemDbBuildKey (g_TempKey, MEMDB_CATEGORY_MODULE_CHECK, TEXT("*"), NULL, NULL);
  1030. if (MemDbEnumFirstValue (&enumItems, g_TempKey, MEMDB_ALL_SUBLEVELS, MEMDB_ENDPOINTS_ONLY)) {
  1031. do {
  1032. if (CANCELLED()) {
  1033. SetLastError (ERROR_CANCELLED);
  1034. return FALSE;
  1035. }
  1036. #ifdef DEBUG
  1037. {
  1038. CHAR DbgBuf[256];
  1039. if (GetPrivateProfileString ("MigDb", GetFileNameFromPath (enumItems.szName), "", DbgBuf, 256, g_DebugInfPath)) {
  1040. DEBUGMSG((DBG_NAUSEA, "Debug point hit in Modules.c"));
  1041. }
  1042. }
  1043. #endif
  1044. if (enumItems.dwValue == MODULESTATUS_UNCHECKED) {
  1045. moduleStatus = GetFileStatusOnNt (enumItems.szName);
  1046. if ((moduleStatus & FILESTATUS_DELETED) == FILESTATUS_DELETED) {
  1047. continue;
  1048. }
  1049. if ((moduleStatus & FILESTATUS_REPLACED) == FILESTATUS_REPLACED) {
  1050. continue;
  1051. }
  1052. g_ModuleRecursionLevel = 0;
  1053. moduleStatus = CheckModule (enumItems.szName, NULL);
  1054. if (moduleStatus == MODULESTATUS_BAD) {
  1055. status = GetFileStatusOnNt (enumItems.szName);
  1056. if (!(status & FILESTATUS_DELETED)) {
  1057. RemoveOperationsFromPath (enumItems.szName, ALL_CHANGE_OPERATIONS);
  1058. MarkFileForExternalDelete (enumItems.szName);
  1059. }
  1060. if (!IsFileMarkedForAnnounce (enumItems.szName)) {
  1061. AnnounceFileInReport (enumItems.szName, 0, ACT_INC_NOBADAPPS);
  1062. }
  1063. LOG ((LOG_INFORMATION, (PCSTR)MSG_MODULE_REQUIRES_EXPORT_LOG, enumItems.szName));
  1064. }
  1065. }
  1066. Count++;
  1067. if (!(Count % 4)) {
  1068. TickProgressBar ();
  1069. }
  1070. }
  1071. while (MemDbEnumNextValue (&enumItems));
  1072. }
  1073. DEBUGMSG((DBG_MODULES, "Modules checking : ==========================="));
  1074. DEBUGMSG((DBG_MODULES, "Number of executables checked : %ld", g_NumEXEs));
  1075. DEBUGMSG((DBG_MODULES, "Number of modules in MEMDB tree: %ld", Count));
  1076. MemDbDeleteTree (MEMDB_CATEGORY_MODULE_CHECK);
  1077. return TRUE;
  1078. }
  1079. DWORD
  1080. ProcessModules (
  1081. IN DWORD Request
  1082. )
  1083. {
  1084. switch (Request) {
  1085. case REQUEST_QUERYTICKS:
  1086. return TICKS_PROCESS_MODULES;
  1087. case REQUEST_RUN:
  1088. if (!pProcessModules ()) {
  1089. return GetLastError ();
  1090. }
  1091. else {
  1092. return ERROR_SUCCESS;
  1093. }
  1094. default:
  1095. DEBUGMSG ((DBG_ERROR, "Bad parameter in ProcessModules"));
  1096. }
  1097. return 0;
  1098. }
  1099. BOOL
  1100. pPrepareProcessModules (
  1101. VOID
  1102. )
  1103. {
  1104. PCTSTR TempStr;
  1105. TempStr = JoinPaths (g_UpgradeSources, S_E95ONLY_DAT);
  1106. MemDbImport (TempStr);
  1107. FreePathString (TempStr);
  1108. return TRUE;
  1109. }
  1110. DWORD
  1111. PrepareProcessModules (
  1112. IN DWORD Request
  1113. )
  1114. {
  1115. switch (Request) {
  1116. case REQUEST_QUERYTICKS:
  1117. return TICKS_PREPARE_PROCESS_MODULES;
  1118. case REQUEST_RUN:
  1119. if (!pPrepareProcessModules ()) {
  1120. return GetLastError ();
  1121. }
  1122. else {
  1123. return ERROR_SUCCESS;
  1124. }
  1125. default:
  1126. DEBUGMSG ((DBG_ERROR, "Bad parameter in PrepareProcessModules"));
  1127. }
  1128. return 0;
  1129. }
  1130. BOOL
  1131. SaveExeFiles (
  1132. IN PFILE_HELPER_PARAMS Params
  1133. )
  1134. {
  1135. if (Params->Handled) {
  1136. return TRUE;
  1137. }
  1138. // Save EXE and SCR files to MemDB to enumerate later
  1139. if ((StringIMatch (Params->Extension, TEXT(".EXE"))) ||
  1140. (StringIMatch (Params->Extension, TEXT(".SCR")))
  1141. ) {
  1142. if (!IsFileMarkedAsKnownGood (Params->FullFileSpec)) {
  1143. MemDbSetValueEx (
  1144. MEMDB_CATEGORY_MODULE_CHECK,
  1145. Params->FullFileSpec,
  1146. NULL,
  1147. NULL,
  1148. MODULESTATUS_UNCHECKED,
  1149. NULL);
  1150. #ifdef DEBUG
  1151. g_NumEXEs++;
  1152. #endif
  1153. }
  1154. }
  1155. return TRUE;
  1156. }