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