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.

189 lines
6.1 KiB

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