msvc64: adding tools/depends directory and code.

v0.27.3
Robin Mills 15 years ago
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…
Cancel
Save