Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1269 lines
55 KiB

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
imagecfg.c
Abstract:
This function change the image loader configuration information in an image file.
Author:
Steve Wood (stevewo) 8-Nov-1994
Revision History:
--*/
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <private.h>
struct {
DWORD Flag;
LPSTR ClearPrefix;
LPSTR SetPrefix;
LPSTR Description;
} NtGlobalFlagNames[] = {
{FLG_STOP_ON_EXCEPTION, "Don't ", "", "Stop on exception"},
{FLG_SHOW_LDR_SNAPS, "Don't ", "", "Show Loader Debugging Information"},
{FLG_DEBUG_INITIAL_COMMAND, "Don't ", "", "Debug Initial Command (WINLOGON)"},
{FLG_STOP_ON_HUNG_GUI, "Don't ", "", "Stop on Hung GUI"},
{FLG_HEAP_ENABLE_TAIL_CHECK, "Disable", "Enable", " Heap Tail Checking"},
{FLG_HEAP_ENABLE_FREE_CHECK, "Disable", "Enable", " Heap Free Checking"},
{FLG_HEAP_VALIDATE_PARAMETERS, "Disable", "Enable", " Heap Parameter Validation"},
{FLG_HEAP_VALIDATE_ALL, "Disable", "Enable", " Heap Validate on Call"},
{FLG_POOL_ENABLE_TAGGING, "Disable", "Enable", " Pool Tagging"},
{FLG_HEAP_ENABLE_TAGGING, "Disable", "Enable", " Heap Tagging"},
{FLG_USER_STACK_TRACE_DB, "Disable", "Enable", " User Mode Stack Backtrace DB (x86 checked only)"},
{FLG_KERNEL_STACK_TRACE_DB, "Disable", "Enable", " Kernel Mode Stack Backtrace DB (x86 checked only)"},
{FLG_MAINTAIN_OBJECT_TYPELIST, "Don't ", "", "Maintain list of kernel mode objects by type"},
{FLG_HEAP_ENABLE_TAG_BY_DLL, "Disable", "Enable", " Heap DLL Tagging"},
{FLG_ENABLE_CSRDEBUG, "Disable", "Enable", " Debugging of CSRSS"},
{FLG_ENABLE_KDEBUG_SYMBOL_LOAD, "Disable", "Enable", " Kernel Debugger Symbol load"},
{FLG_DISABLE_PAGE_KERNEL_STACKS, "Enable", "Disable", " Paging of Kernel Stacks"},
{FLG_HEAP_DISABLE_COALESCING, "Enable", "Disable", " Heap Coalescing on Free"},
{FLG_ENABLE_CLOSE_EXCEPTIONS, "Disable", "Enable", " Close Exceptions"},
{FLG_ENABLE_EXCEPTION_LOGGING, "Disable", "Enable", " Exception Logging"},
{FLG_ENABLE_HANDLE_TYPE_TAGGING, "Disable", "Enable", " Handle type tagging"},
{FLG_HEAP_PAGE_ALLOCS, "Disable", "Enable", " Heap page allocs"},
{FLG_DEBUG_INITIAL_COMMAND_EX, "Disable", "Enable", " Extended debug initial command"},
{FLG_DISABLE_DBGPRINT, "Enable", "Disable"," DbgPrint to debugger"},
{0, NULL}
};
void
DisplayGlobalFlags(
LPSTR IndentString,
DWORD NtGlobalFlags,
BOOLEAN Set
)
{
ULONG i;
for (i=0; NtGlobalFlagNames[i].Description; i++) {
if (NtGlobalFlagNames[i].Flag & NtGlobalFlags) {
printf( "%s%s%s\n",
IndentString,
Set ? NtGlobalFlagNames[i].SetPrefix :
NtGlobalFlagNames[i].ClearPrefix,
NtGlobalFlagNames[i].Description
);
}
}
return;
}
BOOL fVerbose;
BOOL fUsage;
BOOL fConfigInfoChanged;
BOOL fImageHasConfigInfo;
BOOL fImageHeaderChanged;
LPSTR CurrentImageName;
BOOL f64bitImage;
LOADED_IMAGE CurrentImage;
PIMAGE_LOAD_CONFIG_DIRECTORY pConfigInfo;
CHAR DebugFilePath[_MAX_PATH];
LPSTR SymbolPath;
ULONG GlobalFlagsClear;
ULONG GlobalFlagsSet;
ULONG CriticalSectionDefaultTimeout;
ULONG ProcessHeapFlags;
ULONG MajorSubsystemVersion;
ULONG MinorSubsystemVersion;
ULONG Win32VersionValue;
ULONG Win32CSDVerValue;
BOOLEAN fUniprocessorOnly;
BOOLEAN fRestrictedWorkingSet;
BOOLEAN fEnableLargeAddresses;
BOOLEAN fNoBind;
BOOLEAN fEnableTerminalServerAware;
BOOLEAN fDisableTerminalServerAware;
BOOLEAN fSwapRunNet;
BOOLEAN fSwapRunCD;
BOOLEAN fQuiet;
ULONGLONG DeCommitFreeBlockThreshold;
ULONGLONG DeCommitTotalFreeThreshold;
ULONGLONG MaximumAllocationSize;
ULONGLONG VirtualMemoryThreshold;
ULONGLONG ImageProcessAffinityMask;
ULONGLONG SizeOfStackReserve;
ULONGLONG SizeOfStackCommit;
VOID
DisplayImageInfo(
BOOL HasConfigInfo
);
PVOID
GetAddressOfExportedData(
PLOADED_IMAGE Dll,
LPSTR ExportedName
);
ULONGLONG
ConvertNum(
char *s
)
{
ULONGLONG result;
int n;
if (!_strnicmp( s, "0x", 2 )) {
s += 2;
n = sscanf( s, "%I64x", &result );
}
else {
n = sscanf( s, "%I64d", &result );
}
return( ( n != 1 ) ? 0 : result );
} // ConvertNum()
__inline PVOID
GetVaForRva(
PLOADED_IMAGE Image,
ULONG Rva
)
{
PVOID Va;
Va = ImageRvaToVa( Image->FileHeader,
Image->MappedAddress,
Rva,
&Image->LastRvaSection
);
return Va;
}
PVOID
GetAddressOfExportedData(
PLOADED_IMAGE Dll,
LPSTR ExportedName
)
{
PIMAGE_EXPORT_DIRECTORY Exports;
ULONG ExportSize;
USHORT HintIndex;
USHORT OrdinalNumber;
PULONG NameTableBase;
PUSHORT NameOrdinalTableBase;
PULONG FunctionTableBase;
LPSTR NameTableName;
Exports = (PIMAGE_EXPORT_DIRECTORY)ImageDirectoryEntryToData( (PVOID)Dll->MappedAddress,
FALSE,
IMAGE_DIRECTORY_ENTRY_EXPORT,
&ExportSize
);
if (Exports) {
NameTableBase = (PULONG)GetVaForRva( Dll, Exports->AddressOfNames );
NameOrdinalTableBase = (PUSHORT)GetVaForRva( Dll, Exports->AddressOfNameOrdinals );
FunctionTableBase = (PULONG)GetVaForRva( Dll, Exports->AddressOfFunctions );
if (NameTableBase != NULL &&
NameOrdinalTableBase != NULL &&
FunctionTableBase != NULL
) {
for (HintIndex = 0; HintIndex < Exports->NumberOfNames; HintIndex++) {
NameTableName = (LPSTR)GetVaForRva( Dll, NameTableBase[ HintIndex ] );
if (NameTableName) {
if (!strcmp( ExportedName, NameTableName )) {
OrdinalNumber = NameOrdinalTableBase[ HintIndex ];
return FunctionTableBase[ OrdinalNumber ] + Dll->MappedAddress;
}
}
}
}
}
return NULL;
}
VOID
DisplayConfigInfo32(PIMAGE_LOAD_CONFIG_DIRECTORY32 LoadConfig)
{
if (LoadConfig->GlobalFlagsClear) {
printf( " NtGlobalFlags to clear: %08x\n", LoadConfig->GlobalFlagsClear);
DisplayGlobalFlags( " ", LoadConfig->GlobalFlagsClear, FALSE );
}
if (LoadConfig->GlobalFlagsSet) {
printf( " NtGlobalFlags to set: %08x\n", LoadConfig->GlobalFlagsSet);
DisplayGlobalFlags( " ", LoadConfig->GlobalFlagsSet, TRUE );
}
if (LoadConfig->CriticalSectionDefaultTimeout) {
printf( " Default Critical Section Timeout: %u milliseconds\n", LoadConfig->CriticalSectionDefaultTimeout);
}
if (LoadConfig->DeCommitFreeBlockThreshold) {
printf( " Process Heap DeCommit Free Block threshold: %08x\n", (DWORD)LoadConfig->DeCommitFreeBlockThreshold);
}
if (LoadConfig->DeCommitTotalFreeThreshold) {
printf( " Process Heap DeCommit Total Free threshold: %08x\n", (DWORD)LoadConfig->DeCommitTotalFreeThreshold);
}
if (LoadConfig->LockPrefixTable) {
printf( " Lock Prefix Table: %x\n", LoadConfig->LockPrefixTable);
}
if (LoadConfig->MaximumAllocationSize) {
printf( " Process Heap Maximum Allocation Size: %08x\n", LoadConfig->MaximumAllocationSize);
}
if (LoadConfig->VirtualMemoryThreshold) {
printf( " Process Heap VirtualAlloc Threshold: %08x\n", LoadConfig->VirtualMemoryThreshold);
}
if (LoadConfig->ProcessHeapFlags) {
printf( " Process Heap Flags: %08x\n", LoadConfig->ProcessHeapFlags);
}
if (LoadConfig->ProcessAffinityMask) {
printf( " Process Affinity Mask: %08x\n", LoadConfig->ProcessAffinityMask);
}
if (LoadConfig->CSDVersion) {
printf( " CSD version: %d\n", LoadConfig->CSDVersion);
}
if (LoadConfig->Size >= FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, SEHandlerCount)) {
if (LoadConfig->SecurityCookie) {
printf( " Security Cookie offset: %x\n", LoadConfig->SecurityCookie);
}
if (LoadConfig->SEHandlerTable) {
printf( " SEH handler table: %x\n", LoadConfig->SEHandlerTable);
}
if (LoadConfig->SEHandlerCount) {
printf( " SEH Handler count: %d\n", LoadConfig->SEHandlerCount);
}
}
}
VOID
DisplayConfigInfo64(PIMAGE_LOAD_CONFIG_DIRECTORY64 LoadConfig)
{
if (LoadConfig->GlobalFlagsClear) {
printf( " NtGlobalFlags to clear: %08x\n", LoadConfig->GlobalFlagsClear);
DisplayGlobalFlags( " ", LoadConfig->GlobalFlagsClear, FALSE );
}
if (LoadConfig->GlobalFlagsSet) {
printf( " NtGlobalFlags to set: %08x\n", LoadConfig->GlobalFlagsSet);
DisplayGlobalFlags( " ", LoadConfig->GlobalFlagsSet, TRUE );
}
if (LoadConfig->CriticalSectionDefaultTimeout) {
printf( " Default Critical Section Timeout: %u milliseconds\n", LoadConfig->CriticalSectionDefaultTimeout);
}
if (LoadConfig->DeCommitFreeBlockThreshold) {
printf( " Process Heap DeCommit Free Block threshold: %I64x\n", LoadConfig->DeCommitFreeBlockThreshold);
}
if (LoadConfig->DeCommitTotalFreeThreshold) {
printf( " Process Heap DeCommit Total Free threshold: %I64x\n", LoadConfig->DeCommitTotalFreeThreshold);
}
if (LoadConfig->LockPrefixTable) {
printf( " Lock Prefix Table: %I64x\n", LoadConfig->LockPrefixTable);
}
if (LoadConfig->MaximumAllocationSize) {
printf( " Process Heap Maximum Allocation Size: %I64x\n", LoadConfig->MaximumAllocationSize);
}
if (LoadConfig->VirtualMemoryThreshold) {
printf( " Process Heap VirtualAlloc Threshold: %I64x\n", LoadConfig->VirtualMemoryThreshold);
}
if (LoadConfig->ProcessHeapFlags) {
printf( " Process Heap Flags: %08x\n", LoadConfig->ProcessHeapFlags);
}
if (LoadConfig->ProcessAffinityMask) {
printf( " Process Affinity Mask: %I64x\n", LoadConfig->ProcessAffinityMask);
}
if (LoadConfig->CSDVersion) {
printf( " CSD version: %d\n", LoadConfig->CSDVersion);
}
if (LoadConfig->Size >= FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, SEHandlerCount)) {
if (LoadConfig->SecurityCookie) {
printf( " Security Cookie offset: %I64x\n", LoadConfig->SecurityCookie);
}
if (LoadConfig->SEHandlerTable) {
printf( " SEH handler table: %I64x\n", LoadConfig->SEHandlerTable);
}
if (LoadConfig->SEHandlerCount) {
printf( " SEH Handler count: %d\n", LoadConfig->SEHandlerCount);
}
}
}
VOID
DisplayHeaderInfo32(PIMAGE_NT_HEADERS32 NtHeader)
{
printf( " Subsystem Version of %u.%u\n", NtHeader->OptionalHeader.MajorSubsystemVersion, NtHeader->OptionalHeader.MinorSubsystemVersion);
if (NtHeader->OptionalHeader.Win32VersionValue) {
printf( " Win32 GetVersion return value: %08x\n", NtHeader->OptionalHeader.Win32VersionValue);
}
if (NtHeader->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE) {
printf( " Image can handle large (>2GB) addresses\n" );
}
if (NtHeader->FileHeader.Characteristics & IMAGE_FILE_NET_RUN_FROM_SWAP) {
printf( " Image will run from swapfile if located on net\n" );
}
if (NtHeader->FileHeader.Characteristics & IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP) {
printf( " Image will run from swapfile if located on removable media\n" );
}
if (NtHeader->FileHeader.Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY) {
printf( " Image can only run in uni-processor mode on multi-processor systems\n" );
}
if (NtHeader->FileHeader.Characteristics & IMAGE_FILE_AGGRESIVE_WS_TRIM) {
printf( " Image working set trimmed aggressively on small memory systems\n" );
}
if (NtHeader->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE) {
printf( " Image is Terminal Server aware\n" );
}
if (NtHeader->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_NO_BIND) {
printf( " Image does not support binding\n" );
}
if (NtHeader->OptionalHeader.SizeOfStackReserve) {
printf( " Stack Reserve Size: 0x%x\n", NtHeader->OptionalHeader.SizeOfStackReserve );
}
if (NtHeader->OptionalHeader.SizeOfStackCommit) {
printf( " Stack Commit Size: 0x%x\n", NtHeader->OptionalHeader.SizeOfStackCommit );
}
}
VOID
DisplayHeaderInfo64(PIMAGE_NT_HEADERS64 NtHeader)
{
printf( " Subsystem Version of %u.%u\n", NtHeader->OptionalHeader.MajorSubsystemVersion, NtHeader->OptionalHeader.MinorSubsystemVersion);
if (NtHeader->OptionalHeader.Win32VersionValue) {
printf( " Win32 GetVersion return value: %08x\n", NtHeader->OptionalHeader.Win32VersionValue);
}
if (NtHeader->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE) {
printf( " Image can handle large (>2GB) addresses\n" );
}
if (NtHeader->FileHeader.Characteristics & IMAGE_FILE_NET_RUN_FROM_SWAP) {
printf( " Image will run from swapfile if located on net\n" );
}
if (NtHeader->FileHeader.Characteristics & IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP) {
printf( " Image will run from swapfile if located on removable media\n" );
}
if (NtHeader->FileHeader.Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY) {
printf( " Image can only run in uni-processor mode on multi-processor systems\n" );
}
if (NtHeader->FileHeader.Characteristics & IMAGE_FILE_AGGRESIVE_WS_TRIM) {
printf( " Image working set trimmed aggressively on small memory systems\n" );
}
if (NtHeader->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE) {
printf( " Image is Terminal Server aware\n" );
}
if (NtHeader->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_NO_BIND) {
printf( " Image does not support binding\n" );
}
if (NtHeader->OptionalHeader.SizeOfStackReserve) {
printf( " Stack Reserve Size: 0x%I64x\n", NtHeader->OptionalHeader.SizeOfStackReserve );
}
if (NtHeader->OptionalHeader.SizeOfStackCommit) {
printf( " Stack Commit Size: 0x%I64x\n", NtHeader->OptionalHeader.SizeOfStackCommit );
}
}
BOOL
CheckIfConfigInfoChanged64(PIMAGE_LOAD_CONFIG_DIRECTORY64 LoadConfig)
{
if ((GlobalFlagsClear && (LoadConfig->GlobalFlagsClear != GlobalFlagsClear)) ||
(GlobalFlagsSet && (LoadConfig->GlobalFlagsSet != GlobalFlagsSet)) ||
(CriticalSectionDefaultTimeout && (LoadConfig->CriticalSectionDefaultTimeout != CriticalSectionDefaultTimeout)) ||
(ProcessHeapFlags && (LoadConfig->ProcessHeapFlags != ProcessHeapFlags)) ||
(DeCommitFreeBlockThreshold && (LoadConfig->DeCommitFreeBlockThreshold != DeCommitFreeBlockThreshold)) ||
(DeCommitTotalFreeThreshold && (LoadConfig->DeCommitTotalFreeThreshold != DeCommitTotalFreeThreshold)) ||
(MaximumAllocationSize && (LoadConfig->MaximumAllocationSize != MaximumAllocationSize)) ||
(VirtualMemoryThreshold && (LoadConfig->VirtualMemoryThreshold != VirtualMemoryThreshold)) ||
(ImageProcessAffinityMask && (LoadConfig->ProcessAffinityMask != ImageProcessAffinityMask)))
{
return TRUE;
} else {
return FALSE;
}
}
BOOL
CheckIfConfigInfoChanged32(PIMAGE_LOAD_CONFIG_DIRECTORY32 LoadConfig)
{
if ((GlobalFlagsClear && (LoadConfig->GlobalFlagsClear != GlobalFlagsClear)) ||
(GlobalFlagsSet && (LoadConfig->GlobalFlagsSet != GlobalFlagsSet)) ||
(CriticalSectionDefaultTimeout && (LoadConfig->CriticalSectionDefaultTimeout != CriticalSectionDefaultTimeout)) ||
(ProcessHeapFlags && (LoadConfig->ProcessHeapFlags != ProcessHeapFlags)) ||
(DeCommitFreeBlockThreshold && (LoadConfig->DeCommitFreeBlockThreshold != (DWORD)DeCommitFreeBlockThreshold)) ||
(DeCommitTotalFreeThreshold && (LoadConfig->DeCommitTotalFreeThreshold != (DWORD)DeCommitTotalFreeThreshold)) ||
(MaximumAllocationSize && (LoadConfig->MaximumAllocationSize != (DWORD)MaximumAllocationSize)) ||
(VirtualMemoryThreshold && (LoadConfig->VirtualMemoryThreshold != (DWORD)VirtualMemoryThreshold)) ||
(ImageProcessAffinityMask && (LoadConfig->ProcessAffinityMask != (DWORD)ImageProcessAffinityMask)))
{
return TRUE;
} else {
return FALSE;
}
}
BOOL
CheckIfImageHeaderChanged32(PIMAGE_NT_HEADERS32 NtHeader)
{
if ((MajorSubsystemVersion &&
NtHeader->OptionalHeader.MajorSubsystemVersion != (USHORT)MajorSubsystemVersion ||
NtHeader->OptionalHeader.MinorSubsystemVersion != (USHORT)MinorSubsystemVersion)
||
(Win32VersionValue && (NtHeader->OptionalHeader.Win32VersionValue != Win32VersionValue))
||
(fEnableLargeAddresses && !(NtHeader->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE))
||
(fNoBind && !(NtHeader->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_NO_BIND))
||
(fEnableTerminalServerAware && !(NtHeader->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE))
||
(fDisableTerminalServerAware && (NtHeader->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE))
||
(fSwapRunNet && !(NtHeader->FileHeader.Characteristics & IMAGE_FILE_NET_RUN_FROM_SWAP))
||
(fSwapRunCD && !(NtHeader->FileHeader.Characteristics & IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP))
||
(fUniprocessorOnly && !(NtHeader->FileHeader.Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY))
||
(fRestrictedWorkingSet && !(NtHeader->FileHeader.Characteristics & IMAGE_FILE_AGGRESIVE_WS_TRIM))
||
(SizeOfStackReserve && (NtHeader->OptionalHeader.SizeOfStackReserve != (DWORD)SizeOfStackReserve))
||
(SizeOfStackCommit && (NtHeader->OptionalHeader.SizeOfStackCommit != (DWORD)SizeOfStackCommit)) )
{
return TRUE;
} else {
return FALSE;
}
}
BOOL
CheckIfImageHeaderChanged64(PIMAGE_NT_HEADERS64 NtHeader)
{
if ((MajorSubsystemVersion &&
NtHeader->OptionalHeader.MajorSubsystemVersion != (USHORT)MajorSubsystemVersion ||
NtHeader->OptionalHeader.MinorSubsystemVersion != (USHORT)MinorSubsystemVersion)
||
(Win32VersionValue && (NtHeader->OptionalHeader.Win32VersionValue != Win32VersionValue))
||
(fEnableLargeAddresses && !(NtHeader->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE))
||
(fNoBind && !(NtHeader->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_NO_BIND))
||
(fEnableTerminalServerAware && !(NtHeader->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE))
||
(fDisableTerminalServerAware && (NtHeader->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE))
||
(fSwapRunNet && !(NtHeader->FileHeader.Characteristics & IMAGE_FILE_NET_RUN_FROM_SWAP))
||
(fSwapRunCD && !(NtHeader->FileHeader.Characteristics & IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP))
||
(fUniprocessorOnly && !(NtHeader->FileHeader.Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY))
||
(fRestrictedWorkingSet && !(NtHeader->FileHeader.Characteristics & IMAGE_FILE_AGGRESIVE_WS_TRIM))
||
(SizeOfStackReserve && (NtHeader->OptionalHeader.SizeOfStackReserve != SizeOfStackReserve))
||
(SizeOfStackCommit && (NtHeader->OptionalHeader.SizeOfStackCommit != SizeOfStackCommit)) )
{
return TRUE;
} else {
return FALSE;
}
}
BOOL
SetImageConfigInformation32(
PLOADED_IMAGE LoadedImage,
PIMAGE_LOAD_CONFIG_DIRECTORY32 ImageConfigInformation
)
{
PIMAGE_LOAD_CONFIG_DIRECTORY32 ImageConfigData;
ULONG i;
ULONG DirectoryAddress;
PIMAGE_NT_HEADERS NtHeaders;
PIMAGE_DATA_DIRECTORY pLoadCfgDataDir;
// We can only write native loadcfg struct
ULONG V1LoadCfgLength = FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, SEHandlerTable);
ULONG NewDataSize;
if (LoadedImage->hFile == INVALID_HANDLE_VALUE) {
return FALSE;
}
ImageConfigData = (PIMAGE_LOAD_CONFIG_DIRECTORY32) ImageDirectoryEntryToData( LoadedImage->MappedAddress,
FALSE,
IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG,
&i
);
if (ImageConfigData && (i == V1LoadCfgLength)) {
if (ImageConfigInformation->Size) {
// Incoming size specified?
if (ImageConfigData->Size == ImageConfigInformation->Size) {
// Current size same as new size? Do the copy
memcpy( ImageConfigData, ImageConfigInformation, ImageConfigInformation->Size);
return TRUE;
}
if (ImageConfigData->Size > ImageConfigInformation->Size) {
// New size < old size - can't allow that
return FALSE;
}
// Last case is new size > old size - fall through and find room for new data.
} else {
// Incoming size not set - must be an V1 user.
if (ImageConfigData->Size) {
// Existing size set? Can't overwrite new data with old data
return FALSE;
}
// New and old are both V1 structs.
memcpy( ImageConfigData, ImageConfigInformation, V1LoadCfgLength);
return TRUE;
}
}
NewDataSize = ImageConfigInformation->Size ? ImageConfigInformation->Size : V1LoadCfgLength;
DirectoryAddress = GetImageUnusedHeaderBytes( LoadedImage, &i );
if (i < NewDataSize) {
return FALSE;
}
NtHeaders = LoadedImage->FileHeader;
pLoadCfgDataDir = &((PIMAGE_NT_HEADERS32)NtHeaders)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG];
pLoadCfgDataDir->VirtualAddress = DirectoryAddress;
pLoadCfgDataDir->Size = V1LoadCfgLength;
ImageConfigData = (PIMAGE_LOAD_CONFIG_DIRECTORY32) ((PCHAR)LoadedImage->MappedAddress + DirectoryAddress);
memcpy( ImageConfigData, ImageConfigInformation, sizeof( *ImageConfigData ) );
return TRUE;
}
BOOL
SetImageConfigInformation64(
PLOADED_IMAGE LoadedImage,
PIMAGE_LOAD_CONFIG_DIRECTORY64 ImageConfigInformation
)
{
PIMAGE_LOAD_CONFIG_DIRECTORY64 ImageConfigData;
ULONG i;
ULONG DirectoryAddress;
PIMAGE_NT_HEADERS NtHeaders;
PIMAGE_DATA_DIRECTORY pLoadCfgDataDir;
// We can only write native loadcfg struct
ULONG V1LoadCfgLength = FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY64, SEHandlerTable);
ULONG NewDataSize;
if (LoadedImage->hFile == INVALID_HANDLE_VALUE) {
return FALSE;
}
ImageConfigData = (PIMAGE_LOAD_CONFIG_DIRECTORY64) ImageDirectoryEntryToData( LoadedImage->MappedAddress,
FALSE,
IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG,
&i
);
if (ImageConfigData && (i == V1LoadCfgLength)) {
if (ImageConfigInformation->Size) {
// Incoming size specified?
if (ImageConfigData->Size == ImageConfigInformation->Size) {
// Current size same as new size? Do the copy
memcpy( ImageConfigData, ImageConfigInformation, ImageConfigInformation->Size);
return TRUE;
}
if (ImageConfigData->Size > ImageConfigInformation->Size) {
// New size < old size - can't allow that
return FALSE;
}
// Last case is new size > old size - fall through and find room for new data.
} else {
// Incoming size not set - must be an V1 user.
if (ImageConfigData->Size) {
// Existing size set? Can't overwrite new data with old data
return FALSE;
}
// New and old are both V1 structs.
memcpy( ImageConfigData, ImageConfigInformation, V1LoadCfgLength);
return TRUE;
}
}
NewDataSize = ImageConfigInformation->Size ? ImageConfigInformation->Size : V1LoadCfgLength;
DirectoryAddress = GetImageUnusedHeaderBytes( LoadedImage, &i );
if (i < NewDataSize) {
return FALSE;
}
NtHeaders = LoadedImage->FileHeader;
pLoadCfgDataDir = &((PIMAGE_NT_HEADERS64)NtHeaders)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG];
pLoadCfgDataDir->VirtualAddress = DirectoryAddress;
pLoadCfgDataDir->Size = V1LoadCfgLength;
ImageConfigData = (PIMAGE_LOAD_CONFIG_DIRECTORY64) ((PCHAR)LoadedImage->MappedAddress + DirectoryAddress);
memcpy( ImageConfigData, ImageConfigInformation, sizeof( *ImageConfigData ) );
return TRUE;
}
int __cdecl
main(
int argc,
char *argv[],
char *envp[]
)
{
UCHAR c;
LPSTR p, sMajor, sMinor, sReserve, sCommit;
ULONG HeaderSum;
SYSTEMTIME SystemTime;
FILETIME LastWriteTime;
DWORD OldChecksum;
PVOID pNewConfigData, pOldConfigData;
DWORD ImageConfigSize;
fUsage = FALSE;
fVerbose = FALSE;
_tzset();
if (argc <= 1) {
goto showUsage;
}
while (--argc) {
p = *++argv;
if (*p == '/' || *p == '-') {
while (c = *++p)
switch (toupper( c )) {
case '?':
fUsage = TRUE;
break;
case 'A':
if (--argc) {
ImageProcessAffinityMask = ConvertNum( *++argv );
if (ImageProcessAffinityMask == 0) {
fprintf( stderr, "IMAGECFG: invalid affinity mask specified to /a switch.\n" );
fUsage = TRUE;
}
} else {
fprintf( stderr, "IMAGECFG: /a switch missing argument.\n" );
fUsage = TRUE;
}
break;
case 'C':
if (--argc) {
if (sscanf( *++argv, "%x", &Win32CSDVerValue ) != 1) {
fprintf( stderr, "IMAGECFG: invalid version string specified to /c switch.\n" );
fUsage = TRUE;
}
} else {
fprintf( stderr, "IMAGECFG: /c switch missing argument.\n" );
fUsage = TRUE;
}
break;
case 'D':
if (argc >= 2) {
argc -= 2;
DeCommitFreeBlockThreshold = ConvertNum( *++argv );
DeCommitTotalFreeThreshold = ConvertNum( *++argv );
} else {
fprintf( stderr, "IMAGECFG: /d switch missing arguments.\n" );
fUsage = TRUE;
}
break;
case 'G':
if (argc >= 2) {
argc -= 2;
GlobalFlagsClear = (ULONG) ConvertNum( *++argv );
GlobalFlagsSet = (ULONG) ConvertNum( *++argv );
} else {
fprintf( stderr, "IMAGECFG: /g switch missing arguments.\n" );
fUsage = TRUE;
}
break;
case 'H':
if (argc > 2) {
INT flag = -1;
if (sscanf( *++argv, "%d", &flag ) != 1) {
fprintf( stderr, "IMAGECFG: invalid option string specified to /h switch.\n" );
fUsage = TRUE;
} else {
--argc;
if (flag == 0) {
fDisableTerminalServerAware = TRUE;
} else if (flag == 1) {
fEnableTerminalServerAware = TRUE;
} else {
fprintf( stderr, "IMAGECFG: /h switch invalid argument.\n" );
fUsage = TRUE;
}
}
} else {
fprintf( stderr, "IMAGECFG: /h switch missing argument.\n" );
fUsage = TRUE;
}
break;
case 'K':
if (--argc) {
sReserve = *++argv;
sCommit = strchr( sReserve, '.' );
if (sCommit != NULL) {
*sCommit++ = '\0';
SizeOfStackCommit = ConvertNum( sCommit );
SizeOfStackCommit = ((SizeOfStackCommit + 0x00000FFFui64) & ~0x00000FFFui64);
if (SizeOfStackCommit == 0) {
fprintf( stderr, "IMAGECFG: invalid stack commit size specified to /k switch.\n" );
fUsage = TRUE;
}
}
SizeOfStackReserve = ConvertNum( sReserve );
SizeOfStackReserve = ((SizeOfStackReserve + 0x0000FFFFui64) & ~0x0000FFFFui64);
if (SizeOfStackReserve == 0) {
fprintf( stderr, "IMAGECFG: invalid stack reserve size specified to /k switch.\n" );
fUsage = TRUE;
}
} else {
fprintf( stderr, "IMAGECFG: /w switch missing argument.\n" );
fUsage = TRUE;
}
break;
case 'L':
fEnableLargeAddresses = TRUE;
break;
case 'M':
if (--argc) {
MaximumAllocationSize = ConvertNum( *++argv );
} else {
fprintf( stderr, "IMAGECFG: /m switch missing argument.\n" );
fUsage = TRUE;
}
break;
case 'N':
fNoBind = TRUE;
break;
case 'O':
if (--argc) {
CriticalSectionDefaultTimeout = (ULONG) ConvertNum( *++argv );
} else {
fprintf( stderr, "IMAGECFG: /o switch missing argument.\n" );
fUsage = TRUE;
}
break;
case 'P':
if (--argc) {
ProcessHeapFlags = (ULONG) ConvertNum( *++argv );
} else {
fprintf( stderr, "IMAGECFG: /p switch missing argument.\n" );
fUsage = TRUE;
}
break;
case 'Q':
fQuiet = TRUE;
break;
case 'R':
fRestrictedWorkingSet = TRUE;
break;
case 'S':
if (--argc) {
SymbolPath = *++argv;
} else {
fprintf( stderr, "IMAGECFG: /s switch missing path argument.\n" );
fUsage = TRUE;
}
break;
case 'T':
if (--argc) {
VirtualMemoryThreshold = ConvertNum( *++argv );
} else {
fprintf( stderr, "IMAGECFG: /t switch missing argument.\n" );
fUsage = TRUE;
}
break;
case 'U':
fUniprocessorOnly = TRUE;
break;
case 'V':
if (--argc) {
sMajor = *++argv;
sMinor = strchr( sMajor, '.' );
if (sMinor != NULL) {
*sMinor++ = '\0';
MinorSubsystemVersion = (ULONG) ConvertNum( sMinor );
}
MajorSubsystemVersion = (ULONG) ConvertNum( sMajor );
if (MajorSubsystemVersion == 0) {
fprintf( stderr, "IMAGECFG: invalid version string specified to /v switch.\n" );
fUsage = TRUE;
}
} else {
fprintf( stderr, "IMAGECFG: /v switch missing argument.\n" );
fUsage = TRUE;
}
break;
case 'W':
if (--argc) {
if (sscanf( *++argv, "%x", &Win32VersionValue ) != 1) {
fprintf( stderr, "IMAGECFG: invalid version string specified to /w switch.\n" );
fUsage = TRUE;
}
} else {
fprintf( stderr, "IMAGECFG: /w switch missing argument.\n" );
fUsage = TRUE;
}
break;
case 'X':
fSwapRunNet = TRUE;
break;
case 'Y':
fSwapRunCD = TRUE;
break;
default:
fprintf( stderr, "IMAGECFG: Invalid switch - /%c\n", c );
fUsage = TRUE;
break;
}
if ( fUsage ) {
showUsage:
fprintf( stderr,
"usage: IMAGECFG [switches] image-names... \n"
" [-?] display this message\n"
" [-a Process Affinity mask value in hex]\n"
" [-c Win32 GetVersionEx Service Pack return value in hex]\n"
" [-d decommit thresholds]\n"
" [-g bitsToClear bitsToSet]\n"
" [-h 1|0 (Enable/Disable Terminal Server Compatible bit)\n"
" [-k StackReserve[.StackCommit]\n"
" [-l enable large (>2GB) addresses\n"
" [-m maximum allocation size]\n"
" [-n bind no longer allowed on this image\n"
" [-o default critical section timeout\n"
" [-p process heap flags]\n"
" [-q only print config info if changed\n"
" [-r run with restricted working set]\n"
" [-s path to symbol files]\n"
" [-t VirtualAlloc threshold]\n"
" [-u Marks image as uniprocessor only]\n"
" [-v MajorVersion.MinorVersion]\n"
" [-w Win32 GetVersion return value in hex]\n"
" [-x Mark image as Net - Run From Swapfile\n"
" [-y Mark image as Removable - Run From Swapfile\n"
);
exit( 1 );
}
} else {
//
// Map and load the current image
//
CurrentImageName = p;
if (MapAndLoad( CurrentImageName,
NULL,
&CurrentImage,
FALSE,
TRUE // Read only
) )
{
if (CurrentImage.FileHeader->OptionalHeader.Magic == IMAGE_ROM_OPTIONAL_HDR_MAGIC) {
// Don't muck with ROM images.
UnMapAndLoad( &CurrentImage );
continue;
}
if (CurrentImage.FileHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
f64bitImage = TRUE;
}
pNewConfigData = malloc(f64bitImage ? sizeof(IMAGE_LOAD_CONFIG_DIRECTORY64) : sizeof(IMAGE_LOAD_CONFIG_DIRECTORY32));
if (!pNewConfigData) {
printf("Out of memory\n");
exit(-1);
}
pOldConfigData = ImageDirectoryEntryToData(CurrentImage.MappedAddress,
FALSE,
IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG,
&ImageConfigSize);
if (pOldConfigData) {
if (!fQuiet) {
if (f64bitImage) {
DisplayConfigInfo64(pOldConfigData);
} else {
DisplayConfigInfo32(pOldConfigData);
}
}
if (((PIMAGE_LOAD_CONFIG_DIRECTORY)pOldConfigData)->Size) {
// New format - Size is the real size.
ImageConfigSize = ((PIMAGE_LOAD_CONFIG_DIRECTORY)pOldConfigData)->Size;
}
memcpy(pNewConfigData, pOldConfigData, ImageConfigSize);
} else {
ZeroMemory(pNewConfigData, f64bitImage ? sizeof(IMAGE_LOAD_CONFIG_DIRECTORY64) : sizeof(IMAGE_LOAD_CONFIG_DIRECTORY32));
((PIMAGE_LOAD_CONFIG_DIRECTORY)pNewConfigData)->Size = f64bitImage ? sizeof(IMAGE_LOAD_CONFIG_DIRECTORY64) : sizeof(IMAGE_LOAD_CONFIG_DIRECTORY32);
}
fConfigInfoChanged = f64bitImage ? CheckIfConfigInfoChanged64(pNewConfigData) : CheckIfConfigInfoChanged32(pNewConfigData);
fImageHeaderChanged = f64bitImage ?
CheckIfImageHeaderChanged64((PIMAGE_NT_HEADERS64)&CurrentImage.FileHeader) :
CheckIfImageHeaderChanged32((PIMAGE_NT_HEADERS32)&CurrentImage.FileHeader);
UnMapAndLoad( &CurrentImage );
if (fConfigInfoChanged || fImageHeaderChanged) {
if (MapAndLoad( CurrentImageName, NULL, &CurrentImage, FALSE, FALSE )) {
// Set Load Config data
if (GlobalFlagsClear) {
if (f64bitImage) {
((PIMAGE_LOAD_CONFIG_DIRECTORY64)pNewConfigData)->GlobalFlagsClear = GlobalFlagsClear;
} else {
((PIMAGE_LOAD_CONFIG_DIRECTORY32)pNewConfigData)->GlobalFlagsClear = GlobalFlagsClear;
}
}
if (GlobalFlagsSet) {
if (f64bitImage) {
((PIMAGE_LOAD_CONFIG_DIRECTORY64)pNewConfigData)->GlobalFlagsSet = GlobalFlagsSet;
} else {
((PIMAGE_LOAD_CONFIG_DIRECTORY32)pNewConfigData)->GlobalFlagsSet = GlobalFlagsSet;
}
}
if (CriticalSectionDefaultTimeout) {
if (f64bitImage) {
((PIMAGE_LOAD_CONFIG_DIRECTORY64)pNewConfigData)->CriticalSectionDefaultTimeout = CriticalSectionDefaultTimeout;
} else {
((PIMAGE_LOAD_CONFIG_DIRECTORY32)pNewConfigData)->CriticalSectionDefaultTimeout = CriticalSectionDefaultTimeout;
}
}
if (ProcessHeapFlags) {
if (f64bitImage) {
((PIMAGE_LOAD_CONFIG_DIRECTORY64)pNewConfigData)->ProcessHeapFlags = ProcessHeapFlags;
} else {
((PIMAGE_LOAD_CONFIG_DIRECTORY32)pNewConfigData)->ProcessHeapFlags = ProcessHeapFlags;
}
}
if (DeCommitFreeBlockThreshold) {
if (f64bitImage) {
((PIMAGE_LOAD_CONFIG_DIRECTORY64)pNewConfigData)->DeCommitFreeBlockThreshold = DeCommitFreeBlockThreshold;
} else {
((PIMAGE_LOAD_CONFIG_DIRECTORY32)pNewConfigData)->DeCommitFreeBlockThreshold = (DWORD)DeCommitFreeBlockThreshold;
}
}
if (DeCommitTotalFreeThreshold) {
if (f64bitImage) {
((PIMAGE_LOAD_CONFIG_DIRECTORY64)pNewConfigData)->DeCommitTotalFreeThreshold = DeCommitTotalFreeThreshold;
} else {
((PIMAGE_LOAD_CONFIG_DIRECTORY32)pNewConfigData)->DeCommitTotalFreeThreshold = (DWORD)DeCommitTotalFreeThreshold;
}
}
if (MaximumAllocationSize) {
if (f64bitImage) {
((PIMAGE_LOAD_CONFIG_DIRECTORY64)pNewConfigData)->MaximumAllocationSize = MaximumAllocationSize;
} else {
((PIMAGE_LOAD_CONFIG_DIRECTORY32)pNewConfigData)->MaximumAllocationSize = (DWORD)MaximumAllocationSize;
}
}
if (VirtualMemoryThreshold) {
if (f64bitImage) {
((PIMAGE_LOAD_CONFIG_DIRECTORY64)pNewConfigData)->VirtualMemoryThreshold = VirtualMemoryThreshold;
} else {
((PIMAGE_LOAD_CONFIG_DIRECTORY32)pNewConfigData)->VirtualMemoryThreshold = (DWORD)VirtualMemoryThreshold;
}
}
if (ImageProcessAffinityMask) {
if (f64bitImage) {
((PIMAGE_LOAD_CONFIG_DIRECTORY64)pNewConfigData)->ProcessAffinityMask = ImageProcessAffinityMask;
} else {
((PIMAGE_LOAD_CONFIG_DIRECTORY32)pNewConfigData)->ProcessAffinityMask = (DWORD)ImageProcessAffinityMask;
}
}
if (Win32CSDVerValue != 0) {
if (f64bitImage) {
((PIMAGE_LOAD_CONFIG_DIRECTORY64)pNewConfigData)->CSDVersion = (USHORT)Win32CSDVerValue;
} else {
((PIMAGE_LOAD_CONFIG_DIRECTORY32)pNewConfigData)->CSDVersion = (USHORT)Win32CSDVerValue;
}
}
// Set File header values
if (fEnableLargeAddresses) {
CurrentImage.FileHeader->FileHeader.Characteristics |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
}
if (fSwapRunNet) {
CurrentImage.FileHeader->FileHeader.Characteristics |= IMAGE_FILE_NET_RUN_FROM_SWAP;
}
if (fSwapRunCD) {
CurrentImage.FileHeader->FileHeader.Characteristics |= IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP;
}
if (fUniprocessorOnly) {
CurrentImage.FileHeader->FileHeader.Characteristics |= IMAGE_FILE_UP_SYSTEM_ONLY;
}
if (fRestrictedWorkingSet) {
CurrentImage.FileHeader->FileHeader.Characteristics |= IMAGE_FILE_AGGRESIVE_WS_TRIM;
}
// Set Optional header values
if (fNoBind) {
if (f64bitImage) {
((PIMAGE_NT_HEADERS64)CurrentImage.FileHeader)->OptionalHeader.DllCharacteristics |= IMAGE_DLLCHARACTERISTICS_NO_BIND;
} else {
((PIMAGE_NT_HEADERS32)CurrentImage.FileHeader)->OptionalHeader.DllCharacteristics |= IMAGE_DLLCHARACTERISTICS_NO_BIND;
}
}
if (fEnableTerminalServerAware) {
if (f64bitImage) {
((PIMAGE_NT_HEADERS64)CurrentImage.FileHeader)->OptionalHeader.DllCharacteristics |= IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE;
} else {
((PIMAGE_NT_HEADERS32)CurrentImage.FileHeader)->OptionalHeader.DllCharacteristics |= IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE;
}
}
if (fDisableTerminalServerAware) {
if (f64bitImage) {
((PIMAGE_NT_HEADERS64)CurrentImage.FileHeader)->OptionalHeader.DllCharacteristics |= IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE;
} else {
((PIMAGE_NT_HEADERS32)CurrentImage.FileHeader)->OptionalHeader.DllCharacteristics |= IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE;
}
}
if (MajorSubsystemVersion != 0) {
if (f64bitImage) {
((PIMAGE_NT_HEADERS64)CurrentImage.FileHeader)->OptionalHeader.MajorSubsystemVersion = (USHORT)MajorSubsystemVersion;
((PIMAGE_NT_HEADERS64)CurrentImage.FileHeader)->OptionalHeader.MinorSubsystemVersion = (USHORT)MinorSubsystemVersion;
} else {
((PIMAGE_NT_HEADERS32)CurrentImage.FileHeader)->OptionalHeader.MajorSubsystemVersion = (USHORT)MajorSubsystemVersion;
((PIMAGE_NT_HEADERS32)CurrentImage.FileHeader)->OptionalHeader.MinorSubsystemVersion = (USHORT)MinorSubsystemVersion;
}
}
if (Win32VersionValue != 0) {
if (f64bitImage) {
((PIMAGE_NT_HEADERS64)CurrentImage.FileHeader)->OptionalHeader.Win32VersionValue = Win32VersionValue;
} else {
((PIMAGE_NT_HEADERS32)CurrentImage.FileHeader)->OptionalHeader.Win32VersionValue = Win32VersionValue;
}
}
if (SizeOfStackReserve) {
if (f64bitImage) {
((PIMAGE_NT_HEADERS64)CurrentImage.FileHeader)->OptionalHeader.SizeOfStackReserve = SizeOfStackReserve;
} else {
((PIMAGE_NT_HEADERS32)CurrentImage.FileHeader)->OptionalHeader.SizeOfStackReserve = (DWORD)SizeOfStackReserve;
}
}
if (SizeOfStackCommit) {
if (f64bitImage) {
((PIMAGE_NT_HEADERS64)CurrentImage.FileHeader)->OptionalHeader.SizeOfStackCommit = SizeOfStackCommit;
} else {
((PIMAGE_NT_HEADERS32)CurrentImage.FileHeader)->OptionalHeader.SizeOfStackCommit = (DWORD)SizeOfStackCommit;
}
}
if (fConfigInfoChanged) {
if (f64bitImage) {
if (SetImageConfigInformation64( &CurrentImage, pNewConfigData )) {
if (!fQuiet) {
printf( "%s updated with the following configuration information:\n", CurrentImageName );
DisplayConfigInfo64(pNewConfigData);
}
} else {
fprintf( stderr, "IMAGECFG: Unable to update configuration information in image.\n" );
}
} else {
if (SetImageConfigInformation32( &CurrentImage, pNewConfigData )) {
if (!fQuiet) {
printf( "%s updated with the following configuration information:\n", CurrentImageName );
DisplayConfigInfo32(pNewConfigData);
}
} else {
fprintf( stderr, "IMAGECFG: Unable to update configuration information in image.\n" );
}
}
}
//
// recompute the checksum.
//
if (f64bitImage) {
OldChecksum = ((PIMAGE_NT_HEADERS64)CurrentImage.FileHeader)->OptionalHeader.CheckSum;
((PIMAGE_NT_HEADERS64)CurrentImage.FileHeader)->OptionalHeader.CheckSum = 0;
CheckSumMappedFile(
(PVOID)CurrentImage.MappedAddress,
CurrentImage.SizeOfImage,
&HeaderSum,
&((PIMAGE_NT_HEADERS64)CurrentImage.FileHeader)->OptionalHeader.CheckSum
);
} else {
OldChecksum = ((PIMAGE_NT_HEADERS32)CurrentImage.FileHeader)->OptionalHeader.CheckSum;
((PIMAGE_NT_HEADERS32)CurrentImage.FileHeader)->OptionalHeader.CheckSum = 0;
CheckSumMappedFile(
(PVOID)CurrentImage.MappedAddress,
CurrentImage.SizeOfImage,
&HeaderSum,
&((PIMAGE_NT_HEADERS32)CurrentImage.FileHeader)->OptionalHeader.CheckSum
);
}
// And update the .dbg file (if requested)
if (SymbolPath &&
CurrentImage.FileHeader->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED) {
if (UpdateDebugInfoFileEx( CurrentImageName,
SymbolPath,
DebugFilePath,
(PIMAGE_NT_HEADERS32)CurrentImage.FileHeader,
OldChecksum
)
) {
if (GetLastError() == ERROR_INVALID_DATA) {
printf( "Warning: Old checksum did not match for %s\n", DebugFilePath);
}
printf( "Updated symbols for %s\n", DebugFilePath );
} else {
printf( "Unable to update symbols: %s\n", DebugFilePath );
}
}
GetSystemTime( &SystemTime );
if (SystemTimeToFileTime( &SystemTime, &LastWriteTime )) {
SetFileTime( CurrentImage.hFile, NULL, NULL, &LastWriteTime );
}
UnMapAndLoad( &CurrentImage );
}
}
} else
if (!CurrentImage.fDOSImage) {
fprintf( stderr, "IMAGECFG: unable to map and load %s GetLastError= %d\n", CurrentImageName, GetLastError() );
} else {
fprintf( stderr,
"IMAGECFG: unable to modify DOS or Windows image file - %s\n",
CurrentImageName
);
}
}
}
exit( 1 );
return 1;
}
#define STANDALONE_MAP
#include <mapi.c>