/***********************************************************************/ /* Copyright (C) 2002 Definitive Solutions, Inc. All Rights Reserved. */ /* THIS COMPUTER PROGRAM IS PROPRIETARY AND CONFIDENTIAL TO DEFINITIVE */ /* SOLUTIONS, INC. AND ITS LICENSORS AND CONTAINS TRADE SECRETS OF */ /* DEFINITIVE SOLUTIONS, INC. THAT ARE PROVIDED PURSUANT TO A WRITTEN */ /* AGREEMENT CONTAINING RESTRICTIONS ON USE AND DISCLOSURE. ANY USE, */ /* REPRODUCTION, OR TRANSFER EXCEPT AS PROVIDED IN SUCH AGREEMENT */ /* IS STRICTLY PROHIBITED. */ /***********************************************************************/ ///////////////////////////////////////////////////////////////////////////// // Virtually all of this code is from Pietrek; all I did was add a wraper and // consolidate it all into one H and one CPP file. Did a little stylistic // cleanup and error checking, too. // // WARNING: There are some hidden functions in the derived classes. Also // much of ain't const-correct. This is not a great example of // how to write C++ code. ///////////////////////////////////////////////////////////////////////////// /* Class Hierarchy Chart --------------------- MemoryMappedFile ModuleDependencyList ModuleFileInfo | ExeFile | PeExe */ //========================================== // Matt Pietrek // Microsoft Systems Journal, Feb 1997 // FILE: MODULEFILEINFO.H //========================================== ///////////////////////////////////////////////////////////////////////////// // How to add this class to your application. // // Add MyDepends.cpp and MyDepends.h to your project in the usual folders. ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // How to use this class: // // MyDepends md; // VERIFY(SUCCEEDED(md.Initialize())); // md.LogAllDepends(); // ///////////////////////////////////////////////////////////////////////////// #if !defined(MYDEPENDSH_7442EA55_20D6_47fe_AF8C_C4A27000C2E3_INCLUDED_) #define MYDEPENDSH_7442EA55_20D6_47fe_AF8C_C4A27000C2E3_INCLUDED_ #pragma once ///////////////////////////////////////////////////////////////////////////// // Forward declarations. class ModuleDependencyList; class ModuleFileInfo; typedef ModuleFileInfo * PMODULE_FILE_INFO; ///////////////////////////////////////////////////////////////////////////// // MyDepends // Declare the class depending on this file is in an EXE project or a DLL one. class #ifdef _WINDLL AFX_EXT_CLASS #endif MyDepends : public CObject { // Construction. public: MyDepends(); virtual ~MyDepends(); // Operations. public: HRESULT Initialize(const CString sFullPath = ""); HRESULT LogAllDepends() const; // Implementation. private: void DisplayFileInformation(PMODULE_FILE_INFO pModInfo) const; BOOL GetFileDateAsString(LPFILETIME pFt, char * pszDate, unsigned cbIn) const; BOOL GetFileTimeAsString(LPFILETIME pFt, char * pszTime, unsigned cbIn, BOOL fSeconds) const; void TimeDateStampToFileTime(DWORD timeDateStamp, LPFILETIME pFileTime) const; void ShowVersionInfo(PSTR pszFileName) const; // Data. private: ModuleDependencyList* m_pmdl; // The list of DLLs. }; //========================================== // Matt Pietrek // Microsoft Systems Journal, Feb 1997 // FILE: MODULEFILEINFO.H //========================================== ///////////////////////////////////////////////////////////////////////////// // The ModuleDependencyList class creates a linked list of ModuleFileInfo // structures. In theory, this list will represent every executable file // loaded by the Win32 loader when the executable is loaded. The class creates // the list by starting with the file passed to the constructor, and recursing // through all the import tables. class ModuleDependencyList { // Construction. public: ModuleDependencyList(PSTR pszFileName); ~ModuleDependencyList(); enum errMDL { errMDL_NO_ERROR, errMDL_FILE_NOT_FOUND, errMDL_NOT_PE_FILE, errMDL_GENERAL_FAILURE }; // Interface. public: errMDL GetErrorType() const; BOOL IsValid() const; PSTR GetErrorString() const; PMODULE_FILE_INFO GetNextModule(PMODULE_FILE_INFO p); PMODULE_FILE_INFO LookupModule(PSTR pszFileName, BOOL fFullName); unsigned GetNumberOfModules() const; // Implementation. private: errMDL AddModule(PSTR pszFullName); // Data. private: unsigned m_cModules; // Number of modules in list. PMODULE_FILE_INFO m_pList; // Pointer to head of linked list. errMDL m_errMDL; // Error type. }; ///////////////////////////////////////////////////////////////////////////// // This structure represents one executable file in a module dependency list. // Both the base filename and the complete path are stored. class ModuleFileInfo { friend class ModuleDependencyList; // Construction. public: ModuleFileInfo(PSTR pszFileName); ~ModuleFileInfo(); // Interface. public: PSTR GetBaseName(); PSTR GetFullName(); PMODULE_FILE_INFO GetNextNotFoundModule(PMODULE_FILE_INFO p); // Implmentation. private: void AddNotFoundModule(PSTR pszFileName); // Data. private: PMODULE_FILE_INFO m_pNext; PMODULE_FILE_INFO m_pNotFoundNext; char m_szBaseName[MAX_PATH + 1]; char m_szFullName[MAX_PATH + 1]; }; ///////////////////////////////////////////////////////////////////////////// // MemoryMappedFile class MemoryMappedFile { // Construction. public: MemoryMappedFile(PSTR pszFileName); ~MemoryMappedFile(); // Interface. public: enum errMMF { errMMF_NoError, errMMF_FileOpen, errMMF_FileMapping, errMMF_MapView }; PVOID GetBase(); DWORD GetFileSize(); BOOL IsValid(); errMMF GetErrorType(); // Data. protected: errMMF m_errMMF; // Data. private: HANDLE m_hFile; HANDLE m_hFileMapping; // Handle of memory mapped file. PVOID m_pMemoryMappedFileBase; DWORD m_cbFile; }; ///////////////////////////////////////////////////////////////////////////// // ExeFile class ExeFile : public MemoryMappedFile { // Construction. public: ExeFile(PSTR pszFileName); ~ExeFile(); // Interface. public: enum ExeType { exeType_Invalid, exeType_DOS, exeType_NE, exeType_VXD, exeType_LX, exeType_PE }; enum errEF { errEXE_FILE_NO_ERROR, errEXE_FILE_FILE_NOT_FOUND, errEXE_FILE_INVALID_FORMAT }; BOOL IsValid(); errEF GetErrorType(); DWORD GetSecondaryHeaderOffset(); ExeType GetExeType(); PSTR GetFileTypeDescription(); // Data. protected: errEF m_errEF; // Data. private: LONG m_secondaryHeaderOffset; ExeType m_exeType; }; ///////////////////////////////////////////////////////////////////////////// // PeExe class PeExe : public ExeFile { // Construction. public: PeExe(PSTR pszFileName); ~PeExe(); // Interface. public: bool IsValid() { return NULL != m_pNtHdr; } // For those who want at the data directly. PIMAGE_NT_HEADERS GetIMAGE_NT_HEADERS() { return m_pNtHdr; } // IMAGE_FILE_HEADER fields WORD GetMachine() { return m_pNtHdr->FileHeader.Machine; } WORD GetNumberOfSections() { return m_pNtHdr->FileHeader.NumberOfSections; } DWORD GetTimeDateStamp() { return m_pNtHdr->FileHeader.TimeDateStamp; } DWORD GetCharacteristics() { return m_pNtHdr->FileHeader.Characteristics; } // IMAGE_OPTIONAL_HEADER fields. DWORD GetSizeOfCode() { return m_pNtHdr->OptionalHeader.SizeOfCode; } DWORD GetSizeOfInitializedData() { return m_pNtHdr->OptionalHeader.SizeOfInitializedData; } DWORD GetSizeOfUninitializedData() { return m_pNtHdr->OptionalHeader.SizeOfUninitializedData; } DWORD GetAddressOfEntryPoint() { return m_pNtHdr->OptionalHeader.AddressOfEntryPoint; } DWORD GetBaseOfCode() { return m_pNtHdr->OptionalHeader.BaseOfCode; } DWORD GetBaseOfData() { return m_pNtHdr->OptionalHeader.BaseOfData; } DWORD GetImageBase() { return m_pNtHdr->OptionalHeader.ImageBase; } DWORD GetSectionAlignment() { return m_pNtHdr->OptionalHeader.SectionAlignment; } DWORD GetFileAlignment() { return m_pNtHdr->OptionalHeader.FileAlignment; } WORD GetMajorOperatingSystemVersion() { return m_pNtHdr->OptionalHeader.MajorOperatingSystemVersion; } WORD GetMinorOperatingSystemVersion() { return m_pNtHdr->OptionalHeader.MinorOperatingSystemVersion; } WORD GetMajorImageVersion() { return m_pNtHdr->OptionalHeader.MajorImageVersion; } WORD GetMinorImageVersion() { return m_pNtHdr->OptionalHeader.MinorImageVersion; } WORD GetMajorSubsystemVersion() { return m_pNtHdr->OptionalHeader.MajorSubsystemVersion; } WORD GetMinorSubsystemVersion() { return m_pNtHdr->OptionalHeader.MinorSubsystemVersion; } DWORD GetSizeOfImage() { return m_pNtHdr->OptionalHeader.SizeOfImage; } DWORD GetSizeOfHeaders() { return m_pNtHdr->OptionalHeader.SizeOfHeaders; } WORD GetSubsystem() { return m_pNtHdr->OptionalHeader.Subsystem; } DWORD GetSizeOfStackReserve() { return m_pNtHdr->OptionalHeader.SizeOfStackReserve; } DWORD GetSizeOfStackCommit() { return m_pNtHdr->OptionalHeader.SizeOfStackCommit; } DWORD GetSizeOfHeapReserve() { return m_pNtHdr->OptionalHeader.SizeOfHeapReserve; } DWORD GetSizeOfHeapCommit() { return m_pNtHdr->OptionalHeader.SizeOfHeapCommit; } DWORD GetDataDirectoryEntryRVA(DWORD id); PVOID GetDataDirectoryEntryPointer(DWORD id); DWORD GetDataDirectoryEntrySize(DWORD id); PVOID GetReadablePointerFromRVA(DWORD rva); // Implementation. private: DWORD RVAToFileOffset(DWORD rva); // Data. private: PIMAGE_NT_HEADERS m_pNtHdr; }; #endif // MYDEPENDSH_7442EA55_20D6_47fe_AF8C_C4A27000C2E3_INCLUDED_