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.

194 lines
6.2 KiB

  1. #include "main.h"
  2. #define MI_MODULE 0
  3. #define MI_DUPLICATE 1
  4. #define MI_EXPORT_ERROR 2
  5. #define MI_DUPLICATE_EXPORT_ERROR 3
  6. #define MI_NOT_FOUND 4
  7. #define MI_ERROR 5
  8. #define FI_IMPORT 0
  9. #define FI_IMPORT_ERROR 1
  10. #define FI_EXPORT 2
  11. #define FI_EXPORT_FORWARD 3
  12. VOID DoKoolShit(LPCTSTR Filename);
  13. LPWSTR MakeWideStrFromAnsi(LPSTR psz);
  14. //******************************************************************************
  15. //***** CFunction
  16. //******************************************************************************
  17. class CFunction {
  18. public:
  19. CFunction *m_pNext;
  20. int m_ordinal;
  21. int m_hint;
  22. DWORD_PTR m_dwAddress;
  23. DWORD_PTR m_dwExtra;
  24. CHAR m_szName[1];
  25. // The m_dwExtra field's purpose is dependent on whether the CFunction
  26. // object is an export or an import. For imports, it is a pointer to the
  27. // associated export in the child module. If the import was not resolved,
  28. // then this value will be NULL. For exports, the m_dwExtra field is a
  29. // pointer to a forward string. If the export has no forward string, then
  30. // this member will be NULL.
  31. inline CFunction* GetAssociatedExport() { return (CFunction*)m_dwExtra; }
  32. inline LPCSTR GetForwardString() { return (LPCSTR)m_dwExtra; }
  33. };
  34. //******************************************************************************
  35. //***** CModuleData
  36. //******************************************************************************
  37. // Every CModule object points to a CModuleData object. There is a single
  38. // CModuleData for every unique module we process. If a module is duplicated in
  39. // in our tree, there will be a CModule object for each instance, but they will
  40. // all point to the same CModuleData object. For each unique module, a CModule
  41. // object and a CModuleData object are created and the module is opened and
  42. // processed. For every duplicate module, just a CModule object is created and
  43. // pointed to the existing CModuleData. Duplicate modules are never opened since
  44. // all the data that would be achieved by processing the file are already stored
  45. // in the CModuleData.
  46. class CModuleData {
  47. public:
  48. // Flag to determine if this module has been processed yet.
  49. BOOL m_fProcessed;
  50. // Filled in by GetFileInfo()
  51. DWORD m_dwTimeStamp;
  52. DWORD m_dwSize;
  53. DWORD m_dwAttributes;
  54. // Filled in by GetModuleInfo()
  55. DWORD m_dwMachine;
  56. DWORD m_dwSubsystem;
  57. DWORD_PTR m_dwBaseAddress;
  58. DWORD m_dwImageVersion;
  59. DWORD m_dwLinkerVersion;
  60. DWORD m_dwOSVersion;
  61. DWORD m_dwSubsystemVersion;
  62. // Filled in by GetVersionInfo()
  63. DWORD m_dwFileVersionMS;
  64. DWORD m_dwFileVersionLS;
  65. DWORD m_dwProductVersionMS;
  66. DWORD m_dwProductVersionLS;
  67. // Build by BuildExports()
  68. CFunction *m_pExports;
  69. // Filled in by CheckForDebugInfo()
  70. BOOL m_fDebug;
  71. // Allocated and filled in by SetModuleError() if an error occurs.
  72. LPSTR m_pszError;
  73. BOOL m_fFileNotFound;
  74. // Allocated and filled in by CreateModule()
  75. LPSTR m_szFile;
  76. CHAR m_szPath[1];
  77. };
  78. //******************************************************************************
  79. //***** CModule
  80. //******************************************************************************
  81. class CModule {
  82. public:
  83. // Our next sibling module.
  84. CModule *m_pNext;
  85. // Head pointer to a list of dependent modules.
  86. CModule *m_pDependents;
  87. // Head pointer to a list of functions that our parent module imports from us.
  88. CFunction *m_pParentImports;
  89. // If we are a duplicate, then this will point to the original CModule.
  90. CModule *m_pModuleOriginal;
  91. // Depth of this module in our tree. Used to catch circular dependencies.
  92. int m_depth;
  93. // Set if any of our parent's imports can't be matched to one of our exports.
  94. BOOL m_fExportError;
  95. // Set if this module was included in the tree because of a forward call.
  96. BOOL m_fForward;
  97. // Set if this module was included via Delay Load import.
  98. BOOL m_fDelayLoad;
  99. // Pointer to the bulk of our module's processed information.
  100. CModuleData *m_pData;
  101. inline int GetImage() {
  102. return ((m_pData->m_fFileNotFound) ? MI_NOT_FOUND :
  103. (m_pData->m_pszError) ? MI_ERROR :
  104. (m_pModuleOriginal && m_fExportError) ? MI_DUPLICATE_EXPORT_ERROR :
  105. (m_fExportError) ? MI_EXPORT_ERROR :
  106. (m_pModuleOriginal) ? MI_DUPLICATE : MI_MODULE);
  107. }
  108. };
  109. class CDepends {
  110. // Internal variables
  111. protected:
  112. // The following 5 members contain information about the currently opened
  113. // module file. We can store them here in our document since there is never
  114. // a time when two files are open at once.
  115. HANDLE m_hFile;
  116. LPVOID m_lpvFile;
  117. PIMAGE_FILE_HEADER m_pIFH;
  118. PIMAGE_OPTIONAL_HEADER m_pIOH;
  119. PIMAGE_SECTION_HEADER m_pISH;
  120. DWORD m_dwMachineType;
  121. // Public variables
  122. public:
  123. CModule *m_pModuleRoot;
  124. BOOL m_fOutOfMemory;
  125. BOOL m_fCircularError;
  126. BOOL m_fMixedMachineError;
  127. int m_cxOrdinal;
  128. int m_cxHint;
  129. int m_cImports;
  130. int m_cExports;
  131. // Public Functions
  132. public:
  133. CDepends();
  134. virtual ~CDepends();
  135. BOOL SetInitialFilename(LPCSTR lpszPathName);
  136. CModule* LoopThruAndPrintLosers(CModule *pModuleCur);
  137. void DeleteContents();
  138. // Internal functions
  139. protected:
  140. CFunction* CreateFunction(int ordinal, int hint, LPCSTR szName, DWORD_PTR dwAddress, LPCSTR szForward = NULL);
  141. CModule* CreateModule(LPCSTR szPath, int depth);
  142. void DeleteModule(CModule *pModule);
  143. CModule* FindModule(CModule *pModuleCur, LPCSTR szPath);
  144. void SetModuleError(CModule *pModule, LPCTSTR szFormat, ...);
  145. BOOL VerifyModule(CModule *pModule);
  146. BOOL GetModuleInfo(CModule *pModule);
  147. BOOL BuildImports(CModule *pModule);
  148. BOOL BuildDelayImports(CModule *pModule);
  149. BOOL WalkIAT(PIMAGE_THUNK_DATA pITDF, PIMAGE_THUNK_DATA pITDA, CModule *pModule, DWORD_PTR dwBase);
  150. BOOL BuildExports(CModule *pModule);
  151. BOOL VerifyParentImports(CModule *pModule);
  152. BOOL ProcessModule(CModule *pModule);
  153. };