msvc64: adding tools/depends directory and code.
parent
7dd72b33b5
commit
5ead8bdf11
Binary file not shown.
@ -0,0 +1,13 @@
|
||||
Depends/ReadMe.txt
|
||||
------------------
|
||||
|
||||
This project is "depends" and is code from MSJ (now MSDN) in 1997. I appreciate and respect the code provided by Matt Pietrik. I have made the following changes:
|
||||
1) Added the -q option
|
||||
2) Added the MSVC build environment (for 32bit and 64bit builds)
|
||||
3) Modified the default response to report 1 and 2.
|
||||
|
||||
The projects builds depends32.exe and depends64.exe which are used by runner32.bat and runner64.bat to test dependancies post build.
|
||||
|
||||
Robin Mills
|
||||
http://clanmills.com
|
||||
2011-01-02
|
@ -0,0 +1,12 @@
|
||||
// Depends2.cpp : Defines the entry point for the console application.
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
|
||||
int main(int argc, char argv[])
|
||||
{
|
||||
printf("hello world\n") ;
|
||||
return 0;
|
||||
}
|
||||
|
@ -0,0 +1,25 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual Studio 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "depends", "depends.vcproj", "{E24D66E3-65A9-4BEB-8579-039AD77C2EFF}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{E24D66E3-65A9-4BEB-8579-039AD77C2EFF}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{E24D66E3-65A9-4BEB-8579-039AD77C2EFF}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{E24D66E3-65A9-4BEB-8579-039AD77C2EFF}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{E24D66E3-65A9-4BEB-8579-039AD77C2EFF}.Debug|x64.Build.0 = Debug|x64
|
||||
{E24D66E3-65A9-4BEB-8579-039AD77C2EFF}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{E24D66E3-65A9-4BEB-8579-039AD77C2EFF}.Release|Win32.Build.0 = Release|Win32
|
||||
{E24D66E3-65A9-4BEB-8579-039AD77C2EFF}.Release|x64.ActiveCfg = Release|x64
|
||||
{E24D66E3-65A9-4BEB-8579-039AD77C2EFF}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@ -0,0 +1,411 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="depends"
|
||||
ProjectGUID="{E24D66E3-65A9-4BEB-8579-039AD77C2EFF}"
|
||||
RootNamespace="depends"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)\"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="version.lib"
|
||||
OutputFile="$(OutDir)\$(ProjectName)32.exe"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)\"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="0"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories="include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="version.lib"
|
||||
OutputFile="$(OutDir)\$(ProjectName)32.exe"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)\"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="version.lib"
|
||||
OutputFile="$(OutDir)\$(ProjectName)64.exe"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)\"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="0"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories="include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="version.lib"
|
||||
OutputFile="$(OutDir)\$(ProjectName)64.exe"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath="src\DEPENDENCYLIST.CPP"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="src\depends.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="src\EXEFILE.CPP"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="src\MEMORYMAPPEDFILE.CPP"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="src\modulefileinfo.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="src\PEEXE.CPP"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath="include\DEPENDENCYLIST.H"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="include\EXEFILE.H"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="include\MEMORYMAPPEDFILE.H"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="include\modulefileinfo.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="include\PEEXE.H"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\targetver.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\ReadMe.txt"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
@ -0,0 +1,57 @@
|
||||
//==========================================
|
||||
// Matt Pietrek
|
||||
// Microsoft Systems Journal, Feb 1997
|
||||
// FILE: DEPENDENCYLIST.H
|
||||
//==========================================
|
||||
#ifndef __DEPLIST_H__
|
||||
#define __DEPLIST_H__
|
||||
|
||||
#ifndef __MODULEFILEINFO_H__
|
||||
#include "modulefileinfo.h"
|
||||
#endif
|
||||
|
||||
enum errModuleDependencyList { errMDL_NO_ERROR,
|
||||
errMDL_FILE_NOT_FOUND,
|
||||
errMDL_NOT_PE_FILE,
|
||||
errMDL_GENERAL_FAILURE };
|
||||
|
||||
//
|
||||
// The MODULE_DEPENDENCY_LIST class creates a linked list of MODULE_FILE_INFO
|
||||
// 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 MODULE_DEPENDENCY_LIST
|
||||
{
|
||||
public:
|
||||
|
||||
MODULE_DEPENDENCY_LIST( PSTR pszFileName );
|
||||
|
||||
~MODULE_DEPENDENCY_LIST( );
|
||||
|
||||
BOOL IsValid( void ){ return (BOOL)(m_errorType == errMDL_NO_ERROR); }
|
||||
|
||||
errModuleDependencyList GetErrorType( void ){ return m_errorType; }
|
||||
|
||||
PSTR GetErrorString( void );
|
||||
|
||||
PMODULE_FILE_INFO GetNextModule( PMODULE_FILE_INFO p );
|
||||
|
||||
PMODULE_FILE_INFO LookupModule( PSTR pszFileName, BOOL fFullName );
|
||||
|
||||
unsigned GetNumberOfModules( void ){ return m_cModules; }
|
||||
|
||||
protected:
|
||||
|
||||
unsigned m_cModules; // Number of modules in list
|
||||
|
||||
PMODULE_FILE_INFO m_pList; // Pointer to head of linked list
|
||||
|
||||
// Recursively adds modules to the list
|
||||
errModuleDependencyList AddModule( PSTR pszFullName );
|
||||
|
||||
errModuleDependencyList m_errorType; // Error type
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,54 @@
|
||||
//==========================================
|
||||
// Matt Pietrek
|
||||
// Microsoft Systems Journal, Feb 1997
|
||||
// FILE: EXEFILE.H
|
||||
//==========================================
|
||||
#ifndef __EXEFILE_H__
|
||||
#define __EXEFILE_H__
|
||||
|
||||
#ifndef __MEMMAPFL_H__
|
||||
#include "memorymappedfile.h"
|
||||
#endif
|
||||
|
||||
// MakePtr is a macro that allows you to easily add to values (including
|
||||
// pointers) together without dealing with C's pointer arithmetic. It
|
||||
// essentially treats the last two parameters as DWORDs. The first
|
||||
// parameter is used to typecast the result to the appropriate pointer type.
|
||||
#define MakePtr( cast, ptr, addValue ) (cast)( (DWORD)(ptr) + (DWORD)(addValue))
|
||||
|
||||
enum EXE_TYPE { exeType_Invalid, exeType_DOS, exeType_NE, exeType_VXD,
|
||||
exeType_LX, exeType_PE };
|
||||
|
||||
enum errEXE_FILE { errEXE_FILE_NO_ERROR,
|
||||
errEXE_FILE_FILE_NOT_FOUND,
|
||||
errEXE_FILE_INVALID_FORMAT };
|
||||
|
||||
class EXE_FILE : public MEMORY_MAPPED_FILE
|
||||
{
|
||||
public:
|
||||
|
||||
EXE_FILE( PSTR pszFileName );
|
||||
~EXE_FILE( ){ ; }
|
||||
|
||||
BOOL IsValid( void ){ return errMMF_NoError == m_errorType; }
|
||||
|
||||
errEXE_FILE GetErrorType( void ){ return m_errorType; }
|
||||
|
||||
DWORD GetSecondaryHeaderOffset( void ){ return m_secondaryHeaderOffset; }
|
||||
|
||||
EXE_TYPE GetExeType( void ){ return m_exeType; }
|
||||
|
||||
PSTR GetFileTypeDescription( void );
|
||||
|
||||
protected:
|
||||
|
||||
errEXE_FILE m_errorType;
|
||||
|
||||
private:
|
||||
|
||||
LONG m_secondaryHeaderOffset;
|
||||
EXE_TYPE m_exeType;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,35 @@
|
||||
//==========================================
|
||||
// Matt Pietrek
|
||||
// Microsoft Systems Journal, Feb 1997
|
||||
// FILE: MEMORYMAPPEDFILE.H
|
||||
//==========================================
|
||||
#ifndef __MEMMAPFL_H__
|
||||
#define __MEMMAPFL_H__
|
||||
|
||||
enum errMMF { errMMF_NoError, errMMF_FileOpen,
|
||||
errMMF_FileMapping, errMMF_MapView };
|
||||
|
||||
class MEMORY_MAPPED_FILE
|
||||
{
|
||||
public:
|
||||
|
||||
MEMORY_MAPPED_FILE( PSTR pszFileName );
|
||||
~MEMORY_MAPPED_FILE(void);
|
||||
|
||||
PVOID GetBase( void ){ return m_pMemoryMappedFileBase; }
|
||||
DWORD GetFileSize( void ){ return m_cbFile; }
|
||||
BOOL IsValid( void ) { return errMMF_NoError == m_errCode; }
|
||||
errMMF GetErrorType(){ return m_errCode; }
|
||||
|
||||
private:
|
||||
|
||||
HANDLE m_hFile;
|
||||
HANDLE m_hFileMapping; // Handle of memory mapped file
|
||||
PVOID m_pMemoryMappedFileBase;
|
||||
DWORD m_cbFile;
|
||||
errMMF m_errCode;
|
||||
};
|
||||
|
||||
typedef MEMORY_MAPPED_FILE *PMEMORY_MAPPED_FILE;
|
||||
|
||||
#endif
|
@ -0,0 +1,98 @@
|
||||
//==========================================
|
||||
// Matt Pietrek
|
||||
// Microsoft Systems Journal, Feb 1997
|
||||
// FILE: PEEXE.H
|
||||
//==========================================
|
||||
#ifndef __PEEXE_H__
|
||||
#define __PEEXE_H__
|
||||
|
||||
#ifndef __EXEFILE_H__
|
||||
#include "exefile.h"
|
||||
#endif
|
||||
|
||||
class PE_EXE : public EXE_FILE
|
||||
{
|
||||
public:
|
||||
|
||||
PE_EXE( PSTR pszFileName );
|
||||
~PE_EXE( ){ }
|
||||
|
||||
BOOL IsValid() { return m_pNtHdr ? TRUE : FALSE; }
|
||||
|
||||
// For those who want at the data directly
|
||||
PIMAGE_NT_HEADERS GetIMAGE_NT_HEADERS( void ) { return m_pNtHdr; }
|
||||
|
||||
// IMAGE_FILE_HEADER fields
|
||||
WORD GetMachine( void )
|
||||
{ return m_pNtHdr->FileHeader.Machine; }
|
||||
WORD GetNumberOfSections( void )
|
||||
{ return m_pNtHdr->FileHeader.NumberOfSections; }
|
||||
DWORD GetTimeDateStamp(void)
|
||||
{ return m_pNtHdr->FileHeader.TimeDateStamp; }
|
||||
DWORD GetCharacteristics( void )
|
||||
{ return m_pNtHdr->FileHeader.Characteristics; }
|
||||
|
||||
// IMAGE_OPTIONAL_HEADER fields
|
||||
DWORD GetSizeOfCode( void )
|
||||
{ return m_pNtHdr->OptionalHeader.SizeOfCode; }
|
||||
DWORD GetSizeOfInitializedData( void )
|
||||
{ return m_pNtHdr->OptionalHeader.SizeOfInitializedData; }
|
||||
DWORD GetSizeOfUninitializedData( void )
|
||||
{ return m_pNtHdr->OptionalHeader.SizeOfUninitializedData; }
|
||||
DWORD GetAddressOfEntryPoint( void )
|
||||
{ return m_pNtHdr->OptionalHeader.AddressOfEntryPoint; }
|
||||
DWORD GetBaseOfCode( void )
|
||||
{ return m_pNtHdr->OptionalHeader.BaseOfCode; }
|
||||
/*
|
||||
DWORD GetBaseOfData( void )
|
||||
{ return m_pNtHdr->OptionalHeader.BaseOfData; }
|
||||
*/
|
||||
DWORD GetImageBase( void )
|
||||
{ return m_pNtHdr->OptionalHeader.ImageBase; }
|
||||
DWORD GetSectionAlignment( void )
|
||||
{ return m_pNtHdr->OptionalHeader.SectionAlignment; }
|
||||
DWORD GetFileAlignment( void )
|
||||
{ return m_pNtHdr->OptionalHeader.FileAlignment; }
|
||||
WORD GetMajorOperatingSystemVersion( void )
|
||||
{ return m_pNtHdr->OptionalHeader.MajorOperatingSystemVersion; }
|
||||
WORD GetMinorOperatingSystemVersion( void )
|
||||
{ return m_pNtHdr->OptionalHeader.MinorOperatingSystemVersion; }
|
||||
WORD GetMajorImageVersion( void )
|
||||
{ return m_pNtHdr->OptionalHeader.MajorImageVersion; }
|
||||
WORD GetMinorImageVersion( void )
|
||||
{ return m_pNtHdr->OptionalHeader.MinorImageVersion; }
|
||||
WORD GetMajorSubsystemVersion( void )
|
||||
{ return m_pNtHdr->OptionalHeader.MajorSubsystemVersion; }
|
||||
WORD GetMinorSubsystemVersion( void )
|
||||
{ return m_pNtHdr->OptionalHeader.MinorSubsystemVersion; }
|
||||
// DWORD GetWin32VersionValue( void )
|
||||
// { return m_pNtHdr->OptionalHeader.Win32VersionValue; }
|
||||
DWORD GetSizeOfImage( void )
|
||||
{ return m_pNtHdr->OptionalHeader.SizeOfImage; }
|
||||
DWORD GetSizeOfHeaders( void )
|
||||
{ return m_pNtHdr->OptionalHeader.SizeOfHeaders; }
|
||||
WORD GetSubsystem( void )
|
||||
{ return m_pNtHdr->OptionalHeader.Subsystem; }
|
||||
DWORD GetSizeOfStackReserve( void )
|
||||
{ return m_pNtHdr->OptionalHeader.SizeOfStackReserve; }
|
||||
DWORD GetSizeOfStackCommit( void )
|
||||
{ return m_pNtHdr->OptionalHeader.SizeOfStackCommit; }
|
||||
DWORD GetSizeOfHeapReserve( void )
|
||||
{ return m_pNtHdr->OptionalHeader.SizeOfHeapReserve; }
|
||||
DWORD GetSizeOfHeapCommit( void )
|
||||
{ return m_pNtHdr->OptionalHeader.SizeOfHeapCommit; }
|
||||
|
||||
DWORD GetDataDirectoryEntryRVA( DWORD id );
|
||||
PVOID GetDataDirectoryEntryPointer( DWORD id );
|
||||
DWORD GetDataDirectoryEntrySize( DWORD id );
|
||||
|
||||
PVOID GetReadablePointerFromRVA( DWORD rva );
|
||||
|
||||
protected:
|
||||
|
||||
DWORD RVAToFileOffset( DWORD rva );
|
||||
|
||||
PIMAGE_NT_HEADERS m_pNtHdr;
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,44 @@
|
||||
//==========================================
|
||||
// Matt Pietrek
|
||||
// Microsoft Systems Journal, Feb 1997
|
||||
// FILE: MODULEFILEINFO.H
|
||||
//==========================================
|
||||
#ifndef __MODULEFILEINFO_H__
|
||||
#define __MODULEFILEINFO_H__
|
||||
|
||||
class MODULE_DEPENDENCY_LIST;
|
||||
|
||||
//
|
||||
// This structure represents one executable file in a module dependency list.
|
||||
// Both the base filename and the complete path are stored.
|
||||
//
|
||||
class MODULE_FILE_INFO
|
||||
{
|
||||
public:
|
||||
|
||||
MODULE_FILE_INFO( PSTR pszFileName );
|
||||
~MODULE_FILE_INFO( void ){}
|
||||
|
||||
PSTR GetBaseName( void ){ return m_szBaseName; }
|
||||
PSTR GetFullName( void ){ return m_szFullName; }
|
||||
|
||||
// For enumerating through the unlocatable imported modules
|
||||
MODULE_FILE_INFO * GetNextNotFoundModule( MODULE_FILE_INFO * );
|
||||
|
||||
private:
|
||||
|
||||
MODULE_FILE_INFO * m_pNext;
|
||||
MODULE_FILE_INFO * m_pNotFoundNext;
|
||||
|
||||
char m_szBaseName[MAX_PATH];
|
||||
char m_szFullName[MAX_PATH];
|
||||
|
||||
// And an unlocatable module to the "not found" list
|
||||
void AddNotFoundModule( PSTR pszFileName );
|
||||
|
||||
friend class MODULE_DEPENDENCY_LIST;
|
||||
};
|
||||
|
||||
typedef MODULE_FILE_INFO * PMODULE_FILE_INFO;
|
||||
|
||||
#endif
|
@ -0,0 +1,187 @@
|
||||
//==========================================
|
||||
// Matt Pietrek
|
||||
// Microsoft Systems Journal, Feb 1997
|
||||
// FILE: DEPENDENCYLIST.CPP
|
||||
//==========================================
|
||||
#include <windows.h>
|
||||
#include <malloc.h>
|
||||
#pragma hdrstop
|
||||
#include "peexe.h"
|
||||
#include "dependencylist.h"
|
||||
|
||||
MODULE_DEPENDENCY_LIST::MODULE_DEPENDENCY_LIST( PSTR pszFileName )
|
||||
{
|
||||
m_errorType = errMDL_GENERAL_FAILURE;
|
||||
m_cModules = 0;
|
||||
m_pList = 0;
|
||||
|
||||
// Make a copy of the path that we can modify to get just the path portion
|
||||
PSTR pszJustPath = _strdup( pszFileName );
|
||||
if ( !pszJustPath )
|
||||
return;
|
||||
|
||||
BOOL fHasPath = FALSE;
|
||||
PSTR pszEnd = strrchr( pszJustPath, '\\' );
|
||||
if ( pszEnd )
|
||||
{
|
||||
*pszEnd = 0; /// Strip off the filename
|
||||
fHasPath = TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// If a path was part of the input filename, save the current directory,
|
||||
// then switch to the new directory.
|
||||
//
|
||||
char szOriginalPath[MAX_PATH];
|
||||
if ( fHasPath )
|
||||
{
|
||||
// This doesn't take into account "App_Paths"!
|
||||
GetCurrentDirectory(MAX_PATH, szOriginalPath); // Save original dir
|
||||
SetCurrentDirectory( pszJustPath ); // Switch to app's dir
|
||||
}
|
||||
|
||||
//
|
||||
// recursively build the module list
|
||||
//
|
||||
m_errorType = AddModule( pszFileName );
|
||||
|
||||
if ( fHasPath ) // Set things back to the way they were
|
||||
SetCurrentDirectory( szOriginalPath );
|
||||
|
||||
free( pszJustPath ); // Free the copy of the path that we allocated
|
||||
}
|
||||
|
||||
|
||||
MODULE_DEPENDENCY_LIST::~MODULE_DEPENDENCY_LIST( )
|
||||
{
|
||||
PMODULE_FILE_INFO pTemp;
|
||||
|
||||
// Delete each MODULE_FILE_INFO structures in the regular linked list
|
||||
pTemp = m_pList;
|
||||
while ( pTemp )
|
||||
{
|
||||
pTemp = m_pList->m_pNext;
|
||||
|
||||
// Before we delete the module, delete each MODULE_FILE_INFO
|
||||
// structures in the not found list
|
||||
PMODULE_FILE_INFO pNotFound = m_pList->m_pNotFoundNext;
|
||||
while ( pNotFound )
|
||||
{
|
||||
pNotFound = m_pList->m_pNotFoundNext->m_pNotFoundNext;
|
||||
delete m_pList->m_pNotFoundNext;
|
||||
m_pList->m_pNotFoundNext = pNotFound;
|
||||
}
|
||||
|
||||
// Now it's OK to delete the module
|
||||
delete m_pList;
|
||||
m_pList = pTemp;
|
||||
m_cModules--;
|
||||
}
|
||||
|
||||
m_pList = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PMODULE_FILE_INFO MODULE_DEPENDENCY_LIST::GetNextModule( PMODULE_FILE_INFO p )
|
||||
{
|
||||
// Returns the next module in the linked list of MODULE_FILE_INFO's
|
||||
return p ? p->m_pNext : m_pList;
|
||||
}
|
||||
|
||||
|
||||
// Given the name of a file, find the MODULE_FILE_INFO structure that
|
||||
// represents it. The fFullName parameter specifies whether the full path
|
||||
// names or just the base file names will be compared.
|
||||
PMODULE_FILE_INFO MODULE_DEPENDENCY_LIST::LookupModule( PSTR pszFileName,
|
||||
BOOL fFullName )
|
||||
{
|
||||
PMODULE_FILE_INFO p = m_pList; // Start at the list head
|
||||
|
||||
while ( p ) // While there's still entries in the list...
|
||||
{
|
||||
PSTR pszCompName = fFullName ? p->m_szFullName : p->m_szBaseName;
|
||||
|
||||
if ( 0 == lstrcmpi( pszFileName, pszCompName ) )
|
||||
return p;
|
||||
|
||||
p = p->m_pNext;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
PSTR MODULE_DEPENDENCY_LIST::GetErrorString( void )
|
||||
{
|
||||
switch ( m_errorType )
|
||||
{
|
||||
case errMDL_NO_ERROR: return "No error";
|
||||
case errMDL_FILE_NOT_FOUND: return "File not found";
|
||||
case errMDL_NOT_PE_FILE: return "Not a PE file";
|
||||
case errMDL_GENERAL_FAILURE:return "General failure";
|
||||
default: return "<Error ???>";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Adds a modules to the MODULE_FILE_INFO list. If the module imports other
|
||||
// modules, this routine recurses to add them, and check their imports.
|
||||
errModuleDependencyList
|
||||
MODULE_DEPENDENCY_LIST::AddModule( PSTR pszFileName )
|
||||
{
|
||||
PE_EXE peFile( pszFileName ); // Get easy access to the executable
|
||||
|
||||
if ( FALSE == peFile.IsValid() ) // A valid PE file???
|
||||
return (errModuleDependencyList)peFile.GetErrorType();
|
||||
|
||||
PMODULE_FILE_INFO pNew = new MODULE_FILE_INFO( pszFileName );
|
||||
if ( !pNew )
|
||||
return errMDL_GENERAL_FAILURE;
|
||||
|
||||
pNew->m_pNext = m_pList;
|
||||
m_pList = pNew;
|
||||
|
||||
m_cModules++;
|
||||
|
||||
//
|
||||
// Now see if this module imports any other modules. If so, we need
|
||||
// to recurse and add them as well.
|
||||
//
|
||||
if (0 == peFile.GetDataDirectoryEntrySize( IMAGE_DIRECTORY_ENTRY_IMPORT ))
|
||||
return errMDL_NO_ERROR;
|
||||
|
||||
// Make a pointer to the imports table
|
||||
PIMAGE_IMPORT_DESCRIPTOR pImportDir;
|
||||
pImportDir = (PIMAGE_IMPORT_DESCRIPTOR)
|
||||
peFile.GetDataDirectoryEntryPointer(IMAGE_DIRECTORY_ENTRY_IMPORT);
|
||||
if ( !pImportDir )
|
||||
return errMDL_NO_ERROR;
|
||||
|
||||
// While there are still non-null IMAGE_IMPORT_DESCRIPTORs...
|
||||
while ( pImportDir->Name )
|
||||
{
|
||||
// Get a pointer to the imported module's base name
|
||||
PSTR pszBaseName;
|
||||
pszBaseName = (PSTR)peFile.GetReadablePointerFromRVA(pImportDir->Name);
|
||||
if ( !pszBaseName )
|
||||
break;
|
||||
|
||||
// Check to see if it's already in our list. Don't add again if so.
|
||||
if ( 0 == LookupModule( pszBaseName, FALSE ) )
|
||||
{
|
||||
// Search path supposedly has the same searching algorithm as
|
||||
// the the Win32 loader...
|
||||
char szPath[MAX_PATH];
|
||||
PSTR pszDontCare;
|
||||
if ( SearchPath(0, pszBaseName, 0, MAX_PATH, szPath, &pszDontCare))
|
||||
AddModule( szPath );
|
||||
else
|
||||
pNew->AddNotFoundModule( pszBaseName );
|
||||
}
|
||||
|
||||
pImportDir++; // Advance to next imported module
|
||||
}
|
||||
|
||||
return errMDL_NO_ERROR;
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
//==========================================
|
||||
// Matt Pietrek
|
||||
// Microsoft Systems Journal, Feb 1997
|
||||
// FILE: EXEFILE.CPP
|
||||
//==========================================
|
||||
#include <windows.h>
|
||||
#pragma hdrstop
|
||||
#include "exefile.h"
|
||||
|
||||
EXE_FILE::EXE_FILE( PSTR pszFileName ) : MEMORY_MAPPED_FILE( pszFileName )
|
||||
{
|
||||
m_errorType = errEXE_FILE_FILE_NOT_FOUND;
|
||||
m_secondaryHeaderOffset = -1; // A bogus value to catch bugs
|
||||
m_exeType = exeType_Invalid;
|
||||
|
||||
if ( FALSE == MEMORY_MAPPED_FILE::IsValid() )
|
||||
return; // m_errorType already set to errEXE_FILE_FILE_NOT_FOUND
|
||||
|
||||
// If we get here, the file exists, and was mapped. We're still not
|
||||
// sure that it's a valid EXE though
|
||||
m_errorType = errEXE_FILE_INVALID_FORMAT;
|
||||
|
||||
if ( GetFileSize() < sizeof(IMAGE_DOS_HEADER) )
|
||||
return;
|
||||
|
||||
PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)GetBase();
|
||||
if ( IMAGE_DOS_SIGNATURE != pDosHdr->e_magic )
|
||||
return;
|
||||
|
||||
// If we get here, it's at least a DOS 'MZ' file
|
||||
m_errorType = errEXE_FILE_NO_ERROR;
|
||||
|
||||
if ( pDosHdr->e_lfarlc < 0x40 ) // Theoretically, this field must be >=
|
||||
{ // 0x40 for it to be a non-DOS executable
|
||||
m_exeType = exeType_DOS;
|
||||
return;
|
||||
}
|
||||
|
||||
// Sanity check. Make sure the "new header" offset isn't past the end
|
||||
// of the file
|
||||
if ( pDosHdr->e_lfanew > (LONG)GetFileSize() )
|
||||
return;
|
||||
|
||||
// Make a pointer to the secondary header
|
||||
m_secondaryHeaderOffset = pDosHdr->e_lfanew;
|
||||
PWORD pSecondHdr = MakePtr( PWORD, GetBase(), m_secondaryHeaderOffset );
|
||||
|
||||
// Decide what type of EXE, based on the start of the secondary header
|
||||
switch ( *pSecondHdr )
|
||||
{
|
||||
case IMAGE_OS2_SIGNATURE: m_exeType = exeType_NE; break;
|
||||
case IMAGE_VXD_SIGNATURE: m_exeType = exeType_VXD; break;
|
||||
case 0x4558: m_exeType = exeType_LX; break; // OS/2 2.X
|
||||
}
|
||||
|
||||
if ( *(PDWORD)pSecondHdr == IMAGE_NT_SIGNATURE )
|
||||
m_exeType = exeType_PE;
|
||||
}
|
||||
|
||||
PSTR EXE_FILE::GetFileTypeDescription( void )
|
||||
{
|
||||
// Returns a static string that describes what type this file is
|
||||
switch ( m_exeType )
|
||||
{
|
||||
case exeType_DOS: return "DOS";
|
||||
case exeType_NE: return "NE";
|
||||
case exeType_VXD: return "VXD";
|
||||
case exeType_LX: return "LX";
|
||||
case exeType_PE: return "PE";
|
||||
default: return "Invalid";
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
//==========================================
|
||||
// Matt Pietrek
|
||||
// Microsoft Systems Journal, Feb 1997
|
||||
// FILE: MEMORYMPAPPEDFILE.CPP
|
||||
//==========================================
|
||||
#include <windows.h>
|
||||
#pragma hdrstop
|
||||
#include "memorymappedfile.h"
|
||||
|
||||
MEMORY_MAPPED_FILE::MEMORY_MAPPED_FILE( PSTR pszFileName )
|
||||
{
|
||||
//
|
||||
// Given a filename, the constructor opens a file handle, creates a file
|
||||
// mapping, and maps the entire file into memory.
|
||||
//
|
||||
m_hFile = INVALID_HANDLE_VALUE;
|
||||
m_hFileMapping = 0;
|
||||
m_pMemoryMappedFileBase = 0;
|
||||
m_cbFile = 0;
|
||||
m_errCode = errMMF_FileOpen; // Initial error code: not found
|
||||
|
||||
// First get a file handle
|
||||
m_hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE)0);
|
||||
|
||||
if ( m_hFile == INVALID_HANDLE_VALUE )
|
||||
{
|
||||
m_errCode = errMMF_FileOpen;
|
||||
return;
|
||||
}
|
||||
|
||||
m_cbFile = ::GetFileSize( m_hFile, 0 );
|
||||
|
||||
// Now, create a file mapping
|
||||
m_hFileMapping = CreateFileMapping(m_hFile,NULL, PAGE_READONLY, 0, 0,NULL);
|
||||
if ( m_hFileMapping == 0 )
|
||||
{
|
||||
// Oops. Something went wrong. Clean up.
|
||||
CloseHandle(m_hFile);
|
||||
m_hFile = INVALID_HANDLE_VALUE;
|
||||
m_errCode = errMMF_FileMapping;
|
||||
return;
|
||||
}
|
||||
|
||||
m_pMemoryMappedFileBase = (PCHAR)MapViewOfFile( m_hFileMapping,
|
||||
FILE_MAP_READ, 0, 0, 0);
|
||||
|
||||
if ( m_pMemoryMappedFileBase == 0 )
|
||||
{
|
||||
// Oops. Something went wrong. Clean up.
|
||||
CloseHandle(m_hFileMapping);
|
||||
m_hFileMapping = 0;
|
||||
CloseHandle(m_hFile);
|
||||
m_hFile = INVALID_HANDLE_VALUE;
|
||||
m_errCode = errMMF_MapView;
|
||||
return;
|
||||
}
|
||||
|
||||
m_errCode = errMMF_NoError;
|
||||
}
|
||||
|
||||
MEMORY_MAPPED_FILE::~MEMORY_MAPPED_FILE(void)
|
||||
{
|
||||
// Clean up everything that was created by the constructor
|
||||
if ( m_pMemoryMappedFileBase )
|
||||
UnmapViewOfFile( m_pMemoryMappedFileBase );
|
||||
|
||||
if ( m_hFileMapping )
|
||||
CloseHandle( m_hFileMapping );
|
||||
|
||||
if ( m_hFile != INVALID_HANDLE_VALUE )
|
||||
CloseHandle( m_hFile );
|
||||
|
||||
m_errCode = errMMF_FileOpen;
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
//==========================================
|
||||
// Matt Pietrek
|
||||
// Microsoft Systems Journal, Feb 1997
|
||||
// FILE: PEEXE.CPP
|
||||
//==========================================
|
||||
#include <windows.h>
|
||||
#include <stdlib.h>
|
||||
#pragma hdrstop
|
||||
#include "peexe.h"
|
||||
|
||||
PE_EXE::PE_EXE( PSTR pszFileName ) : EXE_FILE( pszFileName )
|
||||
{
|
||||
m_pNtHdr = 0;
|
||||
|
||||
if ( FALSE == EXE_FILE::IsValid() )
|
||||
return;
|
||||
|
||||
// It's an EXE, but is it a *PE* file??? If not, set code and bail
|
||||
if ( GetExeType() != exeType_PE )
|
||||
{
|
||||
m_errorType = errEXE_FILE_INVALID_FORMAT;
|
||||
return;
|
||||
}
|
||||
|
||||
m_pNtHdr = MakePtr(PIMAGE_NT_HEADERS,GetBase(),GetSecondaryHeaderOffset());
|
||||
}
|
||||
|
||||
DWORD PE_EXE::GetDataDirectoryEntryRVA( DWORD id )
|
||||
{
|
||||
// Given a IMAGE_DIRECTORY_ENTRY_XXX value (see WINNT.H), retrive the
|
||||
// RVA stored in the corresponding slot
|
||||
|
||||
if ( id >= IMAGE_NUMBEROF_DIRECTORY_ENTRIES )
|
||||
return (DWORD)-1;
|
||||
|
||||
return m_pNtHdr->OptionalHeader.DataDirectory[id].VirtualAddress;
|
||||
}
|
||||
|
||||
PVOID PE_EXE::GetDataDirectoryEntryPointer( DWORD id )
|
||||
{
|
||||
// Given a IMAGE_DIRECTORY_ENTRY_XXX value (see WINNT.H), return a pointer
|
||||
// to memory that corresponds to the RVA in the specified slot.
|
||||
|
||||
if ( id >= IMAGE_NUMBEROF_DIRECTORY_ENTRIES )
|
||||
return (PVOID)-1;
|
||||
|
||||
DWORD va = m_pNtHdr->OptionalHeader.DataDirectory[id].VirtualAddress;
|
||||
|
||||
if ( !va ) // Return 0 if the RVA is 0
|
||||
return 0;
|
||||
|
||||
return GetReadablePointerFromRVA( va );
|
||||
}
|
||||
|
||||
DWORD PE_EXE::GetDataDirectoryEntrySize( DWORD id )
|
||||
{
|
||||
// Given a IMAGE_DIRECTORY_ENTRY_XXX value (see WINNT.H), retrive the
|
||||
// size value stored in the corresponding slot
|
||||
|
||||
if ( id >= IMAGE_NUMBEROF_DIRECTORY_ENTRIES )
|
||||
return (DWORD)-1;
|
||||
|
||||
return m_pNtHdr->OptionalHeader.DataDirectory[id].Size;
|
||||
}
|
||||
|
||||
PVOID PE_EXE::GetReadablePointerFromRVA( DWORD rva )
|
||||
{
|
||||
// Given an RVA, translate it into a pointer within our linear memory
|
||||
// mapping for the executable.
|
||||
|
||||
DWORD fileOffset = RVAToFileOffset( rva );
|
||||
if ( (DWORD)-1 == fileOffset )
|
||||
return 0;
|
||||
|
||||
return MakePtr( PVOID, GetBase(), fileOffset );
|
||||
}
|
||||
|
||||
DWORD PE_EXE::RVAToFileOffset( DWORD rva )
|
||||
{
|
||||
// Given an RVA, figure out which section encompasses it. Next, using
|
||||
// the PointerToRawData field for the found section, return an actual
|
||||
// file offset that corresponds to the RVA
|
||||
|
||||
PIMAGE_SECTION_HEADER pSectHdr = IMAGE_FIRST_SECTION( m_pNtHdr );
|
||||
|
||||
for ( unsigned i = 0; i < GetNumberOfSections(); i++, pSectHdr++ )
|
||||
{
|
||||
DWORD cbMaxOnDisk
|
||||
= min( pSectHdr->Misc.VirtualSize, pSectHdr->SizeOfRawData );
|
||||
|
||||
DWORD startSectRVA = pSectHdr->VirtualAddress;
|
||||
DWORD endSectRVA = startSectRVA + cbMaxOnDisk;
|
||||
|
||||
if ( (rva >= startSectRVA) && (rva < endSectRVA) )
|
||||
return pSectHdr->PointerToRawData + (rva - startSectRVA);
|
||||
}
|
||||
|
||||
return (DWORD)-1; // RVA not found in the section table... Ooops!
|
||||
}
|
@ -0,0 +1,321 @@
|
||||
//==========================================
|
||||
// Matt Pietrek
|
||||
// Microsoft Systems Journal, Feb 1997
|
||||
// FILE: DEPENDS.CPP
|
||||
//==========================================
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include "dependencylist.h"
|
||||
#include "peexe.h"
|
||||
|
||||
//============================== Variables ===============================
|
||||
char g_szHelpSyntax[] =
|
||||
"DEPENDS - Matt Pietrek, 1997, for MSJ\n"
|
||||
"Syntax: DEPENDS [args] <executable filename>\n"
|
||||
" /v show version information\n"
|
||||
" /t show time & date information\n"
|
||||
" /p show full path\n"
|
||||
" /q quiet (don't report some MS dlls)\n"
|
||||
" /l show link time & date information\n\n";
|
||||
|
||||
char * g_pszPrimaryFile = 0;
|
||||
|
||||
BOOL g_fShowDateTime = FALSE;
|
||||
BOOL g_fShowLinkDateTime = FALSE;
|
||||
BOOL g_fShowVersion = FALSE;
|
||||
BOOL g_fShowFullPath = FALSE;
|
||||
BOOL g_fQuiet = FALSE;
|
||||
|
||||
//============================== Prototypes ===============================
|
||||
void DisplayFileInformation( PMODULE_FILE_INFO pModInfo,BOOL bQuiet );
|
||||
void ShowVersionInfo( PSTR pszFileName );
|
||||
BOOL TimeDateStampToFileTime( DWORD timeDateStamp, LPFILETIME pFileTime );
|
||||
BOOL GetFileDateAsString( LPFILETIME pFt, char * pszDate, unsigned cbIn );
|
||||
BOOL GetFileTimeAsString( LPFILETIME pFt, char * pszTime, unsigned cbIn,
|
||||
BOOL fSeconds );
|
||||
|
||||
//=================================== Code ================================
|
||||
|
||||
BOOL ProcessCommandLine( int argc, char * argv[] )
|
||||
{
|
||||
BOOL fSawFileName = FALSE;
|
||||
|
||||
if ( argc < 2 )
|
||||
return FALSE;
|
||||
|
||||
for ( int i = 1; i < argc; i++ )
|
||||
{
|
||||
PSTR pArg = argv[i];
|
||||
|
||||
if ( (*pArg == '/') || (*pArg == '-') ) // Is it a switch char?
|
||||
{
|
||||
pArg++; // Point past switch char
|
||||
|
||||
if ( 0 == lstrcmpi( pArg, "v" ) )
|
||||
g_fShowVersion = TRUE;
|
||||
else if ( 0 == lstrcmpi( pArg, "t" ) )
|
||||
g_fShowDateTime = TRUE;
|
||||
else if ( 0 == lstrcmpi( pArg, "l" ) )
|
||||
g_fShowLinkDateTime = TRUE;
|
||||
else if ( 0 == lstrcmpi( pArg, "p" ) )
|
||||
g_fShowFullPath = TRUE;
|
||||
else if ( 0 == lstrcmpi( pArg, "q" ) )
|
||||
g_fQuiet = TRUE;
|
||||
else
|
||||
{
|
||||
printf( "Unrecognized option: \"%s\"\n", pArg );
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( fSawFileName )
|
||||
return FALSE;
|
||||
|
||||
g_pszPrimaryFile = pArg;
|
||||
fSawFileName = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return fSawFileName;
|
||||
}
|
||||
|
||||
LPCTSTR getModuleBase(PMODULE_FILE_INFO pModule,BOOL bQuiet)
|
||||
{
|
||||
LPCTSTR base = pModule->GetBaseName() ;
|
||||
LPCTSTR result = base ;
|
||||
if ( bQuiet ) {
|
||||
// keep quiet about these guys - they're build/compiler dependant
|
||||
if ( _strnicmp(base,"MSVCR",5) == 0 ) result = NULL ;
|
||||
if ( _strnicmp(base,"MSVCP",5) == 0 ) result = NULL ;
|
||||
if ( _strnicmp(base,"API-MS-Win",10) == 0 ) result = NULL ;
|
||||
}
|
||||
return result ;
|
||||
}
|
||||
|
||||
int main( int argc, char * argv[] )
|
||||
{
|
||||
if ( !ProcessCommandLine( argc, argv ) )
|
||||
{
|
||||
printf( "%s %d bit build\n%s",argv[0],8*sizeof(void*),g_szHelpSyntax );
|
||||
return 1;
|
||||
}
|
||||
|
||||
MODULE_DEPENDENCY_LIST depends( g_pszPrimaryFile );
|
||||
|
||||
if ( !depends.IsValid() )
|
||||
{
|
||||
printf( "Error: %s %s\n", g_pszPrimaryFile, depends.GetErrorString() );
|
||||
return 1;
|
||||
}
|
||||
|
||||
PMODULE_FILE_INFO pModInfo = 0;
|
||||
|
||||
while ( pModInfo = depends.GetNextModule( pModInfo ) )
|
||||
{
|
||||
DisplayFileInformation( pModInfo,g_fQuiet );
|
||||
|
||||
PMODULE_FILE_INFO pNotFound = 0;
|
||||
|
||||
while ( pNotFound = pModInfo->GetNextNotFoundModule(pNotFound) )
|
||||
{
|
||||
LPCTSTR base = getModuleBase(pNotFound,g_fQuiet) ;
|
||||
if ( base ) printf( " Not found: %s\n", base );
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DisplayFileInformation( PMODULE_FILE_INFO pModInfo, BOOL bQuiet )
|
||||
{
|
||||
LPCTSTR base = getModuleBase(pModInfo,bQuiet);
|
||||
if ( !base ) return ;
|
||||
printf( "%-14s", base) ; // ->GetBaseName() );
|
||||
|
||||
PSTR pszFullName = pModInfo->GetFullName();
|
||||
|
||||
if ( g_fShowDateTime )
|
||||
{
|
||||
HFILE hFile = _lopen( pszFullName, OF_READ );
|
||||
if ( HFILE_ERROR != hFile )
|
||||
{
|
||||
FILETIME ft;
|
||||
|
||||
if ( GetFileTime( (HANDLE)hFile, 0, 0, &ft ) )
|
||||
{
|
||||
char szFileDate[32] = { 0 };
|
||||
char szFileTime[32] = { 0 };
|
||||
|
||||
GetFileDateAsString(&ft, szFileDate, sizeof(szFileDate) );
|
||||
GetFileTimeAsString(&ft, szFileTime, sizeof(szFileTime),
|
||||
TRUE);
|
||||
|
||||
printf( "%s %s ", szFileDate, szFileTime );
|
||||
}
|
||||
|
||||
_lclose( hFile );
|
||||
}
|
||||
}
|
||||
|
||||
if ( g_fShowLinkDateTime )
|
||||
{
|
||||
FILETIME ft;
|
||||
char szFileDate[32] = { 0 };
|
||||
char szFileTime[32] = { 0 };
|
||||
|
||||
PE_EXE exe( pszFullName );
|
||||
|
||||
TimeDateStampToFileTime( exe.GetTimeDateStamp(), &ft );
|
||||
|
||||
GetFileDateAsString(&ft, szFileDate, sizeof(szFileDate) );
|
||||
GetFileTimeAsString(&ft, szFileTime, sizeof(szFileTime),
|
||||
TRUE);
|
||||
|
||||
printf( "%s %s ", szFileDate, szFileTime );
|
||||
}
|
||||
|
||||
if ( g_fShowFullPath )
|
||||
printf( "(%s)", pszFullName );
|
||||
|
||||
printf( "\n" );
|
||||
|
||||
if ( g_fShowVersion )
|
||||
ShowVersionInfo( pszFullName );
|
||||
}
|
||||
|
||||
void ShowVersionInfo( PSTR pszFileName )
|
||||
{
|
||||
DWORD cbVerInfo, dummy;
|
||||
|
||||
// How big is the version info?
|
||||
cbVerInfo = GetFileVersionInfoSize( pszFileName, &dummy );
|
||||
if ( !cbVerInfo )
|
||||
return;
|
||||
|
||||
// Allocate space to hold the info
|
||||
PBYTE pVerInfo = new BYTE[cbVerInfo];
|
||||
if ( !pVerInfo )
|
||||
return;
|
||||
|
||||
_try
|
||||
{
|
||||
if ( !GetFileVersionInfo(pszFileName, 0, cbVerInfo, pVerInfo) )
|
||||
_leave;
|
||||
|
||||
char * predefResStrings[] =
|
||||
{
|
||||
"CompanyName",
|
||||
"FileDescription",
|
||||
"FileVersion",
|
||||
"InternalName",
|
||||
"LegalCopyright",
|
||||
"OriginalFilename",
|
||||
"ProductName",
|
||||
"ProductVersion",
|
||||
0
|
||||
};
|
||||
|
||||
for ( unsigned i=0; predefResStrings[i]; i++ )
|
||||
{
|
||||
char szQueryStr[ 0x100 ];
|
||||
char szQueryStr2[0x100 ];
|
||||
|
||||
// Format the string with the 1200 codepage (Unicode)
|
||||
wsprintf( szQueryStr, "\\StringFileInfo\\%04X%04X\\%s",
|
||||
GetUserDefaultLangID(), 1200,
|
||||
predefResStrings[i] );
|
||||
|
||||
// Format the string with the 1252 codepage (Windows Multilingual)
|
||||
wsprintf( szQueryStr2, "\\StringFileInfo\\%04X%04X\\%s",
|
||||
GetUserDefaultLangID(), 1252,
|
||||
predefResStrings[i] );
|
||||
// We may want to format a string with the "0000" codepage
|
||||
|
||||
PSTR pszVerRetVal;
|
||||
UINT cbReturn;
|
||||
BOOL fFound;
|
||||
|
||||
// Try first with the 1252 codepage
|
||||
fFound = VerQueryValue( pVerInfo, szQueryStr,
|
||||
(LPVOID *)&pszVerRetVal, &cbReturn );
|
||||
if ( !fFound )
|
||||
{
|
||||
// Hmm... 1252 wasn't found. Try the 1200 codepage
|
||||
fFound = VerQueryValue( pVerInfo, szQueryStr2,
|
||||
(LPVOID *)&pszVerRetVal, &cbReturn );
|
||||
}
|
||||
|
||||
if ( fFound )
|
||||
printf( " %s %s\n", predefResStrings[i], pszVerRetVal );
|
||||
}
|
||||
}
|
||||
_finally
|
||||
{
|
||||
delete []pVerInfo;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Convert a TimeDateStamp (i.e., # of seconds since 1/1/1970) into a FILETIME
|
||||
|
||||
BOOL TimeDateStampToFileTime( DWORD timeDateStamp, LPFILETIME pFileTime )
|
||||
{
|
||||
__int64 t1970 = 0x019DB1DED53E8000; // Magic... GMT... Don't ask....
|
||||
|
||||
__int64 timeStampIn100nsIncr = (__int64)timeDateStamp * 10000000;
|
||||
|
||||
__int64 finalValue = t1970 + timeStampIn100nsIncr;
|
||||
|
||||
memcpy( pFileTime, &finalValue, sizeof( finalValue ) );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL GetFileDateAsString( LPFILETIME pFt, char * pszDate, unsigned cbIn )
|
||||
{
|
||||
FILETIME ftLocal;
|
||||
SYSTEMTIME st;
|
||||
|
||||
if ( !FileTimeToLocalFileTime( pFt, &ftLocal ) )
|
||||
return FALSE;
|
||||
|
||||
if ( !FileTimeToSystemTime( &ftLocal, &st ) )
|
||||
return FALSE;
|
||||
|
||||
char szTemp[12];
|
||||
|
||||
wsprintf( szTemp, "%02u/%02u/%04u",
|
||||
st.wMonth, st.wDay, st.wYear );
|
||||
lstrcpyn( pszDate, szTemp, cbIn );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL GetFileTimeAsString( LPFILETIME pFt, char * pszTime, unsigned cbIn,
|
||||
BOOL fSeconds )
|
||||
{
|
||||
FILETIME ftLocal;
|
||||
SYSTEMTIME st;
|
||||
|
||||
if ( !FileTimeToLocalFileTime( pFt, &ftLocal ) )
|
||||
return FALSE;
|
||||
|
||||
if ( !FileTimeToSystemTime( &ftLocal, &st ) )
|
||||
return FALSE;
|
||||
|
||||
char szTemp[12];
|
||||
|
||||
if ( fSeconds ) // Want seconds???
|
||||
{
|
||||
wsprintf( szTemp, "%02u:%02u:%02u", st.wHour, st.wMinute, st.wSecond );
|
||||
}
|
||||
else // No thanks.. Just hours and minutes
|
||||
{
|
||||
wsprintf( szTemp, "%02u:%02u", st.wHour, st.wMinute );
|
||||
}
|
||||
|
||||
lstrcpyn( pszTime, szTemp, cbIn );
|
||||
|
||||
return TRUE;
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
//==========================================
|
||||
// Matt Pietrek
|
||||
// Microsoft Systems Journal, Feb 1997
|
||||
// FILE: MODULEFILEINFO.CPP
|
||||
//==========================================
|
||||
#include <windows.h>
|
||||
#include "modulefileinfo.h"
|
||||
|
||||
MODULE_FILE_INFO::MODULE_FILE_INFO( PSTR pszFileName )
|
||||
{
|
||||
m_pNext = 0;
|
||||
m_pNotFoundNext = 0;
|
||||
|
||||
// Find the last '\\' to obtain a pointer to just the base filename part
|
||||
PSTR pszBaseName = strrchr( pszFileName, '\\' );
|
||||
if ( pszBaseName ) // We found a path, so advance to the base filename
|
||||
pszBaseName++;
|
||||
else
|
||||
pszBaseName = pszFileName; // No path. Use the same name for both
|
||||
|
||||
// Initialize the new MODULE_FILE_INFO, and stick it at the head
|
||||
// of the list.
|
||||
lstrcpyn( m_szFullName, pszFileName, sizeof(m_szFullName) );
|
||||
lstrcpyn( m_szBaseName, pszBaseName, sizeof(m_szBaseName) );
|
||||
|
||||
}
|
||||
|
||||
void MODULE_FILE_INFO::AddNotFoundModule( PSTR pszFileName )
|
||||
{
|
||||
PMODULE_FILE_INFO pNew = new MODULE_FILE_INFO( pszFileName );
|
||||
|
||||
pNew->m_pNotFoundNext = m_pNotFoundNext;
|
||||
m_pNotFoundNext = pNew;
|
||||
}
|
||||
|
||||
MODULE_FILE_INFO * MODULE_FILE_INFO::GetNextNotFoundModule( PMODULE_FILE_INFO p)
|
||||
{
|
||||
PMODULE_FILE_INFO pNext = p ? p->m_pNotFoundNext : m_pNotFoundNext;
|
||||
|
||||
return pNext;
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// Depends2.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
@ -0,0 +1,15 @@
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "targetver.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
|
||||
|
||||
|
||||
// TODO: reference additional headers your program requires here
|
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
// The following macros define the minimum required platform. The minimum required platform
|
||||
// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run
|
||||
// your application. The macros work by enabling all features available on platform versions up to and
|
||||
// including the version specified.
|
||||
|
||||
// Modify the following defines if you have to target a platform prior to the ones specified below.
|
||||
// Refer to MSDN for the latest info on corresponding values for different platforms.
|
||||
#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista.
|
||||
#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows.
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue