- BindImage & friends refactoring of my original code. Fixed two or three dozen bugs, stopped making assumptions about everything, actually checked for failure, used dynamic allocation instead of 32 static structures, fixed a lot of broken code, fixed some helper functions, made the code as 64-bit compatible as I could (checked with msvc WP64 + prefast).
- Remove internal.c and use NDK instead
- Remove debug.c and symbol.c like WINE have done
- Rewrite the entire exports file to update it for XP. Forward almost all the functions to dbghelp, like WINE have done (note: windows DLL used delayed imports instead).
- Cleanup source to add implemented/unimplemented tags, source header, and precompiled header.
- Sync with latest code from WINE.
Tested with Quicken 2004 & its patches (which make extensive use of BindImage) as well as random bindings of some applications on my disk. Worked perfectly in Windows.
svn path=/trunk/; revision=19025
/*
- * IMAGEHLP library
- *
- * Copyright 1998 Patrik Stridvall
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: Imagehlp Libary
+ * FILE: lib/imagehlp/access.c
+ * PURPOSE: Image (un)load/mapping and data directory/section access
+ * PROGRAMMER: Patrik Stridvall
*/
-#include <stdarg.h>
-#include <string.h>
-#include "windef.h"
-#include "winbase.h"
-#include "winnt.h"
-#include "winerror.h"
-#include "wine/debug.h"
-#include "imagehlp.h"
-
-/* Couple of Hacks */
-extern inline DWORD WINAPI GetLastError(void)
-{
- DWORD ret;
- __asm__ __volatile__( ".byte 0x64\n\tmovl 0x60,%0" : "=r" (ret) );
- return ret;
-}
+/* INCLUDES ******************************************************************/
-#define InitializeListHead(ListHead) (\
- (ListHead)->Flink = (ListHead)->Blink = (ListHead))
-
-#define InsertTailList(ListHead,Entry) {\
- PLIST_ENTRY _EX_Blink;\
- PLIST_ENTRY _EX_ListHead;\
- _EX_ListHead = (ListHead);\
- _EX_Blink = _EX_ListHead->Blink;\
- (Entry)->Flink = _EX_ListHead;\
- (Entry)->Blink = _EX_Blink;\
- _EX_Blink->Flink = (Entry);\
- _EX_ListHead->Blink = (Entry);\
- }
+#include "precomp.h"
-WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
+//#define NDEBUG
+#include <debug.h>
-/***********************************************************************
- * Data
- */
+/* DATA **********************************************************************/
-static PLOADED_IMAGE IMAGEHLP_pFirstLoadedImage=NULL;
-static PLOADED_IMAGE IMAGEHLP_pLastLoadedImage=NULL;
-
-static LOADED_IMAGE IMAGEHLP_EmptyLoadedImage = {
- NULL, /* ModuleName */
- 0, /* hFile */
- NULL, /* MappedAddress */
- NULL, /* FileHeader */
- NULL, /* LastRvaSection */
- 0, /* NumberOfSections */
- NULL, /* Sections */
- 1, /* Characteristics */
- FALSE, /* fSystemImage */
- FALSE, /* fDOSImage */
- { &IMAGEHLP_EmptyLoadedImage.Links, &IMAGEHLP_EmptyLoadedImage.Links }, /* Links */
- 148, /* SizeOfImage; */
-};
-
-extern HANDLE IMAGEHLP_hHeap;
BOOLEAN DllListInitialized;
LIST_ENTRY ImageLoadListHead;
-/***********************************************************************
- * EnumerateLoadedModules (IMAGEHLP.@)
- */
-BOOL WINAPI EnumerateLoadedModules(
- HANDLE hProcess,
- PENUMLOADED_MODULES_CALLBACK EnumLoadedModulesCallback,
- PVOID UserContext)
+/* FUNCTIONS *****************************************************************/
+
+PVOID
+IMAGEAPI
+ImageDirectoryEntryToData32(PVOID Base,
+ BOOLEAN MappedAsImage,
+ USHORT DirectoryEntry,
+ PULONG Size,
+ PIMAGE_SECTION_HEADER *FoundHeader OPTIONAL,
+ PIMAGE_FILE_HEADER FileHeader,
+ PIMAGE_OPTIONAL_HEADER OptionalHeader)
{
- FIXME("(%p, %p, %p): stub\n",
- hProcess, EnumLoadedModulesCallback, UserContext
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ ULONG i;
+ PIMAGE_SECTION_HEADER CurrentSection;
+ ULONG DirectoryEntryVA;
+
+ /* Check if this entry is invalid */
+ if (DirectoryEntry >= OptionalHeader->NumberOfRvaAndSizes)
+ {
+ /* Nothing found */
+ *Size = 0;
+ return NULL;
+ }
+
+ /* Get the VA of the Directory Requested */
+ DirectoryEntryVA = OptionalHeader->DataDirectory[DirectoryEntry].VirtualAddress;
+ if (!DirectoryEntryVA)
+ {
+ /* It doesn't exist */
+ *Size = 0;
+ return NULL;
+ }
+
+ /* Get the size of the Directory Requested */
+ *Size = OptionalHeader->DataDirectory[DirectoryEntry].Size;
+
+ /* Check if it was mapped as an image or if the entry is within the headers */
+ if ((MappedAsImage) || (DirectoryEntryVA < OptionalHeader->SizeOfHeaders))
+ {
+ /* No header found */
+ if (FoundHeader) *FoundHeader = NULL;
+
+ /* And simply return the VA */
+ return (PVOID)((ULONG_PTR)Base + DirectoryEntryVA);
+ }
+
+ /* Read the first Section */
+ CurrentSection = (PIMAGE_SECTION_HEADER)((ULONG_PTR)OptionalHeader +
+ FileHeader->SizeOfOptionalHeader);
+
+ /* Loop through every section*/
+ for (i = 0; i < FileHeader->NumberOfSections; i++)
+ {
+ /* If the Directory VA is located inside this section's VA, then this section belongs to this Directory */
+ if ((DirectoryEntryVA >= CurrentSection->VirtualAddress) &&
+ (DirectoryEntryVA < (CurrentSection->VirtualAddress +
+ CurrentSection->SizeOfRawData)))
+ {
+ /* Return the section header */
+ if (FoundHeader) *FoundHeader = CurrentSection;
+ return ((PVOID)((ULONG_PTR)Base +
+ (DirectoryEntryVA - CurrentSection->VirtualAddress) +
+ CurrentSection->PointerToRawData));
+ }
+
+ /* Move to the next section */
+ CurrentSection++;
+ }
+
+ /* If we got here, then we didn't find anything */
+ return NULL;
}
-/***********************************************************************
- * GetTimestampForLoadedLibrary (IMAGEHLP.@)
+/*
+ * @unimplemented
*/
-DWORD WINAPI GetTimestampForLoadedLibrary(HMODULE Module)
+DWORD
+IMAGEAPI
+GetTimestampForLoadedLibrary(HMODULE Module)
{
- FIXME("(%p): stub\n", Module);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
+ UNIMPLEMENTED;
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
}
-/***********************************************************************
- * GetImageConfigInformation (IMAGEHLP.@)
+/*
+ * @unimplemented
*/
-BOOL WINAPI GetImageConfigInformation(
- PLOADED_IMAGE LoadedImage,
- PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation)
+BOOL
+IMAGEAPI
+GetImageConfigInformation(PLOADED_IMAGE LoadedImage,
+ PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation)
{
- FIXME("(%p, %p): stub\n",
- LoadedImage, ImageConfigInformation
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ UNIMPLEMENTED;
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
}
-/***********************************************************************
- * GetImageUnusedHeaderBytes (IMAGEHLP.@)
+/*
+ * @implemented
*/
DWORD
-WINAPI
-GetImageUnusedHeaderBytes(
- PLOADED_IMAGE LoadedImage,
- LPDWORD SizeUnusedHeaderBytes
- )
+IMAGEAPI
+GetImageUnusedHeaderBytes(PLOADED_IMAGE LoadedImage,
+ LPDWORD SizeUnusedHeaderBytes)
{
- DWORD FirstFreeByte;
- PIMAGE_OPTIONAL_HEADER OptionalHeader32 = NULL;
- PIMAGE_NT_HEADERS NtHeaders;
- ULONG i;
+ SIZE_T FirstFreeByte;
+ PIMAGE_OPTIONAL_HEADER OptionalHeader = NULL;
+ PIMAGE_NT_HEADERS NtHeaders;
+ ULONG i;
- /* Read the NT Headers */
+ /* Read the NT Headers */
NtHeaders = LoadedImage->FileHeader;
- /* Find the first free byte, which is after all the headers and sections */
- FirstFreeByte = (ULONG_PTR)NtHeaders - (ULONG_PTR)LoadedImage->MappedAddress +
- FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader) +
- NtHeaders->FileHeader.SizeOfOptionalHeader +
- NtHeaders->FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
-
- /* Get the Optional Header */
- OptionalHeader32 = &LoadedImage->FileHeader->OptionalHeader;
-
- /* There is the possibilty that one of the Data Directories is in the PE Header
- itself, so we'll need to find such a case and add it to our PE used space */
- for ( i = 0; i<OptionalHeader32->NumberOfRvaAndSizes; i++ ) {
-
- /* If the VA is less then the size of headers, then the data is inside the PE header */
- if (OptionalHeader32->DataDirectory[i].VirtualAddress < OptionalHeader32->SizeOfHeaders) {
-
- /* However, make sure it's not 0, which means it doesnt actually exist */
- if (OptionalHeader32->DataDirectory[i].VirtualAddress >= FirstFreeByte) {
-
- /* Our first empty byte is after this Directory Data then */
- FirstFreeByte = OptionalHeader32->DataDirectory[i].VirtualAddress +
- OptionalHeader32->DataDirectory[i].Size;
- }
+ /* Find the first free byte, which is after all the headers and sections */
+ FirstFreeByte = (ULONG_PTR)NtHeaders -
+ (ULONG_PTR)LoadedImage->MappedAddress +
+ FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader) +
+ NtHeaders->FileHeader.SizeOfOptionalHeader +
+ NtHeaders->FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
+
+ /* Get the Optional Header */
+ OptionalHeader = &LoadedImage->FileHeader->OptionalHeader;
+
+ /*
+ * There is the possibilty that one of the Data Directories is in the PE Header
+ * itself, so we'll need to find such a case and add it to our PE used space
+ */
+ for (i = 0; i < OptionalHeader->NumberOfRvaAndSizes; i++)
+ {
+ /* If the VA is less then the size of headers, then the data is inside the PE header */
+ if (OptionalHeader->DataDirectory[i].VirtualAddress <
+ OptionalHeader->SizeOfHeaders)
+ {
+ /* However, make sure it's not 0, which means it doesnt actually exist */
+ if (OptionalHeader->DataDirectory[i].VirtualAddress >=
+ FirstFreeByte)
+ {
+ /* Our first empty byte is after this Directory Data then */
+ FirstFreeByte = OptionalHeader->DataDirectory[i].VirtualAddress +
+ OptionalHeader->DataDirectory[i].Size;
}
}
+ }
- /* Return the unused Header Bytes */
- *SizeUnusedHeaderBytes = OptionalHeader32->SizeOfHeaders - FirstFreeByte;
+ /* Return the unused Header Bytes */
+ *SizeUnusedHeaderBytes = OptionalHeader->SizeOfHeaders - (DWORD)FirstFreeByte;
- /* And return the first free byte*/
- return FirstFreeByte;
+ /* And return the first free byte*/
+ return (DWORD)FirstFreeByte;
}
-/***********************************************************************
- * ImageDirectoryEntryToData (IMAGEHLP.@)
+/*
+ * @implemented
*/
PVOID
-WINAPI
-ImageDirectoryEntryToData(
- PVOID Base,
- BOOLEAN MappedAsImage,
- USHORT DirectoryEntry,
- PULONG Size
- )
+IMAGEAPI
+ImageDirectoryEntryToData(PVOID Base,
+ BOOLEAN MappedAsImage,
+ USHORT DirectoryEntry,
+ PULONG Size)
{
- return ImageDirectoryEntryToDataEx(Base, MappedAsImage, DirectoryEntry, Size, NULL);
+ /* Let the extended function handle it */
+ return ImageDirectoryEntryToDataEx(Base,
+ MappedAsImage,
+ DirectoryEntry,
+ Size,
+ NULL);
}
-/***********************************************************************
- * RosImageDirectoryEntryToDataEx (IMAGEHLP.@)
+/*
+ * @implemented
*/
PVOID
-WINAPI
-ImageDirectoryEntryToDataEx (
- IN PVOID Base,
- IN BOOLEAN MappedAsImage,
- IN USHORT DirectoryEntry,
- OUT PULONG Size,
- OUT PIMAGE_SECTION_HEADER *FoundSection OPTIONAL
- )
+IMAGEAPI
+ImageDirectoryEntryToDataEx(IN PVOID Base,
+ IN BOOLEAN MappedAsImage,
+ IN USHORT DirectoryEntry,
+ OUT PULONG Size,
+ OUT PIMAGE_SECTION_HEADER *FoundSection OPTIONAL)
{
- PIMAGE_NT_HEADERS NtHeader;
- PIMAGE_FILE_HEADER FileHeader;
- PIMAGE_OPTIONAL_HEADER OptionalHeader;
+ PIMAGE_NT_HEADERS NtHeader;
+ PIMAGE_FILE_HEADER FileHeader;
+ PIMAGE_OPTIONAL_HEADER OptionalHeader;
+ /* Get the optional header ourselves */
NtHeader = ImageNtHeader(Base);
FileHeader = &NtHeader->FileHeader;
OptionalHeader = &NtHeader->OptionalHeader;
- return (ImageDirectoryEntryToData32(Base,
- MappedAsImage,
- DirectoryEntry,
- Size,
- FoundSection,
- FileHeader,
- OptionalHeader));
+ /* FIXME: Read image type and call appropriate function (32, 64, ROM) */
+ return ImageDirectoryEntryToData32(Base,
+ MappedAsImage,
+ DirectoryEntry,
+ Size,
+ FoundSection,
+ FileHeader,
+ OptionalHeader);
}
-/***********************************************************************
- * RosImageDirectoryEntryToDataEx (IMAGEHLP.@)
- */
-PVOID
-STDCALL
-ImageDirectoryEntryToData32 (
- PVOID Base,
- BOOLEAN MappedAsImage,
- USHORT DirectoryEntry,
- PULONG Size,
- PIMAGE_SECTION_HEADER *FoundHeader OPTIONAL,
- PIMAGE_FILE_HEADER FileHeader,
- PIMAGE_OPTIONAL_HEADER OptionalHeader
- )
-{
- ULONG i;
- PIMAGE_SECTION_HEADER CurrentSection;
- ULONG DirectoryEntryVA;
-
- /* Get the VA of the Directory Requested */
- DirectoryEntryVA = OptionalHeader->DataDirectory[DirectoryEntry].VirtualAddress;
-
- /* Get the size of the Directory Requested */
- *Size = OptionalHeader->DataDirectory[DirectoryEntry].Size;
-
- /* Return VA if Mapped as Image*/
- if (MappedAsImage || DirectoryEntryVA < OptionalHeader->SizeOfHeaders) {
- if (FoundHeader) {
- *FoundHeader = NULL;
- }
- return (PVOID)((ULONG_PTR)Base + DirectoryEntryVA);
- }
-
- /* Read the first Section */
- CurrentSection = (PIMAGE_SECTION_HEADER)((ULONG_PTR)OptionalHeader + FileHeader->SizeOfOptionalHeader);
-
- /* Loop through every section*/
- for (i=0; i<FileHeader->NumberOfSections; i++) {
-
- /* If the Directory VA is located inside this section's VA, then this section belongs to this Directory */
- if (DirectoryEntryVA >= CurrentSection->VirtualAddress &&
- DirectoryEntryVA < CurrentSection->VirtualAddress + CurrentSection->SizeOfRawData) {
- if (FoundHeader) {
- *FoundHeader = CurrentSection;
- }
- //return( (PVOID)((ULONG_PTR)Base + (DirectoryAddress - NtSection->VirtualAddress) + NtSection->PointerToRawData) );
- return ((PVOID)((ULONG_PTR)Base + (DirectoryEntryVA - CurrentSection->VirtualAddress) + CurrentSection->PointerToRawData));
- }
- ++CurrentSection;
- }
- return(NULL);
-}
-/***********************************************************************
- * ImageLoad (IMAGEHLP.@)
+/*
+ * @implemented
*/
-PLOADED_IMAGE WINAPI ImageLoad(LPSTR DllName, LPSTR DllPath)
+PLOADED_IMAGE
+IMAGEAPI
+ImageLoad(LPSTR DllName,
+ LPSTR DllPath)
{
- PLIST_ENTRY Head,Next;
+ PLIST_ENTRY Head, Next;
PLOADED_IMAGE LoadedImage;
+ CHAR Drive[_MAX_DRIVE], Dir[_MAX_DIR], Filename[_MAX_FNAME], Ext[_MAX_EXT];
+ BOOL CompleteName = TRUE;
+ CHAR FullName[MAX_PATH];
- /* Initialize the List Head */
- if (!DllListInitialized) {
+ /* Initialize the List Head */
+ if (!DllListInitialized)
+ {
InitializeListHead(&ImageLoadListHead);
DllListInitialized = TRUE;
}
- /* Move to the Next DLL */
+ /* Move to the Next DLL */
Head = &ImageLoadListHead;
Next = Head->Flink;
+ DPRINT("Trying to find library: %s in current ListHead \n", DllName);
- //FIXME("Trying to find library: %s in current ListHead \n", DllName);
+ /* Split the path */
+ _splitpath(DllName, Drive, Dir, Filename, Ext);
- /* Check if we already Loaded it */
- while (Next != Head) {
+ /* Check if we only got a name */
+ if (!strlen(Drive) && !strlen(Dir)) CompleteName = FALSE;
- /* Get the Loaded Image Structure */
+ /* Check if we already Loaded it */
+ while (Next != Head)
+ {
+ /* Get the Loaded Image Structure */
LoadedImage = CONTAINING_RECORD(Next, LOADED_IMAGE, Links);
- //FIXME("Found: %s in current ListHead \n", LoadedImage->ModuleName);
+ DPRINT("Found: %s in current ListHead \n", LoadedImage->ModuleName);
+
+ /* Check if we didn't have a complete name */
+ if (!CompleteName)
+ {
+ /* Split this module's name */
+ _splitpath(LoadedImage->ModuleName, NULL, NULL, Filename, Ext);
- /* Check if the Names Match */
- if (!lstrcmpi( DllName, LoadedImage->ModuleName )) {
- //FIXME("Found it, returning it\n");
+ /* Use only the name and extension */
+ strcpy(FullName, Filename);
+ strcat(FullName, Ext);
+ }
+ else
+ {
+ /* Use the full untouched name */
+ strcpy(FullName, LoadedImage->ModuleName);
+ }
+
+ /* Check if the Names Match */
+ if (!_stricmp(DllName, FullName))
+ {
+ DPRINT("Found it, returning it\n");
return LoadedImage;
}
- /* Move to next Entry */
+ /* Move to next Entry */
Next = Next->Flink;
- //FIXME("Moving to next List Entry\n");
}
- //FIXME("Didn't find it...allocating it for you now\n");
-
- /* Allocate memory for the Structure, and write the Module Name under */
- LoadedImage = HeapAlloc(IMAGEHLP_hHeap, 0, sizeof(*LoadedImage) + lstrlen(DllName) + 1);
+ /* Allocate memory for the Structure, and write the Module Name under */
+ DPRINT("Didn't find it...allocating it for you now\n");
+ LoadedImage = HeapAlloc(IMAGEHLP_hHeap,
+ 0,
+ sizeof(*LoadedImage) + strlen(DllName) + 1);
+ if (LoadedImage)
+ {
+ /* Module Name will be after structure */
+ LoadedImage->ModuleName = (LPSTR)(LoadedImage + 1);
- /* Module Name will be after structure */
- LoadedImage->ModuleName = (LPSTR)LoadedImage + 1;
+ /* Copy the Module Name */
+ strcpy(LoadedImage->ModuleName, DllName);
- /* Copy the Moduel Name */
- lstrcpy(LoadedImage->ModuleName, DllName);
+ /* Now Load it */
+ if (MapAndLoad(DllName, DllPath, LoadedImage, TRUE, TRUE))
+ {
+ /* Add it to our list and return it */
+ InsertTailList(&ImageLoadListHead, &LoadedImage->Links);
+ return LoadedImage;
+ }
- /* Now Load it and add it to our list*/
- if (MapAndLoad(DllName, DllPath, LoadedImage, TRUE, TRUE)) {
- InsertTailList(&ImageLoadListHead, &LoadedImage->Links);
- return LoadedImage;
+ /* If we're here...there's been a failure */
+ HeapFree(IMAGEHLP_hHeap, 0, LoadedImage);
+ LoadedImage = NULL;
}
-
- /* If we're here...there's been a failure */
- HeapFree(IMAGEHLP_hHeap, 0, LoadedImage);
- LoadedImage = NULL;
return LoadedImage;
}
-/***********************************************************************
- * ImageRvaToSection (IMAGEHLP.@)
+/*
+ * @implemented
*/
PIMAGE_SECTION_HEADER
-WINAPI
-ImageRvaToSection(
- IN PIMAGE_NT_HEADERS NtHeaders,
- IN PVOID Base,
- IN ULONG Rva
- )
+IMAGEAPI
+ImageRvaToSection(IN PIMAGE_NT_HEADERS NtHeaders,
+ IN PVOID Base,
+ IN ULONG Rva)
{
- PIMAGE_SECTION_HEADER Section;
+ PIMAGE_SECTION_HEADER Section;
ULONG i;
- /* Get the First Section */
+ /* Get the First Section */
Section = IMAGE_FIRST_SECTION(NtHeaders);
- /* Look through each section and check if the RVA is in between */
- for (i=0; i < NtHeaders->FileHeader.NumberOfSections; i++) {
- if (Rva >= Section->VirtualAddress && Rva < Section->VirtualAddress +
- Section->SizeOfRawData) {
+ /* Look through each section */
+ for (i = 0; i < NtHeaders->FileHeader.NumberOfSections; i++)
+ {
+ /* Check if the RVA is in between */
+ if ((Rva >= Section->VirtualAddress) &&
+ (Rva < (Section->VirtualAddress + Section->SizeOfRawData)))
+ {
+ /* Return this section */
return Section;
- }
- ++Section;
}
- /* Not Found */
+ /* Move to the next section */
+ Section++;
+ }
+
+ /* Not Found */
return NULL;
}
-/***********************************************************************
- * ImageNtHeader (IMAGEHLP.@)
+/*
+ * @implemented
*/
-PIMAGE_NT_HEADERS WINAPI ImageNtHeader(PVOID Base)
+PIMAGE_NT_HEADERS
+IMAGEAPI
+ImageNtHeader(PVOID Base)
{
- TRACE("(%p)\n", Base);
-
- /* Just return the e_lfanew Offset VA */
- return (PIMAGE_NT_HEADERS)((LPBYTE)Base +
- ((PIMAGE_DOS_HEADER)Base)->e_lfanew);
+ /* Let RTL do it */
+ return RtlImageNtHeader(Base);
}
-/***********************************************************************
- * ImageRvaToVa (IMAGEHLP.@)
+/*
+ * @implemented
*/
PVOID
-WINAPI
-ImageRvaToVa(
- IN PIMAGE_NT_HEADERS NtHeaders,
- IN PVOID Base,
- IN ULONG Rva,
- IN OUT PIMAGE_SECTION_HEADER *LastRvaSection OPTIONAL
- )
+IMAGEAPI
+ImageRvaToVa(IN PIMAGE_NT_HEADERS NtHeaders,
+ IN PVOID Base,
+ IN ULONG Rva,
+ IN OUT PIMAGE_SECTION_HEADER *LastRvaSection OPTIONAL)
{
PIMAGE_SECTION_HEADER Section;
- /* Get the Section Associated */
- Section = ImageRvaToSection(NtHeaders, Base, Rva);
+ /* Get the Section Associated */
+ Section = ImageRvaToSection(NtHeaders, Base, Rva);
- /* Return it, if specified */
+ /* Return it, if specified */
if (LastRvaSection) *LastRvaSection = Section;
- /* Return the VA */
+ /* Return the VA */
return (PVOID)((ULONG_PTR)Base + (Rva - Section->VirtualAddress) +
- Section->PointerToRawData);
+ Section->PointerToRawData);
}
-/***********************************************************************
- * ImageUnload (IMAGEHLP.@)
+/*
+ * @implemented
*/
-BOOL WINAPI ImageUnload(PLOADED_IMAGE pLoadedImage)
+BOOL
+IMAGEAPI
+ImageUnload(PLOADED_IMAGE LoadedImage)
{
- LIST_ENTRY *pCurrent, *pFind;
-
- TRACE("(%p)\n", pLoadedImage);
-
- if(!IMAGEHLP_pFirstLoadedImage || !pLoadedImage)
- {
- /* No image loaded or null pointer */
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
+ /* If the image list isn't empty, remove this entry */
+ if (!IsListEmpty(&LoadedImage->Links)) RemoveEntryList(&LoadedImage->Links);
- pFind=&pLoadedImage->Links;
- pCurrent=&IMAGEHLP_pFirstLoadedImage->Links;
- while((pCurrent != pFind) &&
- (pCurrent != NULL))
- pCurrent = pCurrent->Flink;
- if(!pCurrent)
- {
- /* Not found */
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
+ /* Unmap and unload it */
+ UnMapAndLoad(LoadedImage);
- if(pCurrent->Blink)
- pCurrent->Blink->Flink = pCurrent->Flink;
- else
- IMAGEHLP_pFirstLoadedImage = pCurrent->Flink?CONTAINING_RECORD(
- pCurrent->Flink, LOADED_IMAGE, Links):NULL;
-
- if(pCurrent->Flink)
- pCurrent->Flink->Blink = pCurrent->Blink;
- else
- IMAGEHLP_pLastLoadedImage = pCurrent->Blink?CONTAINING_RECORD(
- pCurrent->Blink, LOADED_IMAGE, Links):NULL;
+ /* Free the structure */
+ HeapFree(IMAGEHLP_hHeap, 0, LoadedImage);
- return FALSE;
+ /* Return success */
+ return TRUE;
}
-/***********************************************************************
- * MapAndLoad (IMAGEHLP.@)
+/*
+ * @implemented
*/
-BOOL WINAPI MapAndLoad(
- LPSTR ImageName,
- LPSTR DllPath,
- PLOADED_IMAGE LoadedImage,
- BOOL DotDll,
- BOOL ReadOnly)
+BOOL
+IMAGEAPI
+MapAndLoad(LPSTR ImageName,
+ LPSTR DllPath,
+ PLOADED_IMAGE LoadedImage,
+ BOOL DotDll,
+ BOOL ReadOnly)
{
- HANDLE hFileMapping = NULL;
- PIMAGE_NT_HEADERS NtHeader = NULL;
- ULONG Tried = 0;
- UCHAR Buffer[MAX_PATH];
- LPSTR FilePart;
- LPSTR FileToOpen;
-
- /* So we can add the DLL Path later */
- FileToOpen = ImageName;
+ HANDLE hFile;
+ HANDLE hFileMapping;
+ ULONG Tried = 0;
+ UCHAR Buffer[MAX_PATH];
+ LPSTR FilePart;
+ LPSTR FileToOpen;
+ PIMAGE_NT_HEADERS NtHeader;
+
+ /* So we can add the DLL Path later */
+ FileToOpen = ImageName;
+
+ /* Assume failure */
+ LoadedImage->hFile = INVALID_HANDLE_VALUE;
-TryAgain:
- /* Get a handle to the file */
- if ((LoadedImage->hFile = CreateFileA (FileToOpen,
- ReadOnly ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
- ReadOnly ? FILE_SHARE_READ : FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL)) == INVALID_HANDLE_VALUE)
+ /* Start open loop */
+ while (TRUE)
{
- /* It Failed, use the DLL Search Path then (make sure we haven't already) */
- if (!Tried) {
- Tried = SearchPath(DllPath, ImageName, DotDll ? ".dll" : ".exe", MAX_PATH, Buffer, &FilePart);
- if (Tried) {
- FileToOpen = Buffer;
- goto TryAgain;
+ /* Get a handle to the file */
+ hFile = CreateFileA(FileToOpen,
+ ReadOnly ? GENERIC_READ :
+ GENERIC_READ | GENERIC_WRITE,
+ ReadOnly ? FILE_SHARE_READ :
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL);
+
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ /* Check if we already tried this once */
+ if (!Tried)
+ {
+ /* We didn't do do a path search now */
+ Tried = SearchPath(DllPath,
+ ImageName,
+ DotDll ? ".dll" : ".exe",
+ MAX_PATH,
+ Buffer,
+ &FilePart);
+
+ /* Check if it was successful */
+ if (Tried && (Tried < MAX_PATH))
+ {
+ /* Change the filename to use, and try again */
+ FileToOpen = Buffer;
+ continue;
+ }
}
+
+ /* Fail */
+ return FALSE;
}
- /* Fail */
- return FALSE;
+
+ /* Success, break out */
+ break;
}
- /* Create the File Mapping */
- if (!(hFileMapping = CreateFileMappingA (LoadedImage->hFile,
- NULL,
- ReadOnly ? PAGE_READONLY : PAGE_READWRITE,
- 0,
- 0,
- NULL)))
+ /* Create the File Mapping */
+ hFileMapping = CreateFileMappingA(hFile,
+ NULL,
+ ReadOnly ? PAGE_READONLY :
+ PAGE_READWRITE,
+ 0,
+ 0,
+ NULL);
+ if (!hFileMapping)
{
- DWORD dwLastError = GetLastError();
- SetLastError(dwLastError);
- goto Error;
+ /* Fail */
+ SetLastError(GetLastError());
+ CloseHandle(hFile);
+ return FALSE;
}
- /* Get a pointer to the file */
- if(!(LoadedImage->MappedAddress = MapViewOfFile(hFileMapping,
- ReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE,
- 0,
- 0,
- 0)))
+ /* Get a pointer to the file */
+ LoadedImage->MappedAddress = MapViewOfFile(hFileMapping,
+ ReadOnly ? FILE_MAP_READ :
+ FILE_MAP_WRITE,
+ 0,
+ 0,
+ 0);
+
+ /* Close the handle to the map, we don't need it anymore */
+ CloseHandle(hFileMapping);
+
+ /* Write the image size */
+ LoadedImage->SizeOfImage = GetFileSize(hFile, NULL);
+
+ /* Get the Nt Header */
+ NtHeader = ImageNtHeader(LoadedImage->MappedAddress);
+
+ /* Allocate memory for the name and save it */
+ LoadedImage->ModuleName = HeapAlloc(IMAGEHLP_hHeap,
+ 0,
+ strlen(FileToOpen) + 16);
+ strcpy(LoadedImage->ModuleName, FileToOpen);
+
+ /* Save the NT Header */
+ LoadedImage->FileHeader = NtHeader;
+
+ /* Save the section data */
+ LoadedImage->Sections = IMAGE_FIRST_SECTION(NtHeader);
+ LoadedImage->NumberOfSections = NtHeader->FileHeader.NumberOfSections;
+
+ /* Setup other data */
+ LoadedImage->SizeOfImage = NtHeader->OptionalHeader.SizeOfImage;
+ LoadedImage->Characteristics = NtHeader->FileHeader.Characteristics;
+ LoadedImage->LastRvaSection = LoadedImage->Sections;
+ LoadedImage->fSystemImage = FALSE; /* FIXME */
+ LoadedImage->fDOSImage = FALSE; /* FIXME */
+ InitializeListHead(&LoadedImage->Links);
+
+ /* Check if it was read-only */
+ if (ReadOnly)
+ {
+ /* It was, so close our handle and write it as invalid */
+ CloseHandle(hFile);
+ LoadedImage->hFile = INVALID_HANDLE_VALUE;
+ }
+ else
{
- DWORD dwLastError = GetLastError();
- SetLastError(dwLastError);
- goto Error;
+ /* Write our file handle */
+ LoadedImage->hFile = hFile;
}
- /* Close the handle to the map, we don't need it anymore */
- CloseHandle(hFileMapping);
- hFileMapping=NULL;
-
- /* Get the Nt Header */
- NtHeader = ImageNtHeader(LoadedImage->MappedAddress);
-
- /* Write data */
- LoadedImage->ModuleName = HeapAlloc(IMAGEHLP_hHeap, 0, lstrlen(ImageName) + 1);
- lstrcpy(LoadedImage->ModuleName, ImageName);
- LoadedImage->FileHeader = NtHeader;
- LoadedImage->Sections = (PIMAGE_SECTION_HEADER)
- ((LPBYTE)&NtHeader->OptionalHeader +
- NtHeader->FileHeader.SizeOfOptionalHeader);
- LoadedImage->NumberOfSections = NtHeader->FileHeader.NumberOfSections;
- LoadedImage->SizeOfImage = NtHeader->OptionalHeader.SizeOfImage;
- LoadedImage->Characteristics = NtHeader->FileHeader.Characteristics;
- LoadedImage->LastRvaSection = LoadedImage->Sections;
- LoadedImage->fSystemImage = FALSE; /* FIXME */
- LoadedImage->fDOSImage = FALSE; /* FIXME */
-
- /* Read only, so no sense in keeping the handle alive */
- if (ReadOnly) CloseHandle(LoadedImage->hFile);
-
- /* Return Success */
- return TRUE;
-
-Error:
- if(LoadedImage->MappedAddress)
- UnmapViewOfFile(LoadedImage->MappedAddress);
- if(hFileMapping)
- CloseHandle(hFileMapping);
- if(LoadedImage->hFile)
- CloseHandle(LoadedImage->hFile);
- return FALSE;
+ /* Return Success */
+ return TRUE;
}
-/***********************************************************************
- * SetImageConfigInformation (IMAGEHLP.@)
+/*
+ * @unimplemented
*/
-BOOL WINAPI SetImageConfigInformation(
- PLOADED_IMAGE LoadedImage,
- PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation)
+BOOL
+IMAGEAPI
+SetImageConfigInformation(PLOADED_IMAGE LoadedImage,
+ PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation)
{
- FIXME("(%p, %p): stub\n",
- LoadedImage, ImageConfigInformation
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ UNIMPLEMENTED;
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
}
-/***********************************************************************
- * UnMapAndLoad (IMAGEHLP.@)
+/*
+ * @implemented
*/
-BOOL WINAPI UnMapAndLoad(PLOADED_IMAGE LoadedImage)
+BOOL
+IMAGEAPI
+UnMapAndLoad(PLOADED_IMAGE Image)
+{
+ PIMAGE_NT_HEADERS NtHeader;
+ DWORD HeaderCheckSum, CheckSum;
+
+ /* Check if the image was read-only */
+ if (Image->hFile == INVALID_HANDLE_VALUE)
+ {
+ /* We'll only unmap the view */
+ UnmapViewOfFile(Image->MappedAddress);
+ }
+ else
+ {
+ /* Calculate the checksum */
+ CheckSumMappedFile(Image->MappedAddress,
+ Image->SizeOfImage,
+ &HeaderCheckSum,
+ &CheckSum);
+
+ /* Get the NT Header */
+ NtHeader = Image->FileHeader;
+
+ /* Write the new checksum to it */
+ NtHeader->OptionalHeader.CheckSum = CheckSum;
+
+ /* Now flush and unmap the image */
+ FlushViewOfFile(Image->MappedAddress, Image->SizeOfImage);
+ UnmapViewOfFile(Image->MappedAddress);
+
+ /* Check if the size changed */
+ if (Image->SizeOfImage != GetFileSize(Image->hFile, NULL))
+ {
+ /* Update the file pointer */
+ SetFilePointer(Image->hFile, Image->SizeOfImage, NULL, FILE_BEGIN);
+ SetEndOfFile(Image->hFile);
+ }
+ }
+
+ /* Check if the image had a valid handle, and close it */
+ if (Image->hFile != INVALID_HANDLE_VALUE) CloseHandle(Image->hFile);
+
+ /* Return success */
+ return TRUE;
+}
+
+BOOL
+IMAGEAPI
+UnloadAllImages(VOID)
{
- FIXME("(%p): stub\n", LoadedImage);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ PLIST_ENTRY Head, Entry;
+ PLOADED_IMAGE CurrentImage;
+
+ /* Make sure we're initialized */
+ if (!DllListInitialized) return TRUE;
+
+ /* Get the list pointers and loop */
+ Head = &ImageLoadListHead;
+ Entry = Head->Flink;
+ while (Entry != Head)
+ {
+ /* Get this image */
+ CurrentImage = CONTAINING_RECORD(Entry, LOADED_IMAGE, Links);
+
+ /* Move to the next entry */
+ Entry = Entry->Flink;
+
+ /* Unload it */
+ ImageUnload(CurrentImage);
+ }
+
+ /* We are not initialized anymore */
+ DllListInitialized = FALSE;
+ return TRUE;
}
+++ /dev/null
-/*
- * IMAGEHLP library
- *
- * Copyright 1998 Patrik Stridvall
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <stdarg.h>
-
-#include "winerror.h"
-#include "windef.h"
-#include "winbase.h"
-#include "wine/debug.h"
-#include "imagehlp.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
-
-/***********************************************************************
- * FindDebugInfoFile (IMAGEHLP.@)
- */
-HANDLE WINAPI FindDebugInfoFile(
- LPSTR FileName, LPSTR SymbolPath, LPSTR DebugFilePath)
-{
- FIXME("(%s, %s, %s): stub\n",
- debugstr_a(FileName), debugstr_a(SymbolPath),
- debugstr_a(DebugFilePath)
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return NULL;
-}
-
-/***********************************************************************
- * FindExecutableImage (IMAGEHLP.@)
- */
-HANDLE WINAPI FindExecutableImage(
- LPSTR FileName, LPSTR SymbolPath, LPSTR ImageFilePath)
-{
- FIXME("(%s, %s, %s): stub\n",
- debugstr_a(FileName), debugstr_a(SymbolPath),
- debugstr_a(ImageFilePath)
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return NULL;
-}
-
-/***********************************************************************
- * MapDebugInformation (IMAGEHLP.@)
- */
-PIMAGE_DEBUG_INFORMATION WINAPI MapDebugInformation(
- HANDLE FileHandle, LPSTR FileName,
- LPSTR SymbolPath, DWORD ImageBase)
-{
- FIXME("(%p, %s, %s, 0x%08lx): stub\n",
- FileHandle, FileName, SymbolPath, ImageBase
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return NULL;
-}
-
-/***********************************************************************
- * StackWalk (IMAGEHLP.@)
- */
-BOOL WINAPI StackWalk(
- DWORD MachineType, HANDLE hProcess, HANDLE hThread,
- LPSTACKFRAME StackFrame, LPVOID ContextRecord,
- PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
- PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
- PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
- PTRANSLATE_ADDRESS_ROUTINE TranslateAddress)
-{
- FIXME(
- "(%ld, %p, %p, %p, %p, %p, %p, %p, %p): stub\n",
- MachineType, hProcess, hThread, StackFrame, ContextRecord,
- ReadMemoryRoutine, FunctionTableAccessRoutine,
- GetModuleBaseRoutine, TranslateAddress
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-/***********************************************************************
- * UnDecorateSymbolName (IMAGEHLP.@)
- */
-DWORD WINAPI UnDecorateSymbolName(
- LPCSTR DecoratedName, LPSTR UnDecoratedName,
- DWORD UndecoratedLength, DWORD Flags)
-{
- FIXME("(%s, %s, %ld, 0x%08lx): stub\n",
- debugstr_a(DecoratedName), debugstr_a(UnDecoratedName),
- UndecoratedLength, Flags
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
-}
-
-/***********************************************************************
- * UnmapDebugInformation (IMAGEHLP.@)
- */
-BOOL WINAPI UnmapDebugInformation(
- PIMAGE_DEBUG_INFORMATION DebugInfo)
-{
- FIXME("(%p): stub\n", DebugInfo);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
LIBRARY imagehlp.dll
EXPORTS
-BindImage@12 @1
-BindImageEx@20 @2
-CheckSumMappedFile@16 @3
-EnumerateLoadedModules@12 @4
-FindDebugInfoFile@12 @5
-FindExecutableImage@12 @6
-GetImageConfigInformation@8 @7
-GetImageUnusedHeaderBytes@8 @8
-GetTimestampForLoadedLibrary@4 @9
-ImageAddCertificate@12 @10
-ImageDirectoryEntryToData@16 @11
-ImageEnumerateCertificates@20 @12
-ImageGetCertificateData@16 @13
-ImageGetCertificateHeader@12 @14
-ImageGetDigestStream@16 @15
-ImageLoad@8 @16
-ImageNtHeader@4 @17
-ImageRemoveCertificate@8 @18
-ImageRvaToSection@12 @19
-ImageRvaToVa@16 @20
-ImageUnload@4 @21
-ImagehlpApiVersion@0 @22
-ImagehlpApiVersionEx@4 @23
-MakeSureDirectoryPathExists@4 @24
-MapAndLoad@20 @25
-MapDebugInformation@16 @26
-MapFileAndCheckSumA@12 @27
-MapFileAndCheckSumW@12 @28
-ReBaseImage@44 @30
-RemovePrivateCvSymbolic@12 @31
-RemoveRelocations@4 @32
-SearchTreeForFile@12 @33
-SetImageConfigInformation@8 @34
-SplitSymbols@16 @35
-StackWalk@36 @36
-SymCleanup@4 @37
-SymEnumerateModules@12 @38
-SymEnumerateSymbols@16 @39
-SymFunctionTableAccess@8 @40
-SymGetModuleBase@8 @41
-SymGetModuleInfo@12 @42
-SymGetOptions@0 @43
-SymGetSearchPath@12 @44
-SymGetSymFromAddr@16 @45
-SymGetSymFromName@12 @46
-SymGetSymNext@8 @47
-SymGetSymPrev@8 @48
-SymInitialize@12 @49
-SymLoadModule@24 @50
-SymRegisterCallback@12 @51
-SymSetOptions@4 @52
-SymSetSearchPath@8 @53
-SymUnDName@12 @54
-SymUnloadModule@8 @55
-TouchFileTimes@8 @56
-UnDecorateSymbolName@16 @57
-UnMapAndLoad@4 @58
-UnmapDebugInformation@4 @59
-UpdateDebugInfoFile@16 @60
-UpdateDebugInfoFileEx@20 @61
+BindImage @2
+BindImageEx @3
+CheckSumMappedFile @4
+EnumerateLoadedModules=Dbghelp.EnumerateLoadedModules @5
+EnumerateLoadedModules64=Dbghelp.EnumerateLoadedModules64 @6
+FindDebugInfoFile=Dbghelp.FindDebugInfoFile @7
+FindDebugInfoFileEx=Dbghelp.FindDebugInfoFileEx @8
+FindExecutableImage=Dbghelp.FindExecutableImage @9
+FindExecutableImageEx=Dbghelp.FindExecutableImageEx @10
+FindFileInPath=Dbghelp.FindFileInPath @11
+FindFileInSearchPath=Dbghelp.FindFileInSearchPath @12
+GetImageConfigInformation @13
+GetImageUnusedHeaderBytes @14
+GetTimestampForLoadedLibrary @15
+ImageAddCertificate @16
+ImageDirectoryEntryToData @17
+ImageDirectoryEntryToDataEx @18
+ImageEnumerateCertificates @19
+ImageGetCertificateData @20
+ImageGetCertificateHeader @21
+ImageGetDigestStream @22
+ImagehlpApiVersion=Dbghelp.ImagehlpApiVersion @29
+ImagehlpApiVersionEx=Dbghelp.ImagehlpApiVersionEx @30
+ImageLoad @23
+ImageNtHeader @24
+ImageRemoveCertificate @25
+ImageRvaToSection @26
+ImageRvaToVa @27
+ImageUnload @28
+MakeSureDirectoryPathExists=Dbghelp.MakeSureDirectoryPathExists @31
+MapAndLoad @32
+MapDebugInformation=Dbghelp.MapDebugInformation @33
+MapFileAndCheckSumA @34
+MapFileAndCheckSumW @35
+ReBaseImage @37
+;ReBaseImage64 @36
+;RemovePrivateCvSymbolic @38
+;RemovePrivateCvSymbolicEx @39
+RemoveRelocations @1
+SearchTreeForFile=Dbghelp.SearchTreeForFile @40
+SetImageConfigInformation @41
+;SplitSymbols @42
+StackWalk=Dbghelp.StackWalk @43
+StackWalk64=Dbghelp.StackWalk64 @44
+SymCleanup=Dbghelp.SymCleanup @45
+SymEnumerateModules=Dbghelp.SymEnumerateModules @51
+SymEnumerateModules64=Dbghelp.SymEnumerateModules64 @50
+SymEnumerateSymbols=Dbghelp.SymEnumerateSymbols @53
+SymEnumerateSymbols64=Dbghelp.SymEnumerateSymbols64 @52
+SymEnumerateSymbolsW=Dbghelp.SymEnumerateSymbolsW @55
+SymEnumerateSymbolsW64=Dbghelp.SymEnumerateSymbolsW64 @54
+SymEnumSourceFiles=Dbghelp.SymEnumSourceFiles @46
+SymEnumSym=Dbghelp.SymEnumSym @47
+SymEnumSymbols=Dbghelp.SymEnumSymbols @48
+SymEnumTypes=Dbghelp.SymEnumTypes @49
+SymFindFileInPath=Dbghelp.SymFindFileInPath @56
+SymFromAddr=Dbghelp.SymFromAddr @57
+SymFromName=Dbghelp.SymFromName @58
+SymFunctionTableAccess=Dbghelp.SymFunctionTableAccess @60
+SymFunctionTableAccess64=Dbghelp.SymFunctionTableAccess64 @59
+SymGetLineFromAddr=Dbghelp.SymGetLineFromAddr @62
+SymGetLineFromAddr64=Dbghelp.SymGetLineFromAddr64 @61
+SymGetLineFromName=Dbghelp.SymGetLineFromName @64
+SymGetLineFromName64=Dbghelp.SymGetLineFromName64 @63
+SymGetLineNext=Dbghelp.SymGetLineNext @66
+SymGetLineNext64=Dbghelp.SymGetLineNext64 @65
+SymGetLinePrev=Dbghelp.SymGetLinePrev @68
+SymGetLinePrev64=Dbghelp.SymGetLinePrev64 @67
+SymGetModuleBase=Dbghelp.SymGetModuleBase @70
+SymGetModuleBase64=Dbghelp.SymGetModuleBase64 @69
+SymGetModuleInfo=Dbghelp.SymGetModuleInfo @72
+SymGetModuleInfo64=Dbghelp.SymGetModuleInfo64 @71
+SymGetModuleInfoW=Dbghelp.SymGetModuleInfoW @74
+SymGetModuleInfoW64=Dbghelp.SymGetModuleInfoW64 @73
+SymGetOptions=Dbghelp.SymGetOptions @76
+SymGetSearchPath=Dbghelp.SymGetSearchPath @75
+SymGetSymFromAddr=Dbghelp.SymGetSymFromAddr @78
+SymGetSymFromAddr64=Dbghelp.SymGetSymFromAddr64 @77
+SymGetSymFromName=Dbghelp.SymGetSymFromName @80
+SymGetSymFromName64=Dbghelp.SymGetSymFromName64 @79
+SymGetSymNext=Dbghelp.SymGetSymNext @82
+SymGetSymNext64=Dbghelp.SymGetSymNext64 @81
+SymGetSymPrev=Dbghelp.SymGetSymPrev @84
+SymGetSymPrev64=Dbghelp.SymGetSymPrev64 @83
+SymGetTypeFromName=Dbghelp.SymGetTypeFromName @85
+SymGetTypeInfo=Dbghelp.SymGetTypeInfo @86
+SymInitialize=Dbghelp.SymInitialize @87
+SymLoadModule=Dbghelp.SymLoadModule @89
+SymLoadModule64=Dbghelp.SymLoadModule64 @88
+SymMatchFileName=Dbghelp.SymMatchFileName @90
+SymMatchString=Dbghelp.SymMatchString @91
+SymRegisterCallback=Dbghelp.SymRegisterCallback @93
+SymRegisterCallback64=Dbghelp.SymRegisterCallback64 @92
+SymRegisterFunctionEntryCallback=Dbghelp.SymRegisterFunctionEntryCallback @95
+SymRegisterFunctionEntryCallback64=Dbghelp.SymRegisterFunctionEntryCallback64 @94
+SymSetContext=Dbghelp.SymSetContext @96
+SymSetOptions=Dbghelp.SymSetOptions @97
+SymSetSearchPath=Dbghelp.SymSetSearchPath @98
+SymUnDName=Dbghelp.SymUnDName @100
+SymUnDName64=Dbghelp.SymUnDName64 @99
+SymUnloadModule=Dbghelp.SymUnloadModule @102
+SymUnloadModule64=Dbghelp.SymUnloadModule64 @101
+TouchFileTimes @103
+UnDecorateSymbolName=Dbghelp.UnDecorateSymbolName @104
+UnMapAndLoad @105
+UnmapDebugInformation=Dbghelp.UnmapDebugInformation @106
+;UpdateDebugInfoFile @107
+;UpdateDebugInfoFileEx @108
<module name="imagehlp" type="win32dll" baseaddress="${BASEADDRESS_IMAGEHLP}" installbase="system32" installname="imagehlp.dll" allowwarnings="true">
<importlibrary definition="imagehlp.def" />
<include base="imagehlp">.</include>
- <include base="ReactOS">include/wine</include>
- <define name="_DISABLE_TIDENTS" />
- <define name="__REACTOS__" />
<define name="__USE_W32API" />
- <define name="_WIN32_IE">0x600</define>
- <define name="_WIN32_WINNT">0x501</define>
- <define name="WINVER">0x501</define>
- <define name="COBJMACROS" />
- <define name="__need_offsetof" />
- <define name="DCX_USESTYLE">0x10000L</define>
- <library>wine</library>
+ <define name="_WIN32_WINNT">0x600</define>
+ <define name="WINVER">0x0600</define>
+ <define name="_IMAGEHLP_SOURCE_"></define>
<library>ntdll</library>
<library>kernel32</library>
<file>access.c</file>
- <file>debug.c</file>
<file>imagehlp_main.c</file>
<file>integrity.c</file>
- <file>internal.c</file>
<file>modify.c</file>
- <file>symbol.c</file>
<file>imagehlp.rc</file>
+ <pch>precomp.h</pch>
+ <linkerflag>-enable-stdcall-fixup</linkerflag>
</module>
/*
- * IMAGEHLP library
- *
- * Copyright 1998 Patrik Stridvall
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: Imagehlp Libary
+ * FILE: lib/imagehlp/imagehlp_main.c
+ * PURPOSE: DLL Entrypoint
+ * PROGRAMMER: Patrik Stridvall
*/
-#include <stdarg.h>
+/* INCLUDES ******************************************************************/
-#include "windef.h"
-#include "winbase.h"
-#include "imagehlp.h"
-#include "winerror.h"
-#include "wine/debug.h"
+#include "precomp.h"
-WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
+//#define NDEBUG
+#include <debug.h>
-/**********************************************************************/
+/* DATA **********************************************************************/
HANDLE IMAGEHLP_hHeap = NULL;
-static API_VERSION IMAGEHLP_ApiVersion = { 4, 0, 0, 5 };
+/* FUNCTIONS *****************************************************************/
-/***********************************************************************
- * DllMain (IMAGEHLP.init)
- */
-BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+BOOL
+IMAGEAPI
+DllMain(HINSTANCE hinstDLL,
+ DWORD fdwReason,
+ LPVOID lpvReserved)
{
- switch(fdwReason)
+ switch(fdwReason)
{
- case DLL_PROCESS_ATTACH:
- DisableThreadLibraryCalls(hinstDLL);
- IMAGEHLP_hHeap = HeapCreate(0, 0x10000, 0);
- break;
- case DLL_PROCESS_DETACH:
- HeapDestroy(IMAGEHLP_hHeap);
- IMAGEHLP_hHeap = NULL;
- break;
- default:
- break;
+ case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls(hinstDLL);
+ IMAGEHLP_hHeap = HeapCreate(0, 0x10000, 0);
+ break;
+ case DLL_PROCESS_DETACH:
+ HeapDestroy(IMAGEHLP_hHeap);
+ IMAGEHLP_hHeap = NULL;
+ break;
+ default:
+ break;
}
- return TRUE;
-}
-
-/***********************************************************************
- * ImagehlpApiVersion (IMAGEHLP.@)
- */
-LPAPI_VERSION WINAPI ImagehlpApiVersion(VOID)
-{
- return &IMAGEHLP_ApiVersion;
-}
-
-/***********************************************************************
- * ImagehlpApiVersionEx (IMAGEHLP.@)
- */
-LPAPI_VERSION WINAPI ImagehlpApiVersionEx(LPAPI_VERSION AppVersion)
-{
- if(!AppVersion)
- return NULL;
-
- AppVersion->MajorVersion = IMAGEHLP_ApiVersion.MajorVersion;
- AppVersion->MinorVersion = IMAGEHLP_ApiVersion.MinorVersion;
- AppVersion->Revision = IMAGEHLP_ApiVersion.Revision;
- AppVersion->Reserved = IMAGEHLP_ApiVersion.Reserved;
-
- return AppVersion;
-}
-
-/***********************************************************************
- * MakeSureDirectoryPathExists (IMAGEHLP.@)
- *
- * Path may contain a file at the end. If a dir is at the end, the path
- * must end with a backslash.
- *
- * Path may be absolute or relative (to current dir).
- *
- */
-BOOL WINAPI MakeSureDirectoryPathExists(LPCSTR DirPath)
-{
- char Path[MAX_PATH];
- char *SlashPos = Path;
- char Slash;
- BOOL bRes;
-
- strcpy(Path, DirPath);
-
- while((SlashPos=strpbrk(SlashPos+1,"\\/")))
- {
- Slash = *SlashPos;
- *SlashPos = 0;
-
- bRes = CreateDirectoryA(Path, NULL);
- if (bRes == FALSE && GetLastError() != ERROR_ALREADY_EXISTS)
- {
- return FALSE;
- }
-
- *SlashPos = Slash;
- }
-
- return TRUE;
-}
-
-
-/***********************************************************************
- * MarkImageAsRunFromSwap (IMAGEHLP.@)
- * FIXME
- * No documentation available.
- */
-
-/***********************************************************************
- * SearchTreeForFile (IMAGEHLP.@)
- */
-BOOL WINAPI SearchTreeForFile(
- LPSTR RootPath, LPSTR InputPathName, LPSTR OutputPathBuffer)
-{
- FIXME("(%s, %s, %s): stub\n",
- debugstr_a(RootPath), debugstr_a(InputPathName),
- debugstr_a(OutputPathBuffer)
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-/***********************************************************************
- * TouchFileTimes (IMAGEHLP.@)
- */
-BOOL WINAPI TouchFileTimes(HANDLE FileHandle, LPSYSTEMTIME lpSystemTime)
-{
- FILETIME FileTime;
- SYSTEMTIME SystemTime;
-
- if(lpSystemTime == NULL)
- {
- GetSystemTime(&SystemTime);
- lpSystemTime = &SystemTime;
- }
-
- return (SystemTimeToFileTime(lpSystemTime, &FileTime) &&
- SetFileTime(FileHandle, NULL, NULL, &FileTime));
+
+ return TRUE;
}
/*
- * IMAGEHLP library
- *
- * Copyright 1998 Patrik Stridvall
- * Copyright 2003 Mike McCormack
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: Imagehlp Libary
+ * FILE: lib/imagehlp/integrity.c
+ * PURPOSE: Image Integrity: Security Certificates and Checksums
+ * PROGRAMMER: Patrik Stridvall, Mike McCormack (WINE)
*/
-#include <stdarg.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "winerror.h"
-#include "winreg.h"
-#include "winternl.h"
-#include "winnt.h"
-//#include "ntstatus.h"
-#include "imagehlp.h"
-#include "wine/debug.h"
-
-#define IMAGE_FILE_SECURITY_DIRECTORY 4 /* winnt.h */
-
-WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
-
/*
* These functions are partially documented at:
* http://www.cs.auckland.ac.nz/~pgut001/pubs/authenticode.txt
*/
-/***********************************************************************
- * IMAGEHLP_GetSecurityDirOffset (INTERNAL)
- *
- * Read a file's PE header, and return the offset and size of the
- * security directory.
- */
-static BOOL IMAGEHLP_GetSecurityDirOffset( HANDLE handle, DWORD num,
- DWORD *pdwOfs, DWORD *pdwSize )
+/* INCLUDES ******************************************************************/
+
+#include "precomp.h"
+
+//#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+static
+BOOL
+IMAGEHLP_GetSecurityDirOffset(HANDLE handle,
+ DWORD *pdwOfs,
+ DWORD *pdwSize)
{
IMAGE_DOS_HEADER dos_hdr;
IMAGE_NT_HEADERS nt_hdr;
- DWORD size, count, offset, len;
+ DWORD count;
BOOL r;
IMAGE_DATA_DIRECTORY *sd;
-
- TRACE("handle %p\n", handle );
+ DPRINT("handle %p\n", handle );
/* read the DOS header */
count = SetFilePointer( handle, 0, NULL, FILE_BEGIN );
return FALSE;
sd = &nt_hdr.OptionalHeader.
- DataDirectory[IMAGE_FILE_SECURITY_DIRECTORY];
+ DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY];
- TRACE("len = %lx addr = %lx\n", sd->Size, sd->VirtualAddress);
+ DPRINT("size = %lx addr = %lx\n", sd->Size, sd->VirtualAddress);
+ *pdwSize = sd->Size;
+ *pdwOfs = sd->VirtualAddress;
- offset = 0;
- size = sd->Size;
+ return TRUE;
+}
+
+static
+BOOL
+IMAGEHLP_GetCertificateOffset(HANDLE handle,
+ DWORD num,
+ DWORD *pdwOfs,
+ DWORD *pdwSize)
+{
+ DWORD size, count, offset, len, sd_VirtualAddr;
+ BOOL r;
+ r = IMAGEHLP_GetSecurityDirOffset( handle, &sd_VirtualAddr, &size );
+ if( !r )
+ return FALSE;
+
+ offset = 0;
/* take the n'th certificate */
while( 1 )
{
/* read the length of the current certificate */
- count = SetFilePointer( handle, sd->VirtualAddress + offset,
+ count = SetFilePointer( handle, sd_VirtualAddr + offset,
NULL, FILE_BEGIN );
if( count == INVALID_SET_FILE_POINTER )
return FALSE;
return FALSE;
}
- *pdwOfs = sd->VirtualAddress + offset;
+ *pdwOfs = sd_VirtualAddr + offset;
*pdwSize = len;
- TRACE("len = %lx addr = %lx\n", len, sd->VirtualAddress + offset);
-
+ DPRINT("len = %lx addr = %lx\n", len, sd_VirtualAddr + offset);
return TRUE;
}
+static
+WORD
+CalcCheckSum(DWORD StartValue,
+ LPVOID BaseAddress,
+ DWORD WordCount)
+{
+ LPWORD Ptr;
+ DWORD Sum;
+ DWORD i;
+
+ Sum = StartValue;
+ Ptr = (LPWORD)BaseAddress;
+ for (i = 0; i < WordCount; i++)
+ {
+ Sum += *Ptr;
+ if (HIWORD(Sum) != 0)
+ {
+ Sum = LOWORD(Sum) + HIWORD(Sum);
+ }
+ Ptr++;
+ }
+
+ return (WORD)(LOWORD(Sum) + HIWORD(Sum));
+}
-/***********************************************************************
- * ImageAddCertificate (IMAGEHLP.@)
+/*
+ * @unimplemented
*/
-
-BOOL WINAPI ImageAddCertificate(
- HANDLE FileHandle, LPWIN_CERTIFICATE Certificate, PDWORD Index)
+BOOL
+IMAGEAPI
+ImageAddCertificate(HANDLE FileHandle,
+ LPWIN_CERTIFICATE Certificate,
+ PDWORD Index)
{
- FIXME("(%p, %p, %p): stub\n",
- FileHandle, Certificate, Index
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ UNIMPLEMENTED;
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
}
-/***********************************************************************
- * ImageEnumerateCertificates (IMAGEHLP.@)
+/*
+ * @unimplemented
*/
-BOOL WINAPI ImageEnumerateCertificates(
- HANDLE FileHandle, WORD TypeFilter, PDWORD CertificateCount,
- PDWORD Indices, DWORD IndexCount)
+BOOL
+IMAGEAPI
+ImageEnumerateCertificates(HANDLE FileHandle,
+ WORD TypeFilter,
+ PDWORD CertificateCount,
+ PDWORD Indices,
+ DWORD IndexCount)
{
- FIXME("(%p, %hd, %p, %p, %ld): stub\n",
- FileHandle, TypeFilter, CertificateCount, Indices, IndexCount
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ DWORD size, count, offset, sd_VirtualAddr;
+ WIN_CERTIFICATE hdr;
+ const size_t cert_hdr_size = sizeof hdr - sizeof hdr.bCertificate;
+ BOOL r;
+
+ DPRINT("%p %hd %p %p %ld\n",
+ FileHandle, TypeFilter, CertificateCount, Indices, IndexCount);
+
+ if( Indices )
+ {
+ DPRINT1("Indicies not FileHandled!\n");
+ return FALSE;
+ }
+
+ r = IMAGEHLP_GetSecurityDirOffset( FileHandle, &sd_VirtualAddr, &size );
+ if( !r )
+ return FALSE;
+
+ offset = 0;
+ *CertificateCount = 0;
+ while( offset < size )
+ {
+ /* read the length of the current certificate */
+ count = SetFilePointer( FileHandle, sd_VirtualAddr + offset,
+ NULL, FILE_BEGIN );
+ if( count == INVALID_SET_FILE_POINTER )
+ return FALSE;
+ r = ReadFile( FileHandle, &hdr, (DWORD)cert_hdr_size, &count, NULL );
+ if( !r )
+ return FALSE;
+ if( count != cert_hdr_size )
+ return FALSE;
+
+ DPRINT("Size = %08lx id = %08hx\n", hdr.dwLength, hdr.wCertificateType );
+
+ /* check the certificate is not too big or too small */
+ if( hdr.dwLength < cert_hdr_size )
+ return FALSE;
+ if( hdr.dwLength > (size-offset) )
+ return FALSE;
+
+ if( (TypeFilter == CERT_SECTION_TYPE_ANY) ||
+ (TypeFilter == hdr.wCertificateType) )
+ {
+ (*CertificateCount)++;
+ }
+
+ /* next certificate */
+ offset += hdr.dwLength;
+ }
+
+ return TRUE;
}
-/***********************************************************************
- * ImageGetCertificateData (IMAGEHLP.@)
- *
- * FIXME: not sure that I'm dealing with the Index the right way
+/*
+ * @implemented
*/
-BOOL WINAPI ImageGetCertificateData(
- HANDLE handle, DWORD Index,
- LPWIN_CERTIFICATE Certificate, PDWORD RequiredLength)
+BOOL
+IMAGEAPI
+ImageGetCertificateData(HANDLE handle,
+ DWORD Index,
+ LPWIN_CERTIFICATE Certificate,
+ PDWORD RequiredLength)
{
DWORD r, offset, ofs, size, count;
+ DPRINT("%p %ld %p %p\n", handle, Index, Certificate, RequiredLength);
- TRACE("%p %ld %p %p\n", handle, Index, Certificate, RequiredLength);
-
- if( !IMAGEHLP_GetSecurityDirOffset( handle, Index, &ofs, &size ) )
+ if( !IMAGEHLP_GetCertificateOffset( handle, Index, &ofs, &size ) )
return FALSE;
if( !Certificate )
if( count != size )
return FALSE;
- TRACE("OK\n");
+ DPRINT("OK\n");
+ return TRUE;
+}
+
+/*
+ * @unimplemented
+ */
+BOOL
+IMAGEAPI
+ImageGetCertificateHeader(HANDLE FileHandle,
+ DWORD CertificateIndex,
+ LPWIN_CERTIFICATE Certificateheader)
+{
+ DWORD r, offset, ofs, size, count;
+ const size_t cert_hdr_size = sizeof *Certificateheader -
+ sizeof Certificateheader->bCertificate;
+
+ DPRINT("%p %ld %p\n", FileHandle, CertificateIndex, Certificateheader);
+
+ if( !IMAGEHLP_GetCertificateOffset( FileHandle, CertificateIndex, &ofs, &size ) )
+ return FALSE;
+
+ if( size < cert_hdr_size )
+ return FALSE;
+
+ offset = SetFilePointer( FileHandle, ofs, NULL, FILE_BEGIN );
+ if( offset == INVALID_SET_FILE_POINTER )
+ return FALSE;
+ r = ReadFile( FileHandle, Certificateheader, (DWORD)cert_hdr_size, &count, NULL );
+ if( !r )
+ return FALSE;
+ if( count != cert_hdr_size )
+ return FALSE;
+
+ DPRINT("OK\n");
return TRUE;
}
-/***********************************************************************
- * ImageGetCertificateHeader (IMAGEHLP.@)
+/*
+ * @unimplemented
+ */
+BOOL
+IMAGEAPI
+ImageGetDigestStream(HANDLE FileHandle,
+ DWORD DigestLevel,
+ DIGEST_FUNCTION DigestFunction,
+ DIGEST_HANDLE DigestHandle)
+{
+ UNIMPLEMENTED;
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+/*
+ * @unimplemented
*/
-BOOL WINAPI ImageGetCertificateHeader(
- HANDLE FileHandle, DWORD CertificateIndex,
- LPWIN_CERTIFICATE Certificateheader)
+BOOL
+IMAGEAPI
+ImageRemoveCertificate(HANDLE FileHandle,
+ DWORD Index)
{
- FIXME("(%p, %ld, %p): stub\n",
- FileHandle, CertificateIndex, Certificateheader
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ UNIMPLEMENTED;
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
}
-/***********************************************************************
- * ImageGetDigestStream (IMAGEHLP.@)
+
+/*
+ * @implemented
*/
-BOOL WINAPI ImageGetDigestStream(
- HANDLE FileHandle, DWORD DigestLevel,
- DIGEST_FUNCTION DigestFunction, DIGEST_HANDLE DigestHandle)
+PIMAGE_NT_HEADERS
+IMAGEAPI
+CheckSumMappedFile(LPVOID BaseAddress,
+ DWORD FileLength,
+ LPDWORD HeaderSum,
+ LPDWORD CheckSum)
{
- FIXME("(%p, %ld, %p, %p): stub\n",
- FileHandle, DigestLevel, DigestFunction, DigestHandle
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ PIMAGE_NT_HEADERS Header;
+ DWORD CalcSum;
+ DWORD HdrSum;
+ DPRINT("stub\n");
+
+ CalcSum = (DWORD)CalcCheckSum(0,
+ BaseAddress,
+ (FileLength + 1) / sizeof(WORD));
+
+ Header = ImageNtHeader(BaseAddress);
+ HdrSum = Header->OptionalHeader.CheckSum;
+
+ /* Subtract image checksum from calculated checksum. */
+ /* fix low word of checksum */
+ if (LOWORD(CalcSum) >= LOWORD(HdrSum))
+ {
+ CalcSum -= LOWORD(HdrSum);
+ }
+ else
+ {
+ CalcSum = ((LOWORD(CalcSum) - LOWORD(HdrSum)) & 0xFFFF) - 1;
+ }
+
+ /* fix high word of checksum */
+ if (LOWORD(CalcSum) >= HIWORD(HdrSum))
+ {
+ CalcSum -= HIWORD(HdrSum);
+ }
+ else
+ {
+ CalcSum = ((LOWORD(CalcSum) - HIWORD(HdrSum)) & 0xFFFF) - 1;
+ }
+
+ /* add file length */
+ CalcSum += FileLength;
+
+ *CheckSum = CalcSum;
+ *HeaderSum = Header->OptionalHeader.CheckSum;
+
+ return Header;
}
-/***********************************************************************
- * ImageRemoveCertificate (IMAGEHLP.@)
+/*
+ * @implemented
+ */
+DWORD
+IMAGEAPI
+MapFileAndCheckSumA(LPSTR Filename,
+ LPDWORD HeaderSum,
+ LPDWORD CheckSum)
+{
+ HANDLE hFile;
+ HANDLE hMapping;
+ LPVOID BaseAddress;
+ DWORD FileLength;
+
+ DPRINT("(%s, %p, %p): stub\n", Filename, HeaderSum, CheckSum);
+
+ hFile = CreateFileA(Filename,
+ GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ 0);
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ return CHECKSUM_OPEN_FAILURE;
+ }
+
+ hMapping = CreateFileMappingW(hFile,
+ NULL,
+ PAGE_READONLY,
+ 0,
+ 0,
+ NULL);
+ if (hMapping == 0)
+ {
+ CloseHandle(hFile);
+ return CHECKSUM_MAP_FAILURE;
+ }
+
+ BaseAddress = MapViewOfFile(hMapping,
+ FILE_MAP_READ,
+ 0,
+ 0,
+ 0);
+ if (hMapping == 0)
+ {
+ CloseHandle(hMapping);
+ CloseHandle(hFile);
+ return CHECKSUM_MAPVIEW_FAILURE;
+ }
+
+ FileLength = GetFileSize(hFile,
+ NULL);
+
+ CheckSumMappedFile(BaseAddress,
+ FileLength,
+ HeaderSum,
+ CheckSum);
+
+ UnmapViewOfFile(BaseAddress);
+ CloseHandle(hMapping);
+ CloseHandle(hFile);
+
+ return 0;
+}
+
+/*
+ * @implemented
*/
-BOOL WINAPI ImageRemoveCertificate(HANDLE FileHandle, DWORD Index)
+DWORD
+IMAGEAPI
+MapFileAndCheckSumW(LPWSTR Filename,
+ LPDWORD HeaderSum,
+ LPDWORD CheckSum)
{
- FIXME("(%p, %ld): stub\n", FileHandle, Index);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ HANDLE hFile;
+ HANDLE hMapping;
+ LPVOID BaseAddress;
+ DWORD FileLength;
+
+ DPRINT("(%S, %p, %p): stub\n", Filename, HeaderSum, CheckSum);
+
+ hFile = CreateFileW(Filename,
+ GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ 0);
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ return CHECKSUM_OPEN_FAILURE;
+ }
+
+ hMapping = CreateFileMappingW(hFile,
+ NULL,
+ PAGE_READONLY,
+ 0,
+ 0,
+ NULL);
+ if (hMapping == 0)
+ {
+ CloseHandle(hFile);
+ return CHECKSUM_MAP_FAILURE;
+ }
+
+ BaseAddress = MapViewOfFile(hMapping,
+ FILE_MAP_READ,
+ 0,
+ 0,
+ 0);
+ if (hMapping == 0)
+ {
+ CloseHandle(hMapping);
+ CloseHandle(hFile);
+ return CHECKSUM_MAPVIEW_FAILURE;
+ }
+
+ FileLength = GetFileSize(hFile,
+ NULL);
+
+ CheckSumMappedFile(BaseAddress,
+ FileLength,
+ HeaderSum,
+ CheckSum);
+
+ UnmapViewOfFile(BaseAddress);
+ CloseHandle(hMapping);
+ CloseHandle(hFile);
+
+ return 0;
}
+++ /dev/null
-/*
- * IMAGEHLP library
- *
- * Copyright 1998 Patrik Stridvall
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <stdarg.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "winerror.h"
-#include "wine/debug.h"
-#include "imagehlp.h"
-
-/***********************************************************************
- * InitializeListHead
- */
-VOID InitializeListHead(PLIST_ENTRY pListHead)
-{
- pListHead->Flink = pListHead;
- pListHead->Blink = pListHead;
-}
-
-/***********************************************************************
- * InsertHeadList
- */
-VOID InsertHeadList(PLIST_ENTRY pListHead, PLIST_ENTRY pEntry)
-{
- pEntry->Blink = pListHead;
- pEntry->Flink = pListHead->Flink;
- pListHead->Flink = pEntry;
-}
-
-/***********************************************************************
- * InsertTailList
- */
-VOID InsertTailList(PLIST_ENTRY pListHead, PLIST_ENTRY pEntry)
-{
- pEntry->Flink = pListHead;
- pEntry->Blink = pListHead->Blink;
- pListHead->Blink = pEntry;
-}
-
-/***********************************************************************
- * IsListEmpty
- */
-BOOLEAN IsListEmpty(PLIST_ENTRY pListHead)
-{
- return !pListHead;
-}
-
-/***********************************************************************
- * PopEntryList
- */
-PSINGLE_LIST_ENTRY PopEntryList(PSINGLE_LIST_ENTRY pListHead)
-{
- pListHead->Next = NULL;
- return pListHead;
-}
-
-/***********************************************************************
- * PushEntryList
- */
-VOID PushEntryList(
- PSINGLE_LIST_ENTRY pListHead, PSINGLE_LIST_ENTRY pEntry)
-{
- pEntry->Next=pListHead;
-}
-
-/***********************************************************************
- * RemoveEntryList
- */
-VOID RemoveEntryList(PLIST_ENTRY pEntry)
-{
- pEntry->Flink->Blink = pEntry->Blink;
- pEntry->Blink->Flink = pEntry->Flink;
- pEntry->Flink = NULL;
- pEntry->Blink = NULL;
-}
-
-/***********************************************************************
- * RemoveHeadList
- */
-PLIST_ENTRY RemoveHeadList(PLIST_ENTRY pListHead)
-{
- PLIST_ENTRY p = pListHead->Flink;
-
- if(p != pListHead)
- {
- RemoveEntryList(pListHead);
- return p;
- }
- else
- {
- pListHead->Flink = NULL;
- pListHead->Blink = NULL;
- return NULL;
- }
-}
-
-/***********************************************************************
- * RemoveTailList
- */
-PLIST_ENTRY RemoveTailList(PLIST_ENTRY pListHead)
-{
- RemoveHeadList(pListHead->Blink);
- if(pListHead != pListHead->Blink)
- return pListHead;
- else
- return NULL;
-}
/*
- * IMAGEHLP library
- *
- * Copyright 1998 Patrik Stridvall
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: Imagehlp Libary
+ * FILE: lib/imagehlp/modify.c
+ * PURPOSE: Binding, Base Fixing and Rebasing
+ * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
*/
-#include <stdarg.h>
+/* INCLUDES ******************************************************************/
-#include "windef.h"
-#include "winbase.h"
-#include "winerror.h"
-#include "wine/debug.h"
-#include "imagehlp.h"
+#include "precomp.h"
-WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
+//#define NDEBUG
+#include <debug.h>
-static WORD CalcCheckSum(DWORD StartValue, LPVOID BaseAddress, DWORD WordCount);
-extern PIMAGE_NT_HEADERS WINAPI ImageNtHeader(PVOID Base);
+/* DATA **********************************************************************/
-/* Internal Structures we use to keep track of the Bound Imports */
-typedef struct _BOUND_FORWARDER_REFS {
- ULONG TimeDateStamp;
- LPSTR ModuleName;
-} BOUND_FORWARDER_REFS, *PBOUND_FORWARDER_REFS;
+CHAR BoundLibraries[4096];
+LPSTR BoundLibrariesPointer;
-typedef struct _BOUND_IMPORT_DESCRIPTOR {
- LPSTR ModuleName;
- ULONG TimeDateStamp;
- USHORT ForwaderReferences;
- PBOUND_FORWARDER_REFS Forwarders;
-} BOUND_IMPORT_DESCRIPTOR, *PBOUND_IMPORT_DESCRIPTOR;
+/* FUNCTIONS *****************************************************************/
-
-VOID
-STDCALL
-BindpWalkAndBindImports(
- PLOADED_IMAGE File,
- LPSTR DllPath
- );
-
-PBOUND_IMPORT_DESCRIPTOR
-STDCALL
-BindpCreateBoundImportDescriptor(
- LPSTR LibraryName,
- PLOADED_IMAGE Library,
- PULONG BoundImportDescriptor
- );
-
-BOOL
-STDCALL
-BindpBindThunk(
- PIMAGE_THUNK_DATA Thunk,
- PLOADED_IMAGE Image,
- PIMAGE_THUNK_DATA BoundThunk,
- PLOADED_IMAGE LoadedLibrary,
- PIMAGE_EXPORT_DIRECTORY Exports,
- PBOUND_IMPORT_DESCRIPTOR BoundImportDescriptor,
- LPSTR DllPath
- );
-
-PIMAGE_BOUND_IMPORT_DESCRIPTOR
-STDCALL
-BindpCreateBoundImportSection(
- PULONG BoundImportDescriptor,
- PULONG BoundImportsSize
- );
-
-ULONG
-STDCALL
-BindpAddBoundForwarder(
- PBOUND_IMPORT_DESCRIPTOR BoundImportDescriptor,
- LPSTR DllPath,
- PUCHAR ForwarderString
- );
-
-UCHAR BoundLibraries[4096];
-LPSTR BoundLibrariesPointer = BoundLibraries;
-PULONG BoundImportDescriptors;
-
-/*
- * BindImageEx
- *
- * FUNCTION:
- * Binds a PE Image File to its imported Libraries
- * ARGUMENTS:
- * Flags - Caller Specified Flags
- * ImageName - Name of Imagefile to Bind
- * DllPath - Path to search DLL Files in, can be NULL to use Default
- * SymbolPath - Path to search Symbol Files in, can be NULL to use Default
- * StatusRoutine - Callback routine to notify of Bind Events, can be NULL to disable.
- *
- * RETURNS:
- * TRUE if Success.
- */
-BOOL
-WINAPI
-BindImageEx(
- IN DWORD Flags,
- IN LPSTR ImageName,
- IN LPSTR DllPath,
- IN LPSTR SymbolPath,
- IN PIMAGEHLP_STATUS_ROUTINE StatusRoutine
- )
+LPSTR
+IMAGEAPI
+BindpCaptureImportModuleName(LPSTR ModuleName)
{
- LOADED_IMAGE FileData;
- PLOADED_IMAGE File;
- ULONG CheckSum, HeaderSum, OldChecksum;
- SYSTEMTIME SystemTime;
- FILETIME LastWriteTime;
-
- FIXME("BindImageEx Called for: %s \n", ImageName);
-
- /* Set and Clear Buffer */
- File = &FileData;
- RtlZeroMemory(File, sizeof(*File));
-
- /* Request Image Data */
- if (MapAndLoad(ImageName, DllPath, File, TRUE, FALSE)) {
-
- //FIXME("Image Mapped and Loaded\n");
-
- /* Read Import Table */
- BindpWalkAndBindImports(File, DllPath);
-
- //FIXME("Binding Completed, getting Checksum\n");
-
- /* Update Checksum */
- OldChecksum = File->FileHeader->OptionalHeader.CheckSum;
- CheckSumMappedFile (File->MappedAddress,
- GetFileSize(File->hFile, NULL),
- &HeaderSum,
- &CheckSum);
- File->FileHeader->OptionalHeader.CheckSum = CheckSum;
-
- //FIXME("Saving Changes to file\n");
-
- /* Save Changes */
- UnmapViewOfFile(File->MappedAddress);
-
- //FIXME("Setting time\n");
-
- /* Save new Modified Time */
- GetSystemTime(&SystemTime);
- SystemTimeToFileTime(&SystemTime, &LastWriteTime);
- SetFileTime(File->hFile, NULL, NULL, &LastWriteTime);
-
- /* Close Handle */
- CloseHandle(File->hFile);
- }
-
- FIXME("Done\n");
- return TRUE;
-}
-
-/*
- * BindpWalkAndBindImports
- *
- * FUNCTION:
- * Does the actual Binding of the Imports and Forward-Referencing
- *
- * ARGUMENTS:
- * File - Name of Imagefile to Bind
- * DllPath - Path to search DLL Files in, can be NULL to use Default
- *
- * RETURNS:
- * Nothing
- */
-VOID
-STDCALL
-BindpWalkAndBindImports(
- PLOADED_IMAGE File,
- LPSTR DllPath
- )
-{
- PIMAGE_IMPORT_DESCRIPTOR Imports;
- PIMAGE_EXPORT_DIRECTORY Exports;
- ULONG SizeOfImports;
- ULONG SizeOfExports;
- ULONG SizeOfThunks;
- PIMAGE_OPTIONAL_HEADER OptionalHeader32 = NULL;
- PIMAGE_FILE_HEADER FileHeader;
- LPSTR ImportedLibrary;
- PLOADED_IMAGE LoadedLibrary;
- PBOUND_IMPORT_DESCRIPTOR BoundImportDescriptor = NULL;
- PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportTable;
- PIMAGE_THUNK_DATA Thunks, TempThunk;
- PIMAGE_THUNK_DATA BoundThunks, TempBoundThunk;
- ULONG ThunkCount = 0;
- ULONG Thunk;
- ULONG BoundImportTableSize;
- ULONG VirtBytesFree, HeaderBytesFree, FirstFreeByte, PhysBytesFree;
-
- //FIXME("BindpWalkAndBindImports Called\n");
-
- /* Load the Import Descriptor */
- Imports = ImageDirectoryEntryToData (File->MappedAddress,
- FALSE,
- IMAGE_DIRECTORY_ENTRY_IMPORT,
- &SizeOfImports);
-
- /* Read the File Header */
- FileHeader = &File->FileHeader->FileHeader;
- OptionalHeader32 = &File->FileHeader->OptionalHeader;
-
- /* Support for up to 32 imported DLLs */
- BoundImportDescriptors = GlobalAlloc(GMEM_ZEROINIT, 32* sizeof(*BoundImportDescriptor));
-
- //FIXME("BoundImportDescriptors Allocated\n");
-
- /* For each Import */
- for(; Imports->Name ; Imports++) {
-
- /* Which DLL is being Imported */
- ImportedLibrary = ImageRvaToVa (File->FileHeader,
- File->MappedAddress,
- Imports->Name,
- &File->LastRvaSection);
-
- FIXME("Loading Imported DLL: %s \n", ImportedLibrary);
-
- /* Load the DLL */
- LoadedLibrary = ImageLoad(ImportedLibrary, DllPath);
-
- FIXME("DLL Loaded at: %p \n", LoadedLibrary->MappedAddress);
-
- /* Now load the Exports */
- Exports = ImageDirectoryEntryToData (LoadedLibrary->MappedAddress,
- FALSE,
- IMAGE_DIRECTORY_ENTRY_EXPORT,
- &SizeOfExports);
-
- /* And load the Thunks */
- Thunks = ImageRvaToVa (File->FileHeader,
- File->MappedAddress,
- (ULONG)Imports->OriginalFirstThunk,
- &File->LastRvaSection);
-
- /* No actual Exports (UPX Packer can do this */
- if (!Thunks) continue;
-
- //FIXME("Creating Bound Descriptor for this DLL\n");
-
- /* Create Bound Import Descriptor */
- BoundImportDescriptor = BindpCreateBoundImportDescriptor (ImportedLibrary,
- LoadedLibrary,
- BoundImportDescriptors);
-
- /* Count how many Thunks we have */
- ThunkCount = 0;
- TempThunk = Thunks;
- while (TempThunk->u1.AddressOfData) {
- ThunkCount++;
- TempThunk++;
- }
-
- /* Allocate Memory for the Thunks we will Bind */
- SizeOfThunks = ThunkCount * sizeof(*TempBoundThunk);
- BoundThunks = GlobalAlloc(GMEM_ZEROINIT, SizeOfThunks);
-
- //FIXME("Binding Thunks\n");
-
- /* Bind the Thunks */
- TempThunk = Thunks;
- TempBoundThunk = BoundThunks;
- for (Thunk=0; Thunk < ThunkCount; Thunk++) {
- BindpBindThunk (TempThunk,
- File,
- TempBoundThunk,
- LoadedLibrary,
- Exports,
- BoundImportDescriptor,
- DllPath);
- TempThunk++;
- TempBoundThunk++;
- }
-
- /* Load the Second Thunk Array */
- TempThunk = ImageRvaToVa (File->FileHeader,
- File->MappedAddress,
- (ULONG)Imports->FirstThunk,
- &File->LastRvaSection);
-
- //FIXME("Copying Bound Thunks\n");
-
- /* Copy the Pointers */
- if (memcmp(TempThunk, BoundThunks, SizeOfThunks)) {
- RtlCopyMemory(TempThunk, BoundThunks, SizeOfThunks);
- }
-
- /* Set the TimeStamp */
- if (Imports->TimeDateStamp != 0xFFFFFFFF) {
- Imports->TimeDateStamp = 0xFFFFFFFF;
- }
-
- /* Free the Allocated Memory */
- GlobalFree(BoundThunks);
-
- //FIXME("Moving to next File\n");
- }
-
- //FIXME("Creating Bound Import Section\n");
-
- /* Create the Bound Import Table */
- BoundImportTable = BindpCreateBoundImportSection(BoundImportDescriptors, &BoundImportTableSize);
-
- /* Zero out the Bound Import Table */
- File->FileHeader->OptionalHeader.DataDirectory
- [IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;
- File->FileHeader->OptionalHeader.DataDirectory
- [IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0;
-
- /* Check if we have enough space */
- FirstFreeByte = GetImageUnusedHeaderBytes(File, &VirtBytesFree);
- HeaderBytesFree = File->Sections->VirtualAddress -
- File->FileHeader->OptionalHeader.SizeOfHeaders + VirtBytesFree;
- PhysBytesFree = File->Sections->PointerToRawData -
- File->FileHeader->OptionalHeader.SizeOfHeaders + VirtBytesFree;
-
- //FIXME("Calculating Space\n");
-
- if (BoundImportTableSize > VirtBytesFree) {
- if (BoundImportTableSize > HeaderBytesFree) {
- FIXME("Not enough Space\n");
- return; /* Fail...not enough space */
- }
- if (BoundImportTableSize <= PhysBytesFree) {
-
- FIXME("Header Recalculation\n");
- /* We have enough NULLs to add it, simply enlarge header data */
- File->FileHeader->OptionalHeader.SizeOfHeaders = File->FileHeader->OptionalHeader.SizeOfHeaders -
- VirtBytesFree +
- BoundImportTableSize +
- ((File->FileHeader->OptionalHeader.FileAlignment - 1)
- & ~(File->FileHeader->OptionalHeader.FileAlignment - 1));
-
- } else {
-
- FIXME("Header Resizing\n");
-
- /* Resize the Headers */
- //UNIMPLEMENTED
-
- /* Recalculate Headers */
- FileHeader = &File->FileHeader->FileHeader;
- OptionalHeader32 = &File->FileHeader->OptionalHeader;
- }
- }
-
- /* Set Bound Import Table Data */
- File->FileHeader->OptionalHeader.DataDirectory
- [IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = FirstFreeByte;
- File->FileHeader->OptionalHeader.DataDirectory
- [IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = BoundImportTableSize;
-
- //FIXME("Copying Bound Import Table\n");
-
- /* Copy the Bound Import Table */
- RtlCopyMemory(File->MappedAddress + FirstFreeByte, BoundImportTable, BoundImportTableSize);
-
- /* Free out local copy */
- GlobalFree(BoundImportTable);
+ LPSTR Name = BoundLibraries;
+
+ /* Check if it hasn't been initialized yet */
+ if (!BoundLibrariesPointer)
+ {
+ /* Start with a null char and set the pointer */
+ *Name = ANSI_NULL;
+ BoundLibrariesPointer = Name;
+ }
+
+ /* Loop the current buffer */
+ while (*Name)
+ {
+ /* Try to match this DLL's name and return it */
+ if (!_stricmp(Name, ModuleName)) return Name;
+
+ /* Move on to the next DLL Name */
+ Name += strlen(Name) + sizeof(CHAR);
+ }
+
+ /* If we got here, we didn't find one, so add this one to our buffer */
+ strcpy(Name, ModuleName);
+
+ /* Set the new position of the buffer, and null-terminate it */
+ BoundLibrariesPointer = Name + strlen(Name) + sizeof(CHAR);
+ *BoundLibrariesPointer = ANSI_NULL;
+
+ /* Return the pointer to the name */
+ return Name;
}
-
-/*
- * BindpCreateBoundImportSection
- *
- * FUNCTION:
- * Creates a 32-bit PE Bound Import Table
- *
- * ARGUMENTS:
- * BoundImportDescriptor - Pointer to the Bound Import Table
- * BoundImportsSize - Size of the Bound Import Table
- *
- * RETURNS:
- * PIMAGE_BOUND_IMPORT_DESCRIPTOR - The Bound Import Table
- */
PIMAGE_BOUND_IMPORT_DESCRIPTOR
-STDCALL
-BindpCreateBoundImportSection(
- PULONG BoundImportDescriptor,
- PULONG BoundImportsSize
- )
+IMAGEAPI
+BindpCreateNewImportSection(PIMPORT_DESCRIPTOR *BoundImportDescriptor,
+ PULONG BoundImportsSize)
{
- ULONG BoundLibraryNamesSize, BoundImportTableSize;
- PBOUND_FORWARDER_REFS BoundForwarder;
- PBOUND_IMPORT_DESCRIPTOR CurrentBoundImportDescriptor;
- PVOID BoundLibraryNames;
- PIMAGE_BOUND_IMPORT_DESCRIPTOR CurrentBoundImportTableEntry, BoundImportTable;
- PIMAGE_BOUND_FORWARDER_REF NewForwarder;
-
- /* Zero the Sizes */
+ ULONG BoundLibraryNamesSize = 0, BoundImportTableSize = 0;
+ PBOUND_FORWARDER_REFS Forwarder, *NextForwarder;
+ PIMPORT_DESCRIPTOR Descriptor, *NextDescriptor;
+ LPSTR BoundLibraryNames;
+ PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundTableEntry, BoundTable;
+ PIMAGE_BOUND_FORWARDER_REF BoundForwarder;
+
+ /* Zero the outoging size */
*BoundImportsSize = 0;
- BoundLibraryNamesSize = 0;
- BoundImportTableSize = 0;
-
- /* Start with the first Internal Descriptor */
- CurrentBoundImportDescriptor = (PBOUND_IMPORT_DESCRIPTOR)BoundImportDescriptor;
-
- /* Loop through every Descriptor we loaded */
- while (CurrentBoundImportDescriptor->ModuleName) {
- /* Add to the size of the Bound Import Table */
+ /* Loop the descriptors and forwarders to get the size */
+ NextDescriptor = BoundImportDescriptor;
+ while ((Descriptor = *NextDescriptor))
+ {
+ /* Add to the size of the Bound Import Table */
BoundImportTableSize += sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR);
- /* Check Forwarders */
- BoundForwarder = CurrentBoundImportDescriptor->Forwarders;
- while (BoundForwarder->ModuleName) {
-
- /* Add to size of Bound Import Table */
+ /* Check Forwarders */
+ NextForwarder = &Descriptor->Forwarders;
+ while ((Forwarder = *NextForwarder))
+ {
+ /* Add to size of Bound Import Table */
BoundImportTableSize += sizeof(IMAGE_BOUND_FORWARDER_REF);
- /* Next Forwarder */
- BoundForwarder++;
- }
-
- /* Read Next Internal Descriptor */
- CurrentBoundImportDescriptor++;
+ /* Next Forwarder */
+ NextForwarder = &Forwarder->Next;
}
- /* Add Terminator for PE Loader*/
+ /* Read Next Internal Descriptor */
+ NextDescriptor = &Descriptor->Next;
+ }
+
+ /* Add Terminator for PE Loader*/
BoundImportTableSize += sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR);
+ DPRINT("Table size: %lx\n", BoundImportTableSize);
- /* Name of Libraries Bound in Bound Import Table */
- BoundLibraryNamesSize = ((ULONG)BoundLibrariesPointer - (ULONG)(&BoundLibraries));
+ /* Name of Libraries Bound in Bound Import Table */
+ BoundLibraryNamesSize = (ULONG)((ULONG_PTR)BoundLibrariesPointer -
+ (ULONG_PTR)BoundLibraries);
+ BoundLibrariesPointer = NULL;
- /* Size of the whole table, dword aligned */
+ /* Size of the whole table, dword aligned */
*BoundImportsSize = BoundImportTableSize +
- ((BoundLibraryNamesSize + sizeof(ULONG) - 1) & ~(sizeof(ULONG)-1));
+ ((BoundLibraryNamesSize + sizeof(ULONG) - 1) &
+ ~(sizeof(ULONG) - 1));
- /* Allocate it */
- BoundImportTable = GlobalAlloc(GMEM_ZEROINIT, *BoundImportsSize);
+ /* Allocate it */
+ BoundTable = HeapAlloc(IMAGEHLP_hHeap, HEAP_ZERO_MEMORY, *BoundImportsSize);
- /* Pointer Library Names inside the Bound Import Table */
- BoundLibraryNames = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)((ULONG_PTR)BoundImportTable +
- BoundImportTableSize);
+ /* Pointer Library Names inside the Bound Import Table */
+ BoundLibraryNames = (LPSTR)BoundTable + BoundImportTableSize;
- /* Copy the Library Names */
+ /* Copy the Library Names */
RtlCopyMemory(BoundLibraryNames, BoundLibraries, BoundLibraryNamesSize);
- /* Go back to first Internal Descriptor and load first entry in the Bound Import Table */
- CurrentBoundImportTableEntry = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)BoundImportTable;
- CurrentBoundImportDescriptor = (PBOUND_IMPORT_DESCRIPTOR)BoundImportDescriptor;
-
- /* Copy the data from our Internal Structure to the Bound Import Table */
- while (CurrentBoundImportDescriptor->ModuleName) {
- CurrentBoundImportTableEntry->TimeDateStamp = CurrentBoundImportDescriptor->TimeDateStamp;
- CurrentBoundImportTableEntry->OffsetModuleName = (USHORT)(BoundImportTableSize +
- (CurrentBoundImportDescriptor->ModuleName -
- (LPSTR) BoundLibraries));
- CurrentBoundImportTableEntry->NumberOfModuleForwarderRefs = CurrentBoundImportDescriptor->ForwaderReferences;
-
- /* Copy the data from our Forwader Entries to the Bound Import Table */
- NewForwarder = (PIMAGE_BOUND_FORWARDER_REF)(CurrentBoundImportTableEntry+1);
- BoundForwarder = CurrentBoundImportDescriptor->Forwarders;
- while (BoundForwarder->ModuleName) {
- NewForwarder->TimeDateStamp =BoundForwarder->TimeDateStamp;
- NewForwarder->OffsetModuleName = (USHORT)(BoundImportTableSize +
- (BoundForwarder->ModuleName -
- (LPSTR) BoundLibraries));
- NewForwarder++;
+ /* Now loop both tables */
+ BoundTableEntry = BoundTable;
+ NextDescriptor = BoundImportDescriptor;
+ while ((Descriptor = *NextDescriptor))
+ {
+ /* Copy the data */
+ BoundTableEntry->TimeDateStamp = Descriptor->TimeDateStamp;
+ BoundTableEntry->OffsetModuleName = (USHORT)(BoundImportTableSize +
+ (Descriptor->ModuleName -
+ (ULONG_PTR)BoundLibraries));
+ BoundTableEntry->NumberOfModuleForwarderRefs = Descriptor->ForwaderReferences;
+
+ /* Now loop the forwarders */
+ BoundForwarder = (PIMAGE_BOUND_FORWARDER_REF)BoundTableEntry + 1;
+ NextForwarder = &Descriptor->Forwarders;
+ while ((Forwarder = *NextForwarder))
+ {
+ /* Copy the data */
+ BoundForwarder->TimeDateStamp = Forwarder->TimeDateStamp;
+ BoundForwarder->OffsetModuleName = (USHORT)(BoundImportTableSize +
+ (Forwarder->ModuleName -
+ (ULONG_PTR)BoundLibraries));
+
+ /* Move to the next new forwarder, and move to the next entry */
BoundForwarder++;
- }
+ NextForwarder = &Forwarder->Next;
+ }
- /* Move to next Bound Import Table Entry */
- CurrentBoundImportTableEntry = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)NewForwarder;
+ /* Move to next Bound Import Table Entry */
+ BoundTableEntry = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)BoundForwarder;
+
+ /* Move to the next descriptor */
+ NextDescriptor = &Descriptor->Next;
+ }
+
+ /* Loop the descriptors and forwarders to free them */
+ NextDescriptor = BoundImportDescriptor;
+ while ((Descriptor = *NextDescriptor))
+ {
+ /* Read next internal descriptor */
+ *NextDescriptor = Descriptor->Next;
+
+ /* Loop its forwarders */
+ NextForwarder = &Descriptor->Forwarders;
+ while ((Forwarder = *NextForwarder))
+ {
+ /* Next Forwarder */
+ *NextForwarder = Forwarder->Next;
+
+ /* Free it */
+ HeapFree(IMAGEHLP_hHeap, 0, Forwarder);
+ }
- /* move to next Internal Descriptor */
- CurrentBoundImportDescriptor++;
- }
+ /* Free it */
+ HeapFree(IMAGEHLP_hHeap, 0, Descriptor);
+ }
- /* Now put the pointer back at the beginning and clear the buffer */
- RtlZeroMemory(BoundLibraries, 4096);
- BoundLibrariesPointer = BoundLibraries;
+ /* Return the Bound Import Table */
+ return BoundTable;
+}
+
+PCHAR
+IMAGEAPI
+BindpAddForwarderReference(LPSTR ModuleName,
+ LPSTR ImportName,
+ PIMPORT_DESCRIPTOR BoundImportDescriptor,
+ LPSTR DllPath,
+ PCHAR ForwarderString,
+ PBOOL ForwarderBound)
+{
+ CHAR DllName[256];
+ PCHAR TempDllName, FunctionName;
+ PLOADED_IMAGE Library;
+ SIZE_T DllNameSize;
+ USHORT OrdinalNumber;
+ USHORT HintIndex;
+ ULONG ExportSize;
+ PIMAGE_EXPORT_DIRECTORY Exports;
+ ULONG_PTR ExportsBase;
+ PULONG AddressOfNames;
+ PUSHORT AddressOfOrdinals;
+ PULONG AddressOfPointers;
+ LPSTR ExportName;
+ ULONG_PTR ForwardedAddress;
+ PBOUND_FORWARDER_REFS Forwarder, *NextForwarder;
+ PIMAGE_OPTIONAL_HEADER OptionalHeader = NULL;
- return BoundImportTable;
+NextForwarder:
+
+ /* Get the DLL Name */
+ TempDllName = ForwarderString;
+ while (*TempDllName && *TempDllName != '.') TempDllName++;
+ if (*TempDllName != '.') return ForwarderString;
+
+ /* Get the size */
+ DllNameSize = (SIZE_T)(TempDllName - ForwarderString);
+ if (DllNameSize >= MAX_PATH) return ForwarderString;
+
+ /* Now copy the name and append the extension */
+ strncpy(DllName, ForwarderString, DllNameSize);
+ DllName[DllNameSize] = ANSI_NULL;
+ strcat(DllName, ".DLL");
+
+ /* Load it */
+ DPRINT("Loading the Thunk Library: %s \n", DllName);
+ Library = ImageLoad(DllName, DllPath);
+ if (!Library) return ForwarderString;
+
+ /* Move past the name */
+ DPRINT("It Loaded at: %p \n", Library->MappedAddress);
+ FunctionName = TempDllName += 1;
+
+ /* Load Exports */
+ Exports = ImageDirectoryEntryToData(Library->MappedAddress,
+ FALSE,
+ IMAGE_DIRECTORY_ENTRY_EXPORT,
+ &ExportSize);
+ if (!Exports) return ForwarderString;
+
+ /* Get the Optional Header */
+ OptionalHeader = &Library->FileHeader->OptionalHeader;
+
+ /* Check if we're binding by ordinal */
+ if (*FunctionName == '#')
+ {
+ /* We are, get the number and validate it */
+ OrdinalNumber = atoi(FunctionName + 1) - (USHORT)Exports->Base;
+ if (OrdinalNumber >= Exports->NumberOfFunctions) return ForwarderString;
+ }
+ else
+ {
+ /* Binding by name... */
+ OrdinalNumber = -1;
+ }
+
+ /* Get the Pointers to the Tables */
+ AddressOfNames = ImageRvaToVa(Library->FileHeader,
+ Library->MappedAddress,
+ Exports->AddressOfNames,
+ &Library->LastRvaSection);
+ AddressOfOrdinals = ImageRvaToVa(Library->FileHeader,
+ Library->MappedAddress,
+ Exports->AddressOfNameOrdinals,
+ &Library->LastRvaSection);
+ AddressOfPointers = ImageRvaToVa(Library->FileHeader,
+ Library->MappedAddress,
+ Exports->AddressOfFunctions,
+ &Library->LastRvaSection);
+
+ /* Check if we're binding by name... */
+ if (OrdinalNumber == 0xffff)
+ {
+ /* Do a full search for the ordinal */
+ for (HintIndex = 0; HintIndex < Exports->NumberOfNames; HintIndex++)
+ {
+ /* Get the Export Name */
+ ExportName = ImageRvaToVa(Library->FileHeader,
+ Library->MappedAddress,
+ (ULONG)AddressOfNames[HintIndex],
+ &Library->LastRvaSection);
+
+ /* Check if it's the one we want */
+ if (!strcmp(FunctionName, ExportName))
+ {
+ OrdinalNumber = AddressOfOrdinals[HintIndex];
+ break;
+ }
+ }
+
+ /* Make sure it's valid */
+ if (HintIndex >= Exports->NumberOfNames) return ForwarderString;
+ }
+
+ /* Get the Forwarded Address */
+ ForwardedAddress = AddressOfPointers[OrdinalNumber] +
+ OptionalHeader->ImageBase;
+
+ /* Loop the forwarders to see if this DLL was already processed */
+ NextForwarder = &BoundImportDescriptor->Forwarders;
+ while ((Forwarder = *NextForwarder))
+ {
+ /* Check for a name match */
+ if (!_stricmp(DllName, Forwarder->ModuleName)) break;
+
+ /* Move to the next one */
+ NextForwarder = &Forwarder->Next;
+ }
+
+ /* Check if we've went through them all without luck */
+ if (!Forwarder)
+ {
+ /* Allocate a forwarder structure */
+ Forwarder = HeapAlloc(IMAGEHLP_hHeap,
+ HEAP_ZERO_MEMORY,
+ sizeof(BOUND_FORWARDER_REFS));
+
+ /* Set the name */
+ Forwarder->ModuleName = BindpCaptureImportModuleName(DllName);
+
+ /* Increase the number of forwarders */
+ BoundImportDescriptor->ForwaderReferences++;
+
+ /* Link it */
+ *NextForwarder = Forwarder;
+ }
+
+ /* Set the timestamp */
+ Forwarder->TimeDateStamp = Library->FileHeader->FileHeader.TimeDateStamp;
+
+ /* Load DLL's Exports */
+ ExportsBase = (ULONG_PTR)ImageDirectoryEntryToData(Library->MappedAddress,
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_EXPORT,
+ &ExportSize) -
+ (ULONG_PTR)Library->MappedAddress;
+
+ /* Convert to VA */
+ ExportsBase += OptionalHeader->ImageBase;
+
+ /* Is this yet another Forward? */
+ DPRINT("I've thunked it\n");
+ if ((ForwardedAddress > ExportsBase) &&
+ (ForwardedAddress < (ExportsBase + ExportSize)))
+ {
+ /* Update the string pointer */
+ ForwarderString = ImageRvaToVa(Library->FileHeader,
+ Library->MappedAddress,
+ AddressOfPointers[OrdinalNumber],
+ &Library->LastRvaSection);
+ goto NextForwarder;
+ }
+ else
+ {
+ /* Update the pointer and return success */
+ ForwarderString = (PUCHAR)ForwardedAddress;
+ *ForwarderBound = TRUE;
+ }
+
+ /* Return the pointer */
+ return ForwarderString;
}
-/*
- * BindpBindThunk
- *
- * FUNCTION:
- * Finds the pointer of the Imported function, and writes it into the Thunk,
- * thus making the Thunk Bound.
- *
- * ARGUMENTS:
- * Thunk - Current Thunk in Unbound File
- * File - File containing the Thunk
- * BoundThunk - Pointer to the corresponding Bound Thunk
- * LoadedLibrary - Library containing the Exported Function
- * Exports - Export Directory of LoadedLibrary
- * BoundImportDescriptor - Internal Bound Import Descriptor of LoadedLibrary
- * DllPath - DLL Search Path
- *
- * RETURNS:
- * TRUE if Suceeded
- */
BOOL
-STDCALL
-BindpBindThunk(
- PIMAGE_THUNK_DATA Thunk,
- PLOADED_IMAGE File,
- PIMAGE_THUNK_DATA BoundThunk,
- PLOADED_IMAGE LoadedLibrary,
- PIMAGE_EXPORT_DIRECTORY Exports,
- PBOUND_IMPORT_DESCRIPTOR BoundImportDescriptor,
- LPSTR DllPath
- )
+IMAGEAPI
+BindpLookupThunk(PIMAGE_THUNK_DATA Thunk,
+ PLOADED_IMAGE Image,
+ PIMAGE_THUNK_DATA BoundThunk,
+ PIMAGE_THUNK_DATA ThunkFunction,
+ PLOADED_IMAGE Library,
+ PIMAGE_EXPORT_DIRECTORY Exports,
+ PIMPORT_DESCRIPTOR BoundImportDescriptor,
+ LPSTR DllPath,
+ PULONG *Forwarders)
{
- PULONG AddressOfNames;
- PUSHORT AddressOfOrdinals;
- PULONG AddressOfPointers;
- PIMAGE_IMPORT_BY_NAME ImportName;
- ULONG OrdinalNumber = 0;
- USHORT HintIndex;
- LPSTR ExportName;
- ULONG ExportsBase;
- ULONG ExportSize;
- UCHAR NameBuffer[32];
- PIMAGE_OPTIONAL_HEADER OptionalHeader32 = NULL;
- PIMAGE_OPTIONAL_HEADER LibraryOptionalHeader32 = NULL;
-
- /* Get the Pointers to the Tables */
- AddressOfNames = ImageRvaToVa (LoadedLibrary->FileHeader,
- LoadedLibrary->MappedAddress,
- Exports->AddressOfNames,
- &LoadedLibrary->LastRvaSection);
- AddressOfOrdinals = ImageRvaToVa (LoadedLibrary->FileHeader,
- LoadedLibrary->MappedAddress,
- Exports->AddressOfNameOrdinals,
- &LoadedLibrary->LastRvaSection);
- AddressOfPointers = ImageRvaToVa (LoadedLibrary->FileHeader,
- LoadedLibrary->MappedAddress,
- Exports->AddressOfFunctions,
- &LoadedLibrary->LastRvaSection);
-
- //FIXME("Binding a Thunk\n");
-
- /* Get the Optional Header */
- OptionalHeader32 = &File->FileHeader->OptionalHeader;
- LibraryOptionalHeader32 = &LoadedLibrary->FileHeader->OptionalHeader;
+ PULONG AddressOfNames;
+ PUSHORT AddressOfOrdinals;
+ PULONG AddressOfPointers;
+ PIMAGE_IMPORT_BY_NAME ImportName;
+ ULONG OrdinalNumber = 0;
+ USHORT HintIndex;
+ LPSTR ExportName;
+ ULONG_PTR ExportsBase;
+ ULONG ExportSize;
+ UCHAR NameBuffer[32];
+ PIMAGE_OPTIONAL_HEADER OptionalHeader = NULL;
+ PIMAGE_OPTIONAL_HEADER LibraryOptionalHeader = NULL;
+ BOOL ForwarderBound = FALSE;
+ PUCHAR ForwarderName;
+ DPRINT("Binding a Thunk\n");
+
+ /* Get the Pointers to the Tables */
+ AddressOfNames = ImageRvaToVa(Library->FileHeader,
+ Library->MappedAddress,
+ Exports->AddressOfNames,
+ &Library->LastRvaSection);
+ AddressOfOrdinals = ImageRvaToVa(Library->FileHeader,
+ Library->MappedAddress,
+ Exports->AddressOfNameOrdinals,
+ &Library->LastRvaSection);
+ AddressOfPointers = ImageRvaToVa(Library->FileHeader,
+ Library->MappedAddress,
+ Exports->AddressOfFunctions,
+ &Library->LastRvaSection);
+
+ /* Get the Optional Headers */
+ OptionalHeader = &Image->FileHeader->OptionalHeader;
+ LibraryOptionalHeader = &Library->FileHeader->OptionalHeader;
- /* Import by Ordinal */
- if (IMAGE_SNAP_BY_ORDINAL(Thunk->u1.Ordinal) == TRUE) {
+ /* Import by Ordinal */
+ if (IMAGE_SNAP_BY_ORDINAL(Thunk->u1.Ordinal) == TRUE)
+ {
+ /* Get the ordinal number and pointer to the name */
OrdinalNumber = (IMAGE_ORDINAL(Thunk->u1.Ordinal) - Exports->Base);
ImportName = (PIMAGE_IMPORT_BY_NAME)NameBuffer;
- } else {
-
- /* Import by Name */
- ImportName = ImageRvaToVa (File->FileHeader,
- File->MappedAddress,
- (ULONG)Thunk->u1.AddressOfData,
- &File->LastRvaSection);
-
- for (HintIndex = 0; HintIndex < Exports->NumberOfNames; HintIndex++) {
-
- /* Get the Export Name */
- ExportName = ImageRvaToVa (LoadedLibrary->FileHeader,
- LoadedLibrary->MappedAddress,
- (ULONG)AddressOfNames[HintIndex],
- &LoadedLibrary->LastRvaSection);
+
+ /* Setup the name for this ordinal */
+ sprintf(ImportName->Name, "Ordinal%lx\n", OrdinalNumber);
+ }
+ else
+ {
+ /* Import by Name, get the data */
+ ImportName = ImageRvaToVa(Image->FileHeader,
+ Image->MappedAddress,
+ (ULONG)Thunk->u1.AddressOfData,
+ &Image->LastRvaSection);
+
+ /* Get the hint and see if we can use it */
+ OrdinalNumber = (USHORT)(Exports->NumberOfFunctions + 1);
+ HintIndex = ImportName->Hint;
+ if (HintIndex < Exports->NumberOfNames)
+ {
+ /* Hint seems valid, get the export name */
+ ExportName = ImageRvaToVa(Library->FileHeader,
+ Library->MappedAddress,
+ (ULONG)AddressOfNames[HintIndex],
+ &Library->LastRvaSection);
+ /* Check if it's the one we want */
+ if (!strcmp(ImportName->Name, ExportName))
+ {
+ OrdinalNumber = AddressOfOrdinals[HintIndex];
+ }
+ }
+
+ /* If the ordinal isn't valid, we'll have to do a long loop */
+ if (OrdinalNumber >= Exports->NumberOfFunctions)
+ {
+ for (HintIndex = 0; HintIndex < Exports->NumberOfNames; HintIndex++)
+ {
+ /* Get the Export Name */
+ ExportName = ImageRvaToVa(Library->FileHeader,
+ Library->MappedAddress,
+ (ULONG)AddressOfNames[HintIndex],
+ &Library->LastRvaSection);
- /* Check if it's the one we want */
- if (!strcmp(ImportName->Name, ExportName)) {
- OrdinalNumber = AddressOfOrdinals[HintIndex];
- break;
+ /* Check if it's the one we want */
+ if (!strcmp(ImportName->Name, ExportName))
+ {
+ OrdinalNumber = AddressOfOrdinals[HintIndex];
+ break;
+ }
}
- }
- }
-
- /* Fail if we still didn't find anything */
- if (!OrdinalNumber) return FALSE;
-
- /* Write the Pointer */
- BoundThunk->u1.Function = (PDWORD)(AddressOfPointers[OrdinalNumber] + LibraryOptionalHeader32->ImageBase);
-
- /* Load DLL's Exports */
- ExportsBase = (ULONG)ImageDirectoryEntryToData (LoadedLibrary->MappedAddress,
- TRUE,
- IMAGE_DIRECTORY_ENTRY_EXPORT,
- &ExportSize) -
- (ULONG_PTR)LoadedLibrary->MappedAddress;
- /* RVA to VA */
- ExportsBase += LibraryOptionalHeader32->ImageBase;
-
- /* Check if the Export is forwarded (meaning that it's pointer is inside the Export Table) */
- if (BoundThunk->u1.Function > (PDWORD)ExportsBase && BoundThunk->u1.Function < (PDWORD)(ExportsBase + ExportSize)) {
-
- //FIXME("This Thunk is a forward...calling forward thunk bounder\n");
- /* Replace the Forwarder String by the actual Pointer */
- BoundThunk->u1.Function = (PDWORD)BindpAddBoundForwarder (BoundImportDescriptor,
- DllPath,
- ImageRvaToVa (LoadedLibrary->FileHeader,
- LoadedLibrary->MappedAddress,
- AddressOfPointers[OrdinalNumber],
- &LoadedLibrary->LastRvaSection));
+ /* Make sure it's valid now */
+ if (OrdinalNumber >= Exports->NumberOfFunctions) return FALSE;
+ }
+ }
+
+ /* Write the Pointer */
+ ThunkFunction->u1.Function = AddressOfPointers[OrdinalNumber] +
+ LibraryOptionalHeader->ImageBase;
+
+ /* Load DLL's Exports */
+ ExportsBase = (ULONG_PTR)ImageDirectoryEntryToData(Library->MappedAddress,
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_EXPORT,
+ &ExportSize) -
+ (ULONG_PTR)Library->MappedAddress;
+
+ /* RVA to VA */
+ ExportsBase += LibraryOptionalHeader->ImageBase;
+
+ /* Check if the Export is forwarded (meaning that it's pointer is inside the Export Table) */
+ if ((ThunkFunction->u1.Function > ExportsBase) &&
+ (ThunkFunction->u1.Function < ExportsBase + ExportSize))
+ {
+ /* Make sure we have a descriptor */
+ if (BoundImportDescriptor)
+ {
+ DPRINT("This Thunk is a forward...calling forward thunk bounder\n");
+
+ /* Get the VA of the pointer containg the name */
+ ForwarderName = ImageRvaToVa(Library->FileHeader,
+ Library->MappedAddress,
+ AddressOfPointers[OrdinalNumber],
+ &Library->LastRvaSection);
+
+ /* Replace the Forwarder String by the actual name */
+ ThunkFunction->u1.ForwarderString =
+ PtrToUlong(BindpAddForwarderReference(Image->ModuleName,
+ ImportName->Name,
+ BoundImportDescriptor,
+ DllPath,
+ ForwarderName,
+ &ForwarderBound));
+ }
- }
+ /* Check if it wasn't bound */
+ if (!ForwarderBound)
+ {
+ /* Set the chain to the ordinal to reflect this */
+ **Forwarders = (ULONG)(ThunkFunction - BoundThunk);
+ *Forwarders = (PULONG)&ThunkFunction->u1.Ordinal;
+ }
+ }
- /* Return Success */
+ /* Return Success */
return TRUE;
}
-/*
- * BindpAddBoundForwarder
- *
- * FUNCTION:
- * Finds the pointer of the Forwarded function, and writes it into the Thunk,
- * thus making the Thunk Bound.
- *
- * ARGUMENTS:
- * BoundImportDescriptor - Internal Bound Import Descriptor of LoadedLibrary
- * DllPath - DLL Search Path
- * ForwarderString - Name of the Forwader String
- *
- * RETURNS:
- * Pointer to the Forwaded Function.
- */
-ULONG
-STDCALL
-BindpAddBoundForwarder(
- PBOUND_IMPORT_DESCRIPTOR BoundImportDescriptor,
- LPSTR DllPath,
- PUCHAR ForwarderString
- )
+PIMPORT_DESCRIPTOR
+IMAGEAPI
+BindpAddImportDescriptor(PIMPORT_DESCRIPTOR *BoundImportDescriptor,
+ PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor,
+ LPSTR DllName,
+ PLOADED_IMAGE Image)
{
- CHAR DllName[256];
- PUCHAR TempDllName;
- PLOADED_IMAGE LoadedLibrary;
- ULONG DllNameSize;
- USHORT OrdinalNumber = 0;
- USHORT HintIndex;
- ULONG ExportSize;
+ PIMPORT_DESCRIPTOR Descriptor, *NextDescriptor;
+
+ /* Loop descriptors and check if this library has already been bound */
+ NextDescriptor = BoundImportDescriptor;
+ while ((Descriptor = *NextDescriptor))
+ {
+ /* Compare the names and return the descriptor if found */
+ if (!_stricmp(Descriptor->ModuleName, DllName)) return Descriptor;
+
+ /* Move to the next one */
+ NextDescriptor = &Descriptor->Next;
+ }
+
+ /* Allocate a new descriptor */
+ Descriptor = HeapAlloc(IMAGEHLP_hHeap,
+ HEAP_ZERO_MEMORY,
+ sizeof(IMPORT_DESCRIPTOR));
+
+ /* Set its Data and check if we have a valid loaded image */
+ Descriptor->ModuleName = BindpCaptureImportModuleName(DllName);
+ *NextDescriptor = Descriptor;
+ if (Image)
+ {
+ /* Save the time stamp */
+ Descriptor->TimeDateStamp = Image->FileHeader->FileHeader.TimeDateStamp;
+ }
+
+ /* Return the descriptor */
+ return Descriptor;
+}
+
+VOID
+IMAGEAPI
+BindpWalkAndProcessImports(PLOADED_IMAGE File,
+ LPSTR DllPath,
+ PBOOLEAN UpdateImage)
+{
+ PIMAGE_IMPORT_DESCRIPTOR Imports;
PIMAGE_EXPORT_DIRECTORY Exports;
- ULONG ExportsBase;
- PULONG AddressOfNames;
- PUSHORT AddressOfOrdinals;
- PULONG AddressOfPointers;
- LPSTR ExportName;
- ULONG ForwardedAddress;
- PBOUND_FORWARDER_REFS BoundForwarder;
- PIMAGE_OPTIONAL_HEADER OptionalHeader32 = NULL;
+ ULONG SizeOfImports;
+ ULONG SizeOfExports;
+ ULONG SizeOfThunks;
+ PIMAGE_OPTIONAL_HEADER OptionalHeader;
+ PIMAGE_FILE_HEADER FileHeader;
+ LPSTR ImportedLibrary;
+ PLOADED_IMAGE LoadedLibrary;
+ ULONG TopForwarderChain;
+ PULONG ForwarderChain;
+ PIMPORT_DESCRIPTOR TopBoundDescriptor = NULL, BoundImportDescriptor;
+ PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportTable, OldBoundImportTable;
+ PIMAGE_THUNK_DATA Thunks, TempThunk;
+ PIMAGE_THUNK_DATA BoundThunks, TempBoundThunk;
+ ULONG ThunkCount = 0;
+ ULONG Thunk;
+ ULONG BoundImportTableSize, OldBoundImportTableSize;
+ ULONG VirtBytesFree, HeaderBytesFree, FirstFreeByte, PhysBytesFree;
+ BOOL ThunkStatus;
+ DPRINT("BindpWalkAndBindImports Called\n");
+
+ /* Assume untouched image */
+ *UpdateImage = FALSE;
+
+ /* Load the Import Descriptor */
+ Imports = ImageDirectoryEntryToData(File->MappedAddress,
+ FALSE,
+ IMAGE_DIRECTORY_ENTRY_IMPORT,
+ &SizeOfImports);
+ if (!Imports) return;
+
+ /* Read the File Header */
+ FileHeader = &File->FileHeader->FileHeader;
+ OptionalHeader = &File->FileHeader->OptionalHeader;
+
+ /* Get the old Bound Import Table, if any */
+ OldBoundImportTable = ImageDirectoryEntryToData(File->MappedAddress,
+ FALSE,
+ IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT,
+ &OldBoundImportTableSize);
+
+ /* For each Import */
+ while(Imports)
+ {
+ /* Make sure we have a name */
+ if (!Imports->Name) break;
+
+ /* Which DLL is being Imported */
+ ImportedLibrary = ImageRvaToVa(File->FileHeader,
+ File->MappedAddress,
+ Imports->Name,
+ &File->LastRvaSection);
+ if (ImportedLibrary)
+ {
+ DPRINT("Loading Imported DLL: %s \n", ImportedLibrary);
+
+ /* Load the DLL */
+ LoadedLibrary = ImageLoad(ImportedLibrary, DllPath);
+ if (!LoadedLibrary)
+ {
+ /* Create the descriptor, even if we failed */
+ BindpAddImportDescriptor(&TopBoundDescriptor,
+ Imports,
+ ImportedLibrary,
+ LoadedLibrary);
+
+ /* Move on the next file */
+ Imports++;
+ continue;
+ }
-NextForwarder:
+ /* Now load the Exports */
+ DPRINT("DLL Loaded at: %p \n", LoadedLibrary->MappedAddress);
+ Exports = ImageDirectoryEntryToData(LoadedLibrary->MappedAddress,
+ FALSE,
+ IMAGE_DIRECTORY_ENTRY_EXPORT,
+ &SizeOfExports);
- /* Get the DLL Name */
- TempDllName = ForwarderString;
- while (*TempDllName && *TempDllName != '.') TempDllName++;
- DllNameSize = (ULONG) (TempDllName - ForwarderString);
- lstrcpyn(DllName, ForwarderString, DllNameSize + 1);
-
- /* Append .DLL extension */
- DllName[DllNameSize] = '\0';
- strcat(DllName, ".DLL" );
-
- /* Load it */
- FIXME("Loading the Thunk Library: %s \n", DllName);
- LoadedLibrary = ImageLoad(DllName, DllPath);
- TempDllName += 1;
-
- /* Return whatever we got back in case of failure*/
- if (!LoadedLibrary) return (ULONG)ForwarderString;
- FIXME("It Loaded at: %p \n", LoadedLibrary->MappedAddress);
-
- /* Load Exports */
- Exports = ImageDirectoryEntryToData(LoadedLibrary->MappedAddress, FALSE, IMAGE_DIRECTORY_ENTRY_EXPORT, &ExportSize);
-
- /* Get the Pointers to the Tables */
- AddressOfNames = ImageRvaToVa (LoadedLibrary->FileHeader,
- LoadedLibrary->MappedAddress,
- Exports->AddressOfNames,
- &LoadedLibrary->LastRvaSection);
- AddressOfOrdinals = ImageRvaToVa (LoadedLibrary->FileHeader,
- LoadedLibrary->MappedAddress,
- Exports->AddressOfNameOrdinals,
- &LoadedLibrary->LastRvaSection);
- AddressOfPointers = ImageRvaToVa (LoadedLibrary->FileHeader,
- LoadedLibrary->MappedAddress,
- Exports->AddressOfFunctions,
- &LoadedLibrary->LastRvaSection);
-
- /* Get the Optional Header */
- OptionalHeader32 = &LoadedLibrary->FileHeader->OptionalHeader;
-
- /* Get the Ordinal Number */
- for (HintIndex = 0; HintIndex < Exports->NumberOfNames; HintIndex++) {
-
- /* Get the Export Name */
- ExportName = ImageRvaToVa (LoadedLibrary->FileHeader,
- LoadedLibrary->MappedAddress,
- AddressOfNames[HintIndex],
- &LoadedLibrary->LastRvaSection);
-
- /* Check if it matches */
- if (!strcmp(TempDllName, ExportName)) {
- OrdinalNumber = AddressOfOrdinals[HintIndex];
- break;
+ /* Move on, if we don't have exports */
+ if (!Exports) continue;
+
+ /* And load the Thunks */
+ Thunks = ImageRvaToVa(File->FileHeader,
+ File->MappedAddress,
+ (ULONG)Imports->OriginalFirstThunk,
+ &File->LastRvaSection);
+
+ /* No actual Exports (UPX Packer can do this */
+ if (!(Thunks) || !(Thunks->u1.Function)) continue;
+
+ /* Create Bound Import Descriptor */
+ DPRINT("Creating Bound Descriptor for this DLL\n");
+ BoundImportDescriptor = BindpAddImportDescriptor(&TopBoundDescriptor,
+ Imports,
+ ImportedLibrary,
+ LoadedLibrary);
+
+ /* Count how many Thunks we have */
+ ThunkCount = 0;
+ TempThunk = Thunks;
+ while (TempThunk->u1.AddressOfData)
+ {
+ ThunkCount++;
+ TempThunk++;
+ }
+
+ /* Allocate Memory for the Thunks we will Bind */
+ SizeOfThunks = ThunkCount * sizeof(*TempBoundThunk);
+ BoundThunks = HeapAlloc(IMAGEHLP_hHeap,
+ HEAP_ZERO_MEMORY,
+ SizeOfThunks);
+
+ /* Setup the initial data pointers */
+ DPRINT("Binding Thunks\n");
+ TempThunk = Thunks;
+ TempBoundThunk = BoundThunks;
+ TopForwarderChain = -1;
+ ForwarderChain = &TopForwarderChain;
+
+ /* Loop for every thunk */
+ for (Thunk = 0; Thunk < ThunkCount; Thunk++)
+ {
+ /* Bind it */
+ ThunkStatus = BindpLookupThunk(TempThunk,
+ File,
+ BoundThunks,
+ TempBoundThunk,
+ LoadedLibrary,
+ Exports,
+ BoundImportDescriptor,
+ DllPath,
+ &ForwarderChain);
+ /* Check if binding failed */
+ if (!ThunkStatus)
+ {
+ /* If we have a descriptor */
+ if (BoundImportDescriptor)
+ {
+ /* Zero the timestamp */
+ BoundImportDescriptor->TimeDateStamp = 0;
+ }
+
+ /* Quit the loop */
+ break;
+ }
+
+ /* Move on */
+ TempThunk++;
+ TempBoundThunk++;
+ }
+
+ /* Load the Second Thunk Array */
+ TempThunk = ImageRvaToVa(File->FileHeader,
+ File->MappedAddress,
+ (ULONG)Imports->FirstThunk,
+ &File->LastRvaSection);
+ if (TempThunk)
+ {
+ /* Check if the forwarder chain changed */
+ if (TopForwarderChain != -1)
+ {
+ /* It did. Update the chain and let caller know */
+ *ForwarderChain = -1;
+ *UpdateImage = TRUE;
+ }
+
+ /* Check if we're not pointing at the new top chain */
+ if (Imports->ForwarderChain != TopForwarderChain)
+ {
+ /* Update it, and let the caller know */
+ Imports->ForwarderChain = TopForwarderChain;
+ *UpdateImage = TRUE;
+ }
+
+ /* Check if thunks have changed */
+ if (memcmp(TempThunk, BoundThunks, SizeOfThunks))
+ {
+ /* Copy the Pointers and let caller know */
+ DPRINT("Copying Bound Thunks\n");
+ RtlCopyMemory(TempThunk, BoundThunks, SizeOfThunks);
+ *UpdateImage = TRUE;
+ }
+
+ /* Check if we have no bound entries */
+ if (!TopBoundDescriptor)
+ {
+ /* Check if the timestamp is different */
+ if (Imports->TimeDateStamp != FileHeader->TimeDateStamp)
+ {
+ /* Update it, and let the caller knmow */
+ Imports->TimeDateStamp = FileHeader->TimeDateStamp;
+ *UpdateImage = TRUE;
+ }
+ }
+ else if ((Imports->TimeDateStamp != 0xFFFFFFFF))
+ {
+ /* Invalidate the timedate stamp */
+ Imports->TimeDateStamp = 0xFFFFFFFF;
+ }
+ }
+
+ /* Free the Allocated Memory */
+ HeapFree(IMAGEHLP_hHeap, 0, BoundThunks);
+
+ DPRINT("Moving to next File\n");
+ Imports++;
}
- }
-
- do {
- /* Get the Forwarded Address */
- ForwardedAddress = AddressOfPointers[OrdinalNumber] + OptionalHeader32->ImageBase;
-
- /* Load the First Bound Forward Structure */
- BoundForwarder = BoundImportDescriptor->Forwarders;
-
- /* Check if we already have the Module Name written */
- while (BoundForwarder->ModuleName) {
- if (!lstrcmpi(DllName, BoundForwarder->ModuleName)) break;
- BoundForwarder++;
- }
-
- if (!BoundForwarder->ModuleName) {
-
- /* Save Library Name in Bound Libraries Buffer */
- strcat((char *)BoundLibrariesPointer, DllName);
-
- /* Set Data */
- BoundForwarder->ModuleName = BoundLibrariesPointer;
- BoundForwarder->TimeDateStamp = LoadedLibrary->FileHeader->FileHeader.TimeDateStamp;
-
- /* Next String */
- BoundLibrariesPointer = BoundLibrariesPointer + strlen((char *)BoundLibrariesPointer) + 1;
- BoundImportDescriptor->ForwaderReferences += 1;
- }
-
- /* Load DLL's Exports */
- ExportsBase = (ULONG)ImageDirectoryEntryToData (LoadedLibrary->MappedAddress,
- TRUE,
- IMAGE_DIRECTORY_ENTRY_EXPORT,
- &ExportSize) -
- (ULONG_PTR)LoadedLibrary->MappedAddress;
- ExportsBase += OptionalHeader32->ImageBase;
-
- //FIXME("I've thunked it\n");
-
- /* Is this yet another Forward? */
- if (ForwardedAddress > ExportsBase && ForwardedAddress < (ExportsBase + ExportSize)) {
- ForwarderString = ImageRvaToVa (LoadedLibrary->FileHeader,
- LoadedLibrary->MappedAddress,
- AddressOfPointers[OrdinalNumber],
- &LoadedLibrary->LastRvaSection);
- goto NextForwarder;
- }
- }
- while (0);
- return ForwardedAddress;
-}
+ }
+
+ /* Create the Bound Import Table */
+ DPRINT("Creating Bound Import Section\n");
+ BoundImportTable = BindpCreateNewImportSection(&TopBoundDescriptor,
+ &BoundImportTableSize);
+
+ /* Check if the import table changed */
+ if (OldBoundImportTableSize != BoundImportTableSize)
+ {
+ /* Let the caller know */
+ *UpdateImage = TRUE;
+ }
+
+ /*
+ * At this point, check if anything that we've done until now has resulted
+ * in the image being touched. If not, then we'll simply return to caller.
+ */
+ if (!(*UpdateImage)) return;
+
+ /* Check if we have a new table */
+ if (BoundImportTable)
+ {
+ /* Zero it out */
+ OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;
+ OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0;
+
+ /* Check if we have enough space */
+ DPRINT("Calculating Space\n");
+ FirstFreeByte = GetImageUnusedHeaderBytes(File, &VirtBytesFree);
+ HeaderBytesFree = File->Sections->VirtualAddress -
+ OptionalHeader->SizeOfHeaders + VirtBytesFree;
+ PhysBytesFree = File->Sections->PointerToRawData -
+ OptionalHeader->SizeOfHeaders + VirtBytesFree;
+
+ /* Check if we overflowed */
+ if (BoundImportTableSize > VirtBytesFree)
+ {
+ /* Check if we have no space a tall */
+ if (BoundImportTableSize > HeaderBytesFree)
+ {
+ DPRINT1("Not enough Space\n");
+ return; /* Fail...not enough space */
+ }
-/*
- * BindpCreateBoundImportDescriptor
- *
- * FUNCTION:
- * Creates an Internal Structure for the Bound Library
- *
- * ARGUMENTS:
- * LibraryName - Name of the Library
- * Library - Loaded Library
- * BoundImportDescriptor - Internal Bound Import Descriptor of Library
- *
- * RETURNS:
- * PBOUND_IMPORT_DESCRIPTOR - Pointer to the Internal Bind Structure
- */
-PBOUND_IMPORT_DESCRIPTOR
-STDCALL
-BindpCreateBoundImportDescriptor(
- LPSTR LibraryName,
- PLOADED_IMAGE Library,
- PULONG BoundImportDescriptor
- )
-{
- PBOUND_IMPORT_DESCRIPTOR CurrentBoundImportDescriptor;
-
- /* Load the First Descriptor */
- CurrentBoundImportDescriptor = (PBOUND_IMPORT_DESCRIPTOR)BoundImportDescriptor;
-
- /* Check if we've already bound this library */
- while (CurrentBoundImportDescriptor->ModuleName) {
- if (!lstrcmpi(CurrentBoundImportDescriptor->ModuleName, LibraryName)) {
- return CurrentBoundImportDescriptor;
- }
- CurrentBoundImportDescriptor++;
- }
-
- /* Save Library Name in Bound Libraries Buffer */
- strcat((char *)BoundLibrariesPointer, LibraryName);
-
- /* Set Data */
- CurrentBoundImportDescriptor->ModuleName = BoundLibrariesPointer;
- CurrentBoundImportDescriptor->TimeDateStamp = Library->FileHeader->FileHeader.TimeDateStamp;
-
- /* Support for up to 32 Forwarded DLLs */
- CurrentBoundImportDescriptor->Forwarders = GlobalAlloc(GMEM_ZEROINIT, 32* sizeof(BOUND_FORWARDER_REFS));
-
- /* Next String */
- BoundLibrariesPointer = BoundLibrariesPointer + strlen((char *)BoundLibrariesPointer) + 1;
-
- return CurrentBoundImportDescriptor;
+ /* Check if we have space on disk to enlarge it */
+ if (BoundImportTableSize <= PhysBytesFree)
+ {
+ /* We have enough NULLs to add it, simply enlarge header data */
+ DPRINT("Header Recalculation\n");
+ OptionalHeader->SizeOfHeaders = OptionalHeader->SizeOfHeaders -
+ VirtBytesFree +
+ BoundImportTableSize +
+ ((OptionalHeader->FileAlignment - 1) &
+ ~(OptionalHeader->FileAlignment - 1));
+ }
+ else
+ {
+ /* Resize the Headers */
+ DPRINT1("UNIMPLEMENTED: Header Resizing\n");
+
+ /* Recalculate Headers */
+ FileHeader = &File->FileHeader->FileHeader;
+ OptionalHeader = &File->FileHeader->OptionalHeader;
+ }
+ }
+
+ /* Set Bound Import Table Data */
+ OptionalHeader->DataDirectory
+ [IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = FirstFreeByte;
+ OptionalHeader->DataDirectory
+ [IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = BoundImportTableSize;
+
+ /* Copy the Bound Import Table */
+ DPRINT("Copying Bound Import Table\n");
+ RtlCopyMemory(File->MappedAddress + FirstFreeByte,
+ BoundImportTable,
+ BoundImportTableSize);
+
+ /* Free the data */
+ HeapFree(IMAGEHLP_hHeap, 0, BoundImportTable);
+ }
+
}
-/***********************************************************************
- * BindImage (IMAGEHLP.@)
+/*
+ * @implemented
*/
-BOOL WINAPI BindImage(
- LPSTR ImageName, LPSTR DllPath, LPSTR SymbolPath)
+BOOL
+IMAGEAPI
+BindImageEx(IN DWORD Flags,
+ IN LPSTR ImageName,
+ IN LPSTR DllPath,
+ IN LPSTR SymbolPath,
+ IN PIMAGEHLP_STATUS_ROUTINE StatusRoutine)
{
- return BindImageEx(0, ImageName, DllPath, SymbolPath, NULL);
-}
+ LOADED_IMAGE FileData;
+ PLOADED_IMAGE File;
+ PIMAGE_FILE_HEADER FileHeader;
+ PIMAGE_OPTIONAL_HEADER32 OptionalHeader;
+ ULONG CheckSum, HeaderCheckSum, OldChecksum;
+ SYSTEMTIME SystemTime;
+ FILETIME LastWriteTime;
+ BOOLEAN UpdateImage;
+ DWORD DataSize;
+ DPRINT("BindImageEx Called for: %s \n", ImageName);
+
+ /* Set and Clear Buffer */
+ File = &FileData;
+ RtlZeroMemory(File, sizeof(*File));
+
+ /* Request Image Data */
+ if (MapAndLoad(ImageName, DllPath, File, TRUE, FALSE))
+ {
+ /* Write the image's name */
+ DPRINT("Image Mapped and Loaded\n");
+ File->ModuleName = ImageName;
+
+ /* Check if the image is valid and if it should be bound */
+ if ((File->FileHeader) &&
+ ((Flags & BIND_ALL_IMAGES) || (!File->fSystemImage)))
+ {
+ /* Get the optional header */
+ FileHeader = &File->FileHeader->FileHeader;
+ OptionalHeader = &File->FileHeader->OptionalHeader;
+
+ /* Check if this image should be bound */
+ if (OptionalHeader->DllCharacteristics &
+ IMAGE_DLLCHARACTERISTICS_NO_BIND)
+ {
+ /* Don't bind it */
+ goto Skip;
+ }
-/***********************************************************************
- * CheckSum (internal)
- */
-static WORD CalcCheckSum(
- DWORD StartValue, LPVOID BaseAddress, DWORD WordCount)
-{
- LPWORD Ptr;
- DWORD Sum;
- DWORD i;
-
- Sum = StartValue;
- Ptr = (LPWORD)BaseAddress;
- for (i = 0; i < WordCount; i++)
- {
- Sum += *Ptr;
- if (HIWORD(Sum) != 0)
- {
- Sum = LOWORD(Sum) + HIWORD(Sum);
- }
- Ptr++;
- }
-
- return (WORD)(LOWORD(Sum) + HIWORD(Sum));
-}
+ /* Check if the image has security data */
+ if ((ImageDirectoryEntryToData(File->MappedAddress,
+ FALSE,
+ IMAGE_DIRECTORY_ENTRY_SECURITY,
+ &DataSize)) || DataSize)
+ {
+ /* It does, skip it */
+ goto Skip;
+ }
+ /* Read Import Table */
+ BindpWalkAndProcessImports(File, DllPath, &UpdateImage);
-/***********************************************************************
- * CheckSumMappedFile (IMAGEHLP.@)
- */
-PIMAGE_NT_HEADERS WINAPI CheckSumMappedFile(
- LPVOID BaseAddress, DWORD FileLength,
- LPDWORD HeaderSum, LPDWORD CheckSum)
-{
- PIMAGE_NT_HEADERS Header;
- DWORD CalcSum;
- DWORD HdrSum;
-
- FIXME("stub\n");
-
- CalcSum = (DWORD)CalcCheckSum(0,
- BaseAddress,
- (FileLength + 1) / sizeof(WORD));
-
- Header = ImageNtHeader(BaseAddress);
- HdrSum = Header->OptionalHeader.CheckSum;
-
- /* Subtract image checksum from calculated checksum. */
- /* fix low word of checksum */
- if (LOWORD(CalcSum) >= LOWORD(HdrSum))
- {
- CalcSum -= LOWORD(HdrSum);
- }
- else
- {
- CalcSum = ((LOWORD(CalcSum) - LOWORD(HdrSum)) & 0xFFFF) - 1;
- }
-
- /* fix high word of checksum */
- if (LOWORD(CalcSum) >= HIWORD(HdrSum))
- {
- CalcSum -= HIWORD(HdrSum);
- }
- else
- {
- CalcSum = ((LOWORD(CalcSum) - HIWORD(HdrSum)) & 0xFFFF) - 1;
- }
-
- /* add file length */
- CalcSum += FileLength;
-
- *CheckSum = CalcSum;
- *HeaderSum = Header->OptionalHeader.CheckSum;
-
- return Header;
-}
+ /* Check if we need to update the image */
+ if ((UpdateImage) && (File->hFile != INVALID_HANDLE_VALUE))
+ {
+ /* FIXME: Update symbols */
+
+ /* Update Checksum */
+ DPRINT("Binding Completed, getting Checksum\n");
+ OldChecksum = File->FileHeader->OptionalHeader.CheckSum;
+ CheckSumMappedFile(File->MappedAddress,
+ GetFileSize(File->hFile, NULL),
+ &HeaderCheckSum,
+ &CheckSum);
+ File->FileHeader->OptionalHeader.CheckSum = CheckSum;
+
+ /* Save Changes */
+ DPRINT("Saving Changes to file\n");
+ FlushViewOfFile(File->MappedAddress, File->SizeOfImage);
+
+ /* Save new Modified Time */
+ DPRINT("Setting time\n");
+ GetSystemTime(&SystemTime);
+ SystemTimeToFileTime(&SystemTime, &LastWriteTime);
+ SetFileTime(File->hFile, NULL, NULL, &LastWriteTime);
+ }
+ }
+ }
-/***********************************************************************
- * MapFileAndCheckSumA (IMAGEHLP.@)
- */
-DWORD WINAPI MapFileAndCheckSumA(
- LPSTR Filename, LPDWORD HeaderSum, LPDWORD CheckSum)
-{
- HANDLE hFile;
- HANDLE hMapping;
- LPVOID BaseAddress;
- DWORD FileLength;
-
- TRACE("(%s, %p, %p): stub\n",
- debugstr_a(Filename), HeaderSum, CheckSum
- );
-
- hFile = CreateFileA(Filename,
- GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- 0);
- if (hFile == INVALID_HANDLE_VALUE)
- {
- return CHECKSUM_OPEN_FAILURE;
- }
-
- hMapping = CreateFileMappingW(hFile,
- NULL,
- PAGE_READONLY,
- 0,
- 0,
- NULL);
- if (hMapping == 0)
- {
- CloseHandle(hFile);
- return CHECKSUM_MAP_FAILURE;
- }
-
- BaseAddress = MapViewOfFile(hMapping,
- FILE_MAP_READ,
- 0,
- 0,
- 0);
- if (hMapping == 0)
- {
- CloseHandle(hMapping);
- CloseHandle(hFile);
- return CHECKSUM_MAPVIEW_FAILURE;
- }
-
- FileLength = GetFileSize(hFile,
- NULL);
-
- CheckSumMappedFile(BaseAddress,
- FileLength,
- HeaderSum,
- CheckSum);
-
- UnmapViewOfFile(BaseAddress);
- CloseHandle(hMapping);
- CloseHandle(hFile);
-
- return 0;
-}
+Skip:
-/***********************************************************************
- * MapFileAndCheckSumW (IMAGEHLP.@)
- */
-DWORD WINAPI MapFileAndCheckSumW(
- LPWSTR Filename, LPDWORD HeaderSum, LPDWORD CheckSum)
-{
- HANDLE hFile;
- HANDLE hMapping;
- LPVOID BaseAddress;
- DWORD FileLength;
-
- TRACE("(%s, %p, %p): stub\n",
- debugstr_w(Filename), HeaderSum, CheckSum
- );
-
- hFile = CreateFileW(Filename,
- GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- 0);
- if (hFile == INVALID_HANDLE_VALUE)
- {
- return CHECKSUM_OPEN_FAILURE;
- }
-
- hMapping = CreateFileMappingW(hFile,
- NULL,
- PAGE_READONLY,
- 0,
- 0,
- NULL);
- if (hMapping == 0)
- {
- CloseHandle(hFile);
- return CHECKSUM_MAP_FAILURE;
- }
-
- BaseAddress = MapViewOfFile(hMapping,
- FILE_MAP_READ,
- 0,
- 0,
- 0);
- if (hMapping == 0)
- {
- CloseHandle(hMapping);
- CloseHandle(hFile);
- return CHECKSUM_MAPVIEW_FAILURE;
- }
-
- FileLength = GetFileSize(hFile,
- NULL);
-
- CheckSumMappedFile(BaseAddress,
- FileLength,
- HeaderSum,
- CheckSum);
-
- UnmapViewOfFile(BaseAddress);
- CloseHandle(hMapping);
- CloseHandle(hFile);
-
- return 0;
-}
+ /* Unmap the image */
+ UnmapViewOfFile(File->MappedAddress);
-/***********************************************************************
- * ReBaseImage (IMAGEHLP.@)
- */
-BOOL WINAPI ReBaseImage(
- LPSTR CurrentImageName, LPSTR SymbolPath, BOOL fReBase,
- BOOL fRebaseSysfileOk, BOOL fGoingDown, ULONG CheckImageSize,
- ULONG *OldImageSize, ULONG *OldImageBase, ULONG *NewImageSize,
- ULONG *NewImageBase, ULONG TimeStamp)
-{
- FIXME(
- "(%s, %s, %d, %d, %d, %ld, %p, %p, %p, %p, %ld): stub\n",
- debugstr_a(CurrentImageName),debugstr_a(SymbolPath), fReBase,
- fRebaseSysfileOk, fGoingDown, CheckImageSize, OldImageSize,
- OldImageBase, NewImageSize, NewImageBase, TimeStamp
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
+ /* Close the handle if it's valid */
+ if (File->hFile != INVALID_HANDLE_VALUE) CloseHandle(File->hFile);
-/***********************************************************************
- * RemovePrivateCvSymbolic (IMAGEHLP.@)
- */
-BOOL WINAPI RemovePrivateCvSymbolic(
- PCHAR DebugData, PCHAR *NewDebugData, ULONG *NewDebugSize)
-{
- FIXME("(%p, %p, %p): stub\n",
- DebugData, NewDebugData, NewDebugSize
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ /* Unload all the images if we're not supposed to cache them */
+ if (!(Flags & BIND_CACHE_IMPORT_DLLS)) UnloadAllImages();
+
+ /* Return success */
+ DPRINT("Done\n");
+ return TRUE;
}
-/***********************************************************************
- * RemoveRelocations (IMAGEHLP.@)
+/*
+ * @implemented
*/
-VOID WINAPI RemoveRelocations(PCHAR ImageName)
+BOOL
+IMAGEAPI
+BindImage(LPSTR ImageName,
+ LPSTR DllPath,
+ LPSTR SymbolPath)
{
- FIXME("(%p): stub\n", ImageName);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ /* Call the newer API */
+ return BindImageEx(0,
+ ImageName,
+ DllPath,
+ SymbolPath,
+ NULL);
}
-/***********************************************************************
- * SplitSymbols (IMAGEHLP.@)
+/*
+ * @unimplemented
*/
-BOOL WINAPI SplitSymbols(
- LPSTR ImageName, LPSTR SymbolsPath,
- LPSTR SymbolFilePath, DWORD Flags)
+BOOL
+IMAGEAPI
+ReBaseImage(LPSTR CurrentImageName,
+ LPSTR SymbolPath,
+ BOOL fReBase,
+ BOOL fRebaseSysfileOk,
+ BOOL fGoingDown,
+ ULONG CheckImageSize,
+ ULONG *OldImageSize,
+ ULONG *OldImageBase,
+ ULONG *NewImageSize,
+ ULONG *NewImageBase,
+ ULONG TimeStamp)
{
- FIXME("(%s, %s, %s, %ld): stub\n",
- debugstr_a(ImageName), debugstr_a(SymbolsPath),
- debugstr_a(SymbolFilePath), Flags
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ UNIMPLEMENTED;
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
}
-/***********************************************************************
- * UpdateDebugInfoFile (IMAGEHLP.@)
+/*
+ * @unimplemented
*/
-BOOL WINAPI UpdateDebugInfoFile(
- LPSTR ImageFileName, LPSTR SymbolPath,
- LPSTR DebugFilePath, PIMAGE_NT_HEADERS NtHeaders)
+VOID
+IMAGEAPI
+RemoveRelocations(PCHAR ImageName)
{
- FIXME("(%s, %s, %s, %p): stub\n",
- debugstr_a(ImageFileName), debugstr_a(SymbolPath),
- debugstr_a(DebugFilePath), NtHeaders
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ UNIMPLEMENTED;
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
}
-/***********************************************************************
- * UpdateDebugInfoFileEx (IMAGEHLP.@)
+/*
+ * @implemented
*/
-BOOL WINAPI UpdateDebugInfoFileEx(
- LPSTR ImageFileName, LPSTR SymbolPath, LPSTR DebugFilePath,
- PIMAGE_NT_HEADERS NtHeaders, DWORD OldChecksum)
+BOOL
+IMAGEAPI
+TouchFileTimes(HANDLE FileHandle,
+ LPSYSTEMTIME lpSystemTime)
{
- FIXME("(%s, %s, %s, %p, %ld): stub\n",
- debugstr_a(ImageFileName), debugstr_a(SymbolPath),
- debugstr_a(DebugFilePath), NtHeaders, OldChecksum
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ FILETIME FileTime;
+ SYSTEMTIME SystemTime;
+
+ if(lpSystemTime == NULL)
+ {
+ GetSystemTime(&SystemTime);
+ lpSystemTime = &SystemTime;
+ }
+
+ return (SystemTimeToFileTime(lpSystemTime,
+ &FileTime) &&
+ SetFileTime(FileHandle,
+ NULL,
+ NULL,
+ &FileTime));
}
--- /dev/null
+/*\r
+ * COPYRIGHT: See COPYING in the top level directory\r
+ * PROJECT: ReactOS System Libraries\r
+ * FILE: lib/imagehlp/precomp.h\r
+ * PURPOSE: Imagehlp Libary Header\r
+ * PROGRAMMER: Alex Ionescu (alex@relsoft.net)\r
+ */\r
+\r
+/* INCLUDES ******************************************************************/\r
+\r
+/* Definitions */\r
+#define _CRT_SECURE_NO_DEPRECATE\r
+#define NTOS_MODE_USER\r
+#define WIN32_NO_STATUS\r
+\r
+/* PSDK/NDK Headers */\r
+#include <windows.h>\r
+#include <imagehlp.h>\r
+#include <ndk/umtypes.h>\r
+#include <ndk/rtlfuncs.h>\r
+\r
+/* C STDLIB Headers */\r
+#include <stdio.h>\r
+\r
+/* TYPES *********************************************************************/\r
+\r
+typedef struct _BOUND_FORWARDER_REFS\r
+{\r
+ struct _BOUND_FORWARDER_REFS *Next;\r
+ ULONG TimeDateStamp;\r
+ LPSTR ModuleName;\r
+} BOUND_FORWARDER_REFS, *PBOUND_FORWARDER_REFS;\r
+\r
+typedef struct _IMPORT_DESCRIPTOR\r
+{\r
+ struct _IMPORT_DESCRIPTOR *Next;\r
+ LPSTR ModuleName;\r
+ ULONG TimeDateStamp;\r
+ USHORT ForwaderReferences;\r
+ PBOUND_FORWARDER_REFS Forwarders;\r
+} IMPORT_DESCRIPTOR, *PIMPORT_DESCRIPTOR;\r
+\r
+/* DATA **********************************************************************/\r
+\r
+extern HANDLE IMAGEHLP_hHeap;\r
+\r
+/* FUNCTIONS *****************************************************************/\r
+\r
+BOOL\r
+IMAGEAPI\r
+UnloadAllImages(VOID);\r
+\r
+/* EOF */\r
+++ /dev/null
-/*
- * IMAGEHLP library
- *
- * Copyright 1998 Patrik Stridvall
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <stdarg.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "winerror.h"
-#include "wine/debug.h"
-#include "imagehlp.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
-
-/***********************************************************************
- * SymCleanup (IMAGEHLP.@)
- */
-BOOL WINAPI SymCleanup(HANDLE hProcess)
-{
- FIXME("(%p): stub\n", hProcess);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-/***********************************************************************
- * SymEnumerateModules (IMAGEHLP.@)
- */
-
-BOOL WINAPI SymEnumerateModules(
- HANDLE hProcess, PSYM_ENUMMODULES_CALLBACK EnumModulesCallback,
- PVOID UserContext)
-{
- FIXME("(%p, %p, %p): stub\n",
- hProcess, EnumModulesCallback, UserContext
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-/***********************************************************************
- * SymEnumerateSymbols (IMAGEHLP.@)
- */
-BOOL WINAPI SymEnumerateSymbols(
- HANDLE hProcess, DWORD BaseOfDll,
- PSYM_ENUMSYMBOLS_CALLBACK EnumSymbolsCallback, PVOID UserContext)
-{
- FIXME("(%p, 0x%08lx, %p, %p): stub\n",
- hProcess, BaseOfDll, EnumSymbolsCallback, UserContext
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-/***********************************************************************
- * SymFunctionTableAccess (IMAGEHLP.@)
- */
-PVOID WINAPI SymFunctionTableAccess(HANDLE hProcess, DWORD AddrBase)
-{
- FIXME("(%p, 0x%08lx): stub\n", hProcess, AddrBase);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-/***********************************************************************
- * SymGetModuleBase (IMAGEHLP.@)
- */
-DWORD WINAPI SymGetModuleBase(HANDLE hProcess, DWORD dwAddr)
-{
- FIXME("(%p, 0x%08lx): stub\n", hProcess, dwAddr);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
-}
-
-/***********************************************************************
- * SymGetModuleInfo (IMAGEHLP.@)
- */
-BOOL WINAPI SymGetModuleInfo(
- HANDLE hProcess, DWORD dwAddr,
- PIMAGEHLP_MODULE ModuleInfo)
-{
- MEMORY_BASIC_INFORMATION mbi;
-
- FIXME("(%p, 0x%08lx, %p): hacked stub\n",
- hProcess, dwAddr, ModuleInfo
- );
-
- /*
- * OpenOffice uses this function to get paths of it's modules
- * from address inside the module. So return at least that for
- * now.
- */
- if (VirtualQuery((PVOID)dwAddr, &mbi, sizeof(mbi)) != sizeof(mbi) ||
- !GetModuleFileNameA((HMODULE)mbi.AllocationBase, ModuleInfo->ImageName, sizeof(ModuleInfo->ImageName)))
- {
- return FALSE;
- }
- return TRUE;
-}
-
-/***********************************************************************
- * SymGetOptions (IMAGEHLP.@)
- */
-DWORD WINAPI SymGetOptions()
-{
- FIXME("(): stub\n");
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
-}
-
-/***********************************************************************
- * SymGetSearchPath (IMAGEHLP.@)
- */
-BOOL WINAPI SymGetSearchPath(
- HANDLE hProcess, LPSTR szSearchPath, DWORD SearchPathLength)
-{
- FIXME("(%p, %s, %ld): stub\n",
- hProcess, debugstr_an(szSearchPath,SearchPathLength), SearchPathLength
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-/***********************************************************************
- * SymGetSymFromAddr (IMAGEHLP.@)
- */
-BOOL WINAPI SymGetSymFromAddr(
- HANDLE hProcess, DWORD dwAddr,
- PDWORD pdwDisplacement, PIMAGEHLP_SYMBOL Symbol)
-{
- FIXME("(%p, 0x%08lx, %p, %p): stub\n",
- hProcess, dwAddr, pdwDisplacement, Symbol
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-/***********************************************************************
- * SymGetSymFromName (IMAGEHLP.@)
- */
-BOOL WINAPI SymGetSymFromName(
- HANDLE hProcess, LPSTR Name, PIMAGEHLP_SYMBOL Symbol)
-{
- FIXME("(%p, %s, %p): stub\n", hProcess, Name, Symbol);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-/***********************************************************************
- * SymGetSymNext (IMAGEHLP.@)
- */
-BOOL WINAPI SymGetSymNext(
- HANDLE hProcess, PIMAGEHLP_SYMBOL Symbol)
-{
- FIXME("(%p, %p): stub\n", hProcess, Symbol);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-/***********************************************************************
- * SymGetSymPrev (IMAGEHLP.@)
- */
-
-BOOL WINAPI SymGetSymPrev(
- HANDLE hProcess, PIMAGEHLP_SYMBOL Symbol)
-{
- FIXME("(%p, %p): stub\n", hProcess, Symbol);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-/***********************************************************************
- * SymInitialize (IMAGEHLP.@)
- */
-BOOL WINAPI SymInitialize(
- HANDLE hProcess, LPSTR UserSearchPath, BOOL fInvadeProcess)
-{
- FIXME("(%p, %s, %d): stub\n",
- hProcess, debugstr_a(UserSearchPath), fInvadeProcess
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-/***********************************************************************
- * SymLoadModule (IMAGEHLP.@)
- */
-
-BOOL WINAPI SymLoadModule(
- HANDLE hProcess, HANDLE hFile, LPSTR ImageName, LPSTR ModuleName,
- DWORD BaseOfDll, DWORD SizeOfDll)
-{
- FIXME("(%p, %p, %s, %s, %ld, %ld): stub\n",
- hProcess, hFile, debugstr_a(ImageName), debugstr_a(ModuleName),
- BaseOfDll, SizeOfDll
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-/***********************************************************************
- * SymRegisterCallback (IMAGEHLP.@)
- */
-BOOL WINAPI SymRegisterCallback(
- HANDLE hProcess, PSYMBOL_REGISTERED_CALLBACK CallbackFunction,
- PVOID UserContext)
-{
- FIXME("(%p, %p, %p): stub\n",
- hProcess, CallbackFunction, UserContext
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-/***********************************************************************
- * SymSetOptions (IMAGEHLP.@)
- */
-DWORD WINAPI SymSetOptions(DWORD SymOptions)
-{
- FIXME("(0x%08lx): stub\n", SymOptions);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
-}
-
-/***********************************************************************
- * SymSetSearchPath (IMAGEHLP.@)
- */
-BOOL WINAPI SymSetSearchPath(HANDLE hProcess, LPSTR szSearchPath)
-{
- FIXME("(%p, %s): stub\n",
- hProcess, debugstr_a(szSearchPath)
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-/***********************************************************************
- * SymUnDName (IMAGEHLP.@)
- */
-BOOL WINAPI SymUnDName(
- PIMAGEHLP_SYMBOL sym, LPSTR UnDecName, DWORD UnDecNameLength)
-{
- FIXME("(%p, %s, %ld): stub\n",
- sym, UnDecName, UnDecNameLength
- );
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
-
-/***********************************************************************
- * SymUnloadModule (IMAGEHLP.@)
- */
-BOOL WINAPI SymUnloadModule(
- HANDLE hProcess, DWORD BaseOfDll)
-{
- FIXME("(%p, 0x%08lx): stub\n", hProcess, BaseOfDll);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
-}
+++ /dev/null
-
-Index: dlls/imagehlp/access.c
-===================================================================
-RCS file: /home/wine/wine/dlls/imagehlp/access.c,v
-retrieving revision 1.20
-diff -u -r1.20 access.c
---- dlls/imagehlp/access.c 5 Apr 2004 22:50:45 -0000 1.20
-+++ dlls/imagehlp/access.c 29 Sep 2004 17:17:35 -0000
-@@ -54,6 +54,8 @@
- };
-
- extern HANDLE IMAGEHLP_hHeap;
-+BOOLEAN DllListInitialized;
-+LIST_ENTRY ImageLoadListHead;
-
- /***********************************************************************
- * GetImageConfigInformation (IMAGEHLP.@)
-@@ -76,11 +78,45 @@
- PLOADED_IMAGE LoadedImage,
- LPDWORD SizeUnusedHeaderBytes)
- {
-- FIXME("(%p, %p): stub\n",
-- LoadedImage, SizeUnusedHeaderBytes
-- );
-- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-- return 0;
-+ DWORD FirstFreeByte;
-+ PIMAGE_OPTIONAL_HEADER OptionalHeader32 = NULL;
-+ PIMAGE_NT_HEADERS NtHeaders;
-+ ULONG i;
-+
-+ /* Read the NT Headers */
-+ NtHeaders = LoadedImage->FileHeader;
-+
-+ /* Find the first free byte, which is after all the headers and sections */
-+ FirstFreeByte = (ULONG_PTR)NtHeaders - (ULONG_PTR)LoadedImage->MappedAddress +
-+ FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader) +
-+ NtHeaders->FileHeader.SizeOfOptionalHeader +
-+ NtHeaders->FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
-+
-+ /* Get the Optional Header */
-+ OptionalHeader32 = &LoadedImage->FileHeader->OptionalHeader;
-+
-+ /* There is the possibilty that one of the Data Directories is in the PE Header
-+ itself, so we'll need to find such a case and add it to our PE used space */
-+ for ( i = 0; i<OptionalHeader32->NumberOfRvaAndSizes; i++ ) {
-+
-+ /* If the VA is less then the size of headers, then the data is inside the PE header */
-+ if (OptionalHeader32->DataDirectory[i].VirtualAddress < OptionalHeader32->SizeOfHeaders) {
-+
-+ /* However, make sure it's not 0, which means it doesnt actually exist */
-+ if (OptionalHeader32->DataDirectory[i].VirtualAddress >= FirstFreeByte) {
-+
-+ /* Our first empty byte is after this Directory Data then */
-+ FirstFreeByte = OptionalHeader32->DataDirectory[i].VirtualAddress +
-+ OptionalHeader32->DataDirectory[i].Size;
-+ }
-+ }
-+ }
-+
-+ /* Return the unused Header Bytes */
-+ *SizeUnusedHeaderBytes = OptionalHeader32->SizeOfHeaders - FirstFreeByte;
-+
-+ /* And return the first free byte*/
-+ return FirstFreeByte;
- }
-
- /***********************************************************************
-@@ -88,15 +124,58 @@
- */
- PLOADED_IMAGE WINAPI ImageLoad(LPSTR DllName, LPSTR DllPath)
- {
-- PLOADED_IMAGE pLoadedImage;
-+ PLIST_ENTRY Head,Next;
-+ PLOADED_IMAGE LoadedImage;
-+
-+ /* Initialize the List Head */
-+ if (!DllListInitialized) {
-+ InitializeListHead(&ImageLoadListHead);
-+ DllListInitialized = TRUE;
-+ }
-+
-+ /* Move to the Next DLL */
-+ Head = &ImageLoadListHead;
-+ Next = Head->Flink;
-+
-+ TRACE("Trying to find library: %s in current ListHead \n", DllName);
-+
-+ /* Check if we already Loaded it */
-+ while (Next != Head) {
-+
-+ /* Get the Loaded Image Structure */
-+ LoadedImage = CONTAINING_RECORD(Next, LOADED_IMAGE, Links);
-+ TRACE("Found: %s in current ListHead \n", LoadedImage->ModuleName);
-+
-+ /* Check if the Names Match */
-+ if (!lstrcmpiA( DllName, LoadedImage->ModuleName )) {
-+ TRACE("Found: %s\n the names match",DllName);
-+ return LoadedImage;
-+ }
-+
-+ /* Move to next Entry */
-+ Next = Next->Flink;
-+ TRACE("Moving to next List Entry\n");
-+ }
-+
-+ /* Allocate memory for the Structure, and write the Module Name under */
-+ LoadedImage = HeapAlloc(IMAGEHLP_hHeap, 0, sizeof(*LoadedImage) + lstrlenA(DllName) + 1);
-
-- FIXME("(%s, %s): stub\n", DllName, DllPath);
-+ /* Module Name will be after structure */
-+ LoadedImage->ModuleName = (LPSTR)LoadedImage + 1;
-
-- pLoadedImage = HeapAlloc(IMAGEHLP_hHeap, 0, sizeof(LOADED_IMAGE));
-- if (pLoadedImage)
-- pLoadedImage->FileHeader = HeapAlloc(IMAGEHLP_hHeap, 0, sizeof(IMAGE_NT_HEADERS));
-+ /* Copy the Moduel Name */
-+ lstrcpyA(LoadedImage->ModuleName, DllName);
-
-- return pLoadedImage;
-+ /* Now Load it and add it to our list*/
-+ if (MapAndLoad(DllName, DllPath, LoadedImage, TRUE, TRUE)) {
-+ InsertTailList(&ImageLoadListHead, &LoadedImage->Links);
-+ return LoadedImage;
-+ }
-+
-+ /* If we're here...there's been a failure */
-+ HeapFree(IMAGEHLP_hHeap, 0, LoadedImage);
-+ LoadedImage = NULL;
-+ return LoadedImage;
- }
-
- /***********************************************************************
-@@ -149,40 +228,62 @@
- LPSTR pszImageName, LPSTR pszDllPath, PLOADED_IMAGE pLoadedImage,
- BOOL bDotDll, BOOL bReadOnly)
- {
-- CHAR szFileName[MAX_PATH];
-- HANDLE hFile = NULL;
- HANDLE hFileMapping = NULL;
-- HMODULE hModule = NULL;
-- PIMAGE_NT_HEADERS pNtHeader = NULL;
-+ PIMAGE_NT_HEADERS NtHeader = NULL;
-+ ULONG Tried = 0;
-+ UCHAR Buffer[MAX_PATH];
-+ LPSTR FilePart;
-+ LPSTR FileToOpen;
-+
-
-- TRACE("(%s, %s, %p, %d, %d)\n", pszImageName, pszDllPath, pLoadedImage,
-- bDotDll, bReadOnly);
-+ /* So we can add the DLL Path later */
-+ FileToOpen = pszImageName;
-
-- /* PathCombine(&szFileName, pszDllPath, pszImageName); */
-- /* PathRenameExtension(&szFileName, bDotDll?:"dll":"exe"); */
-
-- /* FIXME: Check if the file already loaded (use IMAGEHLP_pFirstLoadedImage) */
-- if(!(hFile = CreateFileA(
-- szFileName, GENERIC_READ, 1, /* FIXME: FILE_SHARE_READ not defined */
-- NULL, OPEN_EXISTING, 0, NULL)))
-+TryAgain:
-+ /* Get a handle to the file */
-+ if ((pLoadedImage->hFile = CreateFileA (FileToOpen,
-+ bReadOnly ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
-+ bReadOnly ? FILE_SHARE_READ : FILE_SHARE_READ | FILE_SHARE_WRITE,
-+ NULL,
-+ OPEN_EXISTING,
-+ 0,
-+ NULL)) == INVALID_HANDLE_VALUE)
- {
-- SetLastError(ERROR_FILE_NOT_FOUND);
-- goto Error;
-+
-+ /* It Failed, use the DLL Search Path then (make sure we haven't already) */
-+ if (!Tried) {
-+ Tried = SearchPathA(pszDllPath, pszImageName, bDotDll ? ".dll" : ".exe", MAX_PATH, Buffer, &FilePart);
-+ if (Tried) {
-+ FileToOpen = Buffer;
-+ goto TryAgain;
-+ }
-+ }
-+ /* Fail */
-+ return FALSE;
- }
-
-- if(!(hFileMapping = CreateFileMappingA(
-- hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL)))
-+
-+ /* Create the File Mapping */
-+ if (!(hFileMapping = CreateFileMappingA (pLoadedImage->hFile,
-+ NULL,
-+ bReadOnly ? PAGE_READONLY : PAGE_READWRITE,
-+ 0,
-+ 0,
-+ NULL)))
- {
- DWORD dwLastError = GetLastError();
- WARN("CreateFileMapping: Error = %ld\n", dwLastError);
- SetLastError(dwLastError);
- goto Error;
- }
-- CloseHandle(hFile);
-- hFile = NULL;
-
-- if(!(hModule = (HMODULE) MapViewOfFile(
-- hFileMapping, FILE_MAP_READ, 0, 0, 0)))
-+ /* Get a pointer to the file */
-+ if(!(pLoadedImage->MappedAddress = MapViewOfFile(hFileMapping,
-+ bReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE,
-+ 0,
-+ 0,
-+ 0)))
- {
- DWORD dwLastError = GetLastError();
- WARN("MapViewOfFile: Error = %ld\n", dwLastError);
-@@ -190,52 +291,43 @@
- goto Error;
- }
-
-+
-+ /* Close the handle to the map, we don't need it anymore */
- CloseHandle(hFileMapping);
- hFileMapping=NULL;
-
-- pLoadedImage = (PLOADED_IMAGE) HeapAlloc(
-- IMAGEHLP_hHeap, 0, sizeof(LOADED_IMAGE)
-- );
-+ /* Get the Nt Header */
-+ NtHeader = ImageNtHeader(pLoadedImage->MappedAddress);
-
-- pNtHeader = RtlImageNtHeader(hModule);
--
-- pLoadedImage->ModuleName = HeapAlloc(IMAGEHLP_hHeap, 0, strlen(pszDllPath)+1); /* FIXME: Correct? */
-- strcpy( pLoadedImage->ModuleName, pszDllPath );
-- pLoadedImage->hFile = hFile;
-- pLoadedImage->MappedAddress = (PUCHAR) hModule;
-- pLoadedImage->FileHeader = pNtHeader;
-+ /* Write data */
-+ pLoadedImage->ModuleName = HeapAlloc(IMAGEHLP_hHeap, 0, lstrlenA(pszImageName) + 1);
-+ lstrcpyA(pLoadedImage->ModuleName, pszImageName);
-+ pLoadedImage->FileHeader = NtHeader;
- pLoadedImage->Sections = (PIMAGE_SECTION_HEADER)
-- ((LPBYTE) &pNtHeader->OptionalHeader +
-- pNtHeader->FileHeader.SizeOfOptionalHeader);
-- pLoadedImage->NumberOfSections =
-- pNtHeader->FileHeader.NumberOfSections;
-- pLoadedImage->SizeOfImage =
-- pNtHeader->OptionalHeader.SizeOfImage;
-- pLoadedImage->Characteristics =
-- pNtHeader->FileHeader.Characteristics;
-+ ((LPBYTE)&NtHeader->OptionalHeader +
-+ NtHeader->FileHeader.SizeOfOptionalHeader);
-+ pLoadedImage->NumberOfSections = NtHeader->FileHeader.NumberOfSections;
-+ pLoadedImage->SizeOfImage = NtHeader->OptionalHeader.SizeOfImage;
-+ pLoadedImage->Characteristics = NtHeader->FileHeader.Characteristics;
- pLoadedImage->LastRvaSection = pLoadedImage->Sections;
--
- pLoadedImage->fSystemImage = FALSE; /* FIXME */
- pLoadedImage->fDOSImage = FALSE; /* FIXME */
-
-- /* FIXME: Make thread safe */
-- pLoadedImage->Links.Flink = NULL;
-- pLoadedImage->Links.Blink = &IMAGEHLP_pLastLoadedImage->Links;
-- if(IMAGEHLP_pLastLoadedImage)
-- IMAGEHLP_pLastLoadedImage->Links.Flink = &pLoadedImage->Links;
-- IMAGEHLP_pLastLoadedImage = pLoadedImage;
-- if(!IMAGEHLP_pFirstLoadedImage)
-- IMAGEHLP_pFirstLoadedImage = pLoadedImage;
-
-+ /* Read only, so no sense in keeping the handle alive */
-+ if (bReadOnly) CloseHandle(pLoadedImage->hFile);
-+
-+
-+ /* Return Success */
- return TRUE;
-
- Error:
-- if(hModule)
-- UnmapViewOfFile((PVOID) hModule);
-+ if(pLoadedImage->MappedAddress)
-+ UnmapViewOfFile(pLoadedImage->MappedAddress);
- if(hFileMapping)
- CloseHandle(hFileMapping);
-- if(hFile)
-- CloseHandle(hFile);
-+ if(pLoadedImage->hFile)
-+ CloseHandle(pLoadedImage->hFile);
- return FALSE;
- }
-
-Index: dlls/imagehlp/modify.c
-===================================================================
-RCS file: /home/wine/wine/dlls/imagehlp/modify.c,v
-retrieving revision 1.13
-diff -u -r1.13 modify.c
---- dlls/imagehlp/modify.c 21 Nov 2003 21:31:35 -0000 1.13
-+++ dlls/imagehlp/modify.c 29 Sep 2004 17:17:37 -0000
-@@ -30,8 +30,669 @@
-
- WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
-
-+/* Internal Structures we use to keep track of the Bound Imports */
-+typedef struct _BOUND_FORWARDER_REFS {
-+ ULONG TimeDateStamp;
-+ LPSTR ModuleName;
-+} BOUND_FORWARDER_REFS, *PBOUND_FORWARDER_REFS;
-+
-+typedef struct _BOUND_IMPORT_DESCRIPTOR {
-+ LPSTR ModuleName;
-+ ULONG TimeDateStamp;
-+ USHORT ForwaderReferences;
-+ PBOUND_FORWARDER_REFS Forwarders;
-+} BOUND_IMPORT_DESCRIPTOR, *PBOUND_IMPORT_DESCRIPTOR;
-+
-+UCHAR BoundLibraries[4096];
-+LPSTR BoundLibrariesPointer = BoundLibraries;
-+PULONG BoundImportDescriptors;
-+
- static WORD CalcCheckSum(DWORD StartValue, LPVOID BaseAddress, DWORD WordCount);
-
-+/*
-+ * BindpCreateBoundImportDescriptor
-+ *
-+ * FUNCTION:
-+ * Creates an Internal Structure for the Bound Library
-+ *
-+ * ARGUMENTS:
-+ * LibraryName - Name of the Library
-+ * Library - Loaded Library
-+ * BoundImportDescriptor - Internal Bound Import Descriptor of Library
-+ *
-+ * RETURNS:
-+ * PBOUND_IMPORT_DESCRIPTOR - Pointer to the Internal Bind Structure
-+ */
-+PBOUND_IMPORT_DESCRIPTOR
-+WINAPI
-+BindpCreateBoundImportDescriptor(
-+ LPSTR LibraryName,
-+ PLOADED_IMAGE Library,
-+ PULONG BoundImportDescriptor
-+ )
-+{
-+ PBOUND_IMPORT_DESCRIPTOR CurrentBoundImportDescriptor;
-+
-+ /* Load the First Descriptor */
-+ CurrentBoundImportDescriptor = (PBOUND_IMPORT_DESCRIPTOR)BoundImportDescriptor;
-+
-+ /* Check if we've already bound this library */
-+ while (CurrentBoundImportDescriptor->ModuleName) {
-+ if (!lstrcmpiA(CurrentBoundImportDescriptor->ModuleName, LibraryName)) {
-+ return CurrentBoundImportDescriptor;
-+ }
-+ CurrentBoundImportDescriptor++;
-+ }
-+
-+ /* Save Library Name in Bound Libraries Buffer */
-+ strcat((char *)BoundLibrariesPointer, LibraryName);
-+
-+ /* Set Data */
-+ CurrentBoundImportDescriptor->ModuleName = BoundLibrariesPointer;
-+ CurrentBoundImportDescriptor->TimeDateStamp = Library->FileHeader->FileHeader.TimeDateStamp;
-+
-+ /* Support for up to 32 Forwarded DLLs */
-+ CurrentBoundImportDescriptor->Forwarders = GlobalAlloc(GMEM_ZEROINIT, 32* sizeof(BOUND_FORWARDER_REFS));
-+
-+ /* Next String */
-+ BoundLibrariesPointer = BoundLibrariesPointer + strlen((char *)BoundLibrariesPointer) + 1;
-+
-+ return CurrentBoundImportDescriptor;
-+}
-+
-+/*
-+ * BindpAddBoundForwarder
-+ *
-+ * FUNCTION:
-+ * Finds the pointer of the Forwarded function, and writes it into the Thunk,
-+ * thus making the Thunk Bound.
-+ *
-+ * ARGUMENTS:
-+ * BoundImportDescriptor - Internal Bound Import Descriptor of LoadedLibrary
-+ * DllPath - DLL Search Path
-+ * ForwarderString - Name of the Forwader String
-+ *
-+ * RETURNS:
-+ * Pointer to the Forwaded Function.
-+ */
-+ULONG
-+WINAPI
-+BindpAddBoundForwarder(
-+ PBOUND_IMPORT_DESCRIPTOR BoundImportDescriptor,
-+ LPSTR DllPath,
-+ PUCHAR ForwarderString
-+ )
-+{
-+ CHAR DllName[256];
-+ PUCHAR TempDllName;
-+ PLOADED_IMAGE LoadedLibrary;
-+ ULONG DllNameSize;
-+ USHORT OrdinalNumber = 0;
-+ USHORT HintIndex;
-+ ULONG ExportSize;
-+ PIMAGE_EXPORT_DIRECTORY Exports;
-+ ULONG ExportsBase;
-+ PULONG AddressOfNames;
-+ PUSHORT AddressOfOrdinals;
-+ PULONG AddressOfPointers;
-+ LPSTR ExportName;
-+ ULONG ForwardedAddress;
-+ PBOUND_FORWARDER_REFS BoundForwarder;
-+ PIMAGE_OPTIONAL_HEADER OptionalHeader32 = NULL;
-+
-+NextForwarder:
-+
-+ /* Get the DLL Name */
-+ TempDllName = ForwarderString;
-+ while (*TempDllName && *TempDllName != '.') TempDllName++;
-+ DllNameSize = (ULONG) (TempDllName - ForwarderString);
-+ lstrcpynA(DllName, ForwarderString, DllNameSize + 1);
-+
-+ /* Append .DLL extension */
-+ DllName[DllNameSize] = '\0';
-+ strcat(DllName, ".DLL" );
-+
-+ /* Load it */
-+ TRACE("Loading the Thunk Library: %s \n", DllName);
-+ LoadedLibrary = ImageLoad(DllName, DllPath);
-+ TempDllName += 1;
-+
-+ /* Return whatever we got back in case of failure*/
-+ if (!LoadedLibrary) return (ULONG)ForwarderString;
-+ TRACE("It Loaded at: %p \n", LoadedLibrary->MappedAddress);
-+
-+ /* Load Exports */
-+ Exports = RtlImageDirectoryEntryToData((HMODULE)LoadedLibrary->MappedAddress, FALSE, IMAGE_DIRECTORY_ENTRY_EXPORT, &ExportSize);
-+
-+ /* Get the Pointers to the Tables */
-+ AddressOfNames = ImageRvaToVa (LoadedLibrary->FileHeader,
-+ LoadedLibrary->MappedAddress,
-+ Exports->AddressOfNames,
-+ &LoadedLibrary->LastRvaSection);
-+ AddressOfOrdinals = ImageRvaToVa (LoadedLibrary->FileHeader,
-+ LoadedLibrary->MappedAddress,
-+ Exports->AddressOfNameOrdinals,
-+ &LoadedLibrary->LastRvaSection);
-+ AddressOfPointers = ImageRvaToVa (LoadedLibrary->FileHeader,
-+ LoadedLibrary->MappedAddress,
-+ Exports->AddressOfFunctions,
-+ &LoadedLibrary->LastRvaSection);
-+
-+ /* Get the Optional Header */
-+ OptionalHeader32 = &LoadedLibrary->FileHeader->OptionalHeader;
-+
-+ /* Get the Ordinal Number */
-+ for (HintIndex = 0; HintIndex < Exports->NumberOfNames; HintIndex++) {
-+
-+ /* Get the Export Name */
-+ ExportName = ImageRvaToVa (LoadedLibrary->FileHeader,
-+ LoadedLibrary->MappedAddress,
-+ AddressOfNames[HintIndex],
-+ &LoadedLibrary->LastRvaSection);
-+
-+ /* Check if it matches */
-+ if (!strcmp(TempDllName, ExportName)) {
-+ OrdinalNumber = AddressOfOrdinals[HintIndex];
-+ break;
-+ }
-+ }
-+
-+ do {
-+ /* Get the Forwarded Address */
-+ ForwardedAddress = AddressOfPointers[OrdinalNumber] + OptionalHeader32->ImageBase;
-+
-+ /* Load the First Bound Forward Structure */
-+ BoundForwarder = BoundImportDescriptor->Forwarders;
-+
-+ /* Check if we already have the Module Name written */
-+ while (BoundForwarder->ModuleName) {
-+ if (!lstrcmpiA(DllName, BoundForwarder->ModuleName)) break;
-+ BoundForwarder++;
-+ }
-+
-+ if (!BoundForwarder->ModuleName) {
-+
-+ /* Save Library Name in Bound Libraries Buffer */
-+ strcat((char *)BoundLibrariesPointer, DllName);
-+
-+ /* Set Data */
-+ BoundForwarder->ModuleName = BoundLibrariesPointer;
-+ BoundForwarder->TimeDateStamp = LoadedLibrary->FileHeader->FileHeader.TimeDateStamp;
-+
-+ /* Next String */
-+ BoundLibrariesPointer = BoundLibrariesPointer + strlen((char *)BoundLibrariesPointer) + 1;
-+ BoundImportDescriptor->ForwaderReferences += 1;
-+ }
-+
-+ /* Load DLL's Exports */
-+ ExportsBase = (ULONG)RtlImageDirectoryEntryToData ((HMODULE)LoadedLibrary->MappedAddress,
-+ TRUE,
-+ IMAGE_DIRECTORY_ENTRY_EXPORT,
-+ &ExportSize) -
-+ (ULONG_PTR)LoadedLibrary->MappedAddress;
-+ ExportsBase += OptionalHeader32->ImageBase;
-+
-+ TRACE("I've thunked it\n");
-+
-+ /* Is this yet another Forward? */
-+ if (ForwardedAddress > ExportsBase && ForwardedAddress < (ExportsBase + ExportSize)) {
-+ ForwarderString = ImageRvaToVa (LoadedLibrary->FileHeader,
-+ LoadedLibrary->MappedAddress,
-+ AddressOfPointers[OrdinalNumber],
-+ &LoadedLibrary->LastRvaSection);
-+ goto NextForwarder;
-+ }
-+ }
-+ while (0);
-+ return ForwardedAddress;
-+}
-+
-+/*
-+ * BindpBindThunk
-+ *
-+ * FUNCTION:
-+ * Finds the pointer of the Imported function, and writes it into the Thunk,
-+ * thus making the Thunk Bound.
-+ *
-+ * ARGUMENTS:
-+ * Thunk - Current Thunk in Unbound File
-+ * File - File containing the Thunk
-+ * BoundThunk - Pointer to the corresponding Bound Thunk
-+ * LoadedLibrary - Library containing the Exported Function
-+ * Exports - Export Directory of LoadedLibrary
-+ * BoundImportDescriptor - Internal Bound Import Descriptor of LoadedLibrary
-+ * DllPath - DLL Search Path
-+ *
-+ * RETURNS:
-+ * TRUE if Suceeded
-+ */
-+BOOL
-+WINAPI
-+BindpBindThunk(
-+ PIMAGE_THUNK_DATA Thunk,
-+ PLOADED_IMAGE File,
-+ PIMAGE_THUNK_DATA BoundThunk,
-+ PLOADED_IMAGE LoadedLibrary,
-+ PIMAGE_EXPORT_DIRECTORY Exports,
-+ PBOUND_IMPORT_DESCRIPTOR BoundImportDescriptor,
-+ LPSTR DllPath
-+ )
-+{
-+ PULONG AddressOfNames;
-+ PUSHORT AddressOfOrdinals;
-+ PULONG AddressOfPointers;
-+ PIMAGE_IMPORT_BY_NAME ImportName;
-+ ULONG OrdinalNumber = 0;
-+ USHORT HintIndex;
-+ LPSTR ExportName;
-+ ULONG ExportsBase;
-+ ULONG ExportSize;
-+ UCHAR NameBuffer[32];
-+ PIMAGE_OPTIONAL_HEADER OptionalHeader32 = NULL;
-+ PIMAGE_OPTIONAL_HEADER LibraryOptionalHeader32 = NULL;
-+
-+ /* Get the Pointers to the Tables */
-+ AddressOfNames = ImageRvaToVa (LoadedLibrary->FileHeader,
-+ LoadedLibrary->MappedAddress,
-+ Exports->AddressOfNames,
-+ &LoadedLibrary->LastRvaSection);
-+ AddressOfOrdinals = ImageRvaToVa (LoadedLibrary->FileHeader,
-+ LoadedLibrary->MappedAddress,
-+ Exports->AddressOfNameOrdinals,
-+ &LoadedLibrary->LastRvaSection);
-+ AddressOfPointers = ImageRvaToVa (LoadedLibrary->FileHeader,
-+ LoadedLibrary->MappedAddress,
-+ Exports->AddressOfFunctions,
-+ &LoadedLibrary->LastRvaSection);
-+
-+ TRACE("Binding a Thunk\n");
-+
-+ /* Get the Optional Header */
-+ OptionalHeader32 = &File->FileHeader->OptionalHeader;
-+ LibraryOptionalHeader32 = &LoadedLibrary->FileHeader->OptionalHeader;
-+
-+ /* Import by Ordinal */
-+ if (IMAGE_SNAP_BY_ORDINAL(Thunk->u1.Ordinal) == TRUE) {
-+ OrdinalNumber = (IMAGE_ORDINAL(Thunk->u1.Ordinal) - Exports->Base);
-+ ImportName = (PIMAGE_IMPORT_BY_NAME)NameBuffer;
-+ } else {
-+
-+ /* Import by Name */
-+ ImportName = ImageRvaToVa (File->FileHeader,
-+ File->MappedAddress,
-+ (ULONG)Thunk->u1.AddressOfData,
-+ &File->LastRvaSection);
-+
-+ for (HintIndex = 0; HintIndex < Exports->NumberOfNames; HintIndex++) {
-+
-+ /* Get the Export Name */
-+ ExportName = ImageRvaToVa (LoadedLibrary->FileHeader,
-+ LoadedLibrary->MappedAddress,
-+ (ULONG)AddressOfNames[HintIndex],
-+ &LoadedLibrary->LastRvaSection);
-+
-+ /* Check if it's the one we want */
-+ if (!strcmp(ImportName->Name, ExportName)) {
-+ OrdinalNumber = AddressOfOrdinals[HintIndex];
-+ break;
-+ }
-+ }
-+ }
-+
-+ /* Fail if we still didn't find anything */
-+ if (!OrdinalNumber) return FALSE;
-+
-+ /* Write the Pointer */
-+ (ULONG)BoundThunk->u1.Function = AddressOfPointers[OrdinalNumber] + LibraryOptionalHeader32->ImageBase;
-+
-+ /* Load DLL's Exports */
-+ ExportsBase = (ULONG)RtlImageDirectoryEntryToData ((HMODULE)LoadedLibrary->MappedAddress,
-+ TRUE,
-+ IMAGE_DIRECTORY_ENTRY_EXPORT,
-+ &ExportSize) -
-+ (ULONG_PTR)LoadedLibrary->MappedAddress;
-+ /* RVA to VA */
-+ ExportsBase += LibraryOptionalHeader32->ImageBase;
-+
-+ /* Check if the Export is forwarded (meaning that it's pointer is inside the Export Table) */
-+ if ((ULONG)BoundThunk->u1.Function > ExportsBase && (ULONG)BoundThunk->u1.Function < (ExportsBase + ExportSize)) {
-+
-+ TRACE("This Thunk is a forward...calling forward thunk bounder\n");
-+
-+ /* Replace the Forwarder String by the actual Pointer */
-+ (ULONG)BoundThunk->u1.Function = BindpAddBoundForwarder (BoundImportDescriptor,
-+ DllPath,
-+ ImageRvaToVa (LoadedLibrary->FileHeader,
-+ LoadedLibrary->MappedAddress,
-+ AddressOfPointers[OrdinalNumber],
-+ &LoadedLibrary->LastRvaSection));
-+
-+ }
-+
-+ /* Return Success */
-+ return TRUE;
-+}
-+
-+/*
-+ * BindpCreateBoundImportSection
-+ *
-+ * FUNCTION:
-+ * Creates a 32-bit PE Bound Import Table
-+ *
-+ * ARGUMENTS:
-+ * BoundImportDescriptor - Pointer to the Bound Import Table
-+ * BoundImportsSize - Size of the Bound Import Table
-+ *
-+ * RETURNS:
-+ * PIMAGE_BOUND_IMPORT_DESCRIPTOR - The Bound Import Table
-+ */
-+PIMAGE_BOUND_IMPORT_DESCRIPTOR
-+WINAPI
-+BindpCreateBoundImportSection(
-+ PULONG BoundImportDescriptor,
-+ PULONG BoundImportsSize
-+ )
-+{
-+ ULONG BoundLibraryNamesSize, BoundImportTableSize;
-+ PBOUND_FORWARDER_REFS BoundForwarder;
-+ PBOUND_IMPORT_DESCRIPTOR CurrentBoundImportDescriptor;
-+ PVOID BoundLibraryNames;
-+ PIMAGE_BOUND_IMPORT_DESCRIPTOR CurrentBoundImportTableEntry, BoundImportTable;
-+ PIMAGE_BOUND_FORWARDER_REF NewForwarder;
-+
-+ /* Zero the Sizes */
-+ *BoundImportsSize = 0;
-+ BoundLibraryNamesSize = 0;
-+ BoundImportTableSize = 0;
-+
-+ /* Start with the first Internal Descriptor */
-+ CurrentBoundImportDescriptor = (PBOUND_IMPORT_DESCRIPTOR)BoundImportDescriptor;
-+
-+ /* Loop through every Descriptor we loaded */
-+ while (CurrentBoundImportDescriptor->ModuleName) {
-+
-+ /* Add to the size of the Bound Import Table */
-+ BoundImportTableSize += sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR);
-+
-+ /* Check Forwarders */
-+ BoundForwarder = CurrentBoundImportDescriptor->Forwarders;
-+ while (BoundForwarder->ModuleName) {
-+
-+ /* Add to size of Bound Import Table */
-+ BoundImportTableSize += sizeof(IMAGE_BOUND_FORWARDER_REF);
-+
-+ /* Next Forwarder */
-+ BoundForwarder++;
-+ }
-+
-+ /* Read Next Internal Descriptor */
-+ CurrentBoundImportDescriptor++;
-+ }
-+
-+ /* Add Terminator for PE Loader*/
-+ BoundImportTableSize += sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR);
-+
-+ /* Name of Libraries Bound in Bound Import Table */
-+ BoundLibraryNamesSize = ((ULONG)BoundLibrariesPointer - (ULONG)(&BoundLibraries));
-+
-+ /* Size of the whole table, dword aligned */
-+ *BoundImportsSize = BoundImportTableSize +
-+ ((BoundLibraryNamesSize + sizeof(ULONG) - 1) & ~(sizeof(ULONG)-1));
-+
-+ /* Allocate it */
-+ BoundImportTable = GlobalAlloc(GMEM_ZEROINIT, *BoundImportsSize);
-+
-+ /* Pointer Library Names inside the Bound Import Table */
-+ BoundLibraryNames = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)((ULONG_PTR)BoundImportTable +
-+ BoundImportTableSize);
-+
-+ /* Copy the Library Names */
-+ RtlCopyMemory(BoundLibraryNames, BoundLibraries, BoundLibraryNamesSize);
-+
-+ /* Go back to first Internal Descriptor and load first entry in the Bound Import Table */
-+ CurrentBoundImportTableEntry = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)BoundImportTable;
-+ CurrentBoundImportDescriptor = (PBOUND_IMPORT_DESCRIPTOR)BoundImportDescriptor;
-+
-+ /* Copy the data from our Internal Structure to the Bound Import Table */
-+ while (CurrentBoundImportDescriptor->ModuleName) {
-+ CurrentBoundImportTableEntry->TimeDateStamp = CurrentBoundImportDescriptor->TimeDateStamp;
-+ CurrentBoundImportTableEntry->OffsetModuleName = (USHORT)(BoundImportTableSize +
-+ (CurrentBoundImportDescriptor->ModuleName -
-+ (LPSTR) BoundLibraries));
-+ CurrentBoundImportTableEntry->NumberOfModuleForwarderRefs = CurrentBoundImportDescriptor->ForwaderReferences;
-+
-+ /* Copy the data from our Forwader Entries to the Bound Import Table */
-+ NewForwarder = (PIMAGE_BOUND_FORWARDER_REF)(CurrentBoundImportTableEntry+1);
-+ BoundForwarder = CurrentBoundImportDescriptor->Forwarders;
-+ while (BoundForwarder->ModuleName) {
-+ NewForwarder->TimeDateStamp =BoundForwarder->TimeDateStamp;
-+ NewForwarder->OffsetModuleName = (USHORT)(BoundImportTableSize +
-+ (BoundForwarder->ModuleName -
-+ (LPSTR) BoundLibraries));
-+ NewForwarder++;
-+ BoundForwarder++;
-+ }
-+
-+ /* Move to next Bound Import Table Entry */
-+ CurrentBoundImportTableEntry = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)NewForwarder;
-+
-+ /* move to next Internal Descriptor */
-+ CurrentBoundImportDescriptor++;
-+ }
-+
-+ /* Now put the pointer back at the beginning and clear the buffer */
-+ RtlZeroMemory(BoundLibraries, 4096);
-+ BoundLibrariesPointer = BoundLibraries;
-+
-+ return BoundImportTable;
-+}
-+
-+/*
-+ * BindpWalkAndBindImports
-+ *
-+ * FUNCTION:
-+ * Does the actual Binding of the Imports and Forward-Referencing
-+ *
-+ * ARGUMENTS:
-+ * File - Name of Imagefile to Bind
-+ * DllPath - Path to search DLL Files in, can be NULL to use Default
-+ *
-+ * RETURNS:
-+ * Nothing
-+ */
-+VOID
-+WINAPI
-+BindpWalkAndBindImports(
-+ PLOADED_IMAGE File,
-+ LPSTR DllPath
-+ )
-+{
-+ PIMAGE_IMPORT_DESCRIPTOR Imports;
-+ PIMAGE_EXPORT_DIRECTORY Exports;
-+ ULONG SizeOfImports;
-+ ULONG SizeOfExports;
-+ ULONG SizeOfThunks;
-+ PIMAGE_OPTIONAL_HEADER OptionalHeader32 = NULL;
-+ PIMAGE_FILE_HEADER FileHeader;
-+ LPSTR ImportedLibrary;
-+ PLOADED_IMAGE LoadedLibrary;
-+ PBOUND_IMPORT_DESCRIPTOR BoundImportDescriptor = NULL;
-+ PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportTable;
-+ PIMAGE_THUNK_DATA Thunks, TempThunk;
-+ PIMAGE_THUNK_DATA BoundThunks, TempBoundThunk;
-+ ULONG ThunkCount = 0;
-+ ULONG Thunk;
-+ ULONG BoundImportTableSize;
-+ ULONG VirtBytesFree, HeaderBytesFree, FirstFreeByte, PhysBytesFree;
-+
-+ TRACE("BindpWalkAndBindImports Called\n");
-+
-+ /* Load the Import Descriptor */
-+ Imports = RtlImageDirectoryEntryToData ((HMODULE)File->MappedAddress,
-+ FALSE,
-+ IMAGE_DIRECTORY_ENTRY_IMPORT,
-+ &SizeOfImports);
-+
-+ /* Read the File Header */
-+ FileHeader = &File->FileHeader->FileHeader;
-+ OptionalHeader32 = &File->FileHeader->OptionalHeader;
-+
-+ /* Support for up to 32 imported DLLs */
-+ BoundImportDescriptors = GlobalAlloc(GMEM_ZEROINIT, 32* sizeof(*BoundImportDescriptor));
-+
-+ TRACE("BoundImportDescriptors Allocated\n");
-+
-+ /* For each Import */
-+ for(; Imports->Name ; Imports++) {
-+
-+ /* Which DLL is being Imported */
-+ ImportedLibrary = ImageRvaToVa (File->FileHeader,
-+ File->MappedAddress,
-+ Imports->Name,
-+ &File->LastRvaSection);
-+
-+ TRACE("Loading Imported DLL: %s \n", ImportedLibrary);
-+
-+ /* Load the DLL */
-+ LoadedLibrary = ImageLoad(ImportedLibrary, DllPath);
-+
-+ TRACE("DLL Loaded at: %p \n", LoadedLibrary->MappedAddress);
-+
-+ /* Now load the Exports */
-+ Exports = RtlImageDirectoryEntryToData ((HMODULE)LoadedLibrary->MappedAddress,
-+ FALSE,
-+ IMAGE_DIRECTORY_ENTRY_EXPORT,
-+ &SizeOfExports);
-+
-+ /* And load the Thunks */
-+ Thunks = ImageRvaToVa (File->FileHeader,
-+ File->MappedAddress,
-+ (ULONG)Imports->u.OriginalFirstThunk,
-+ &File->LastRvaSection);
-+
-+ /* No actual Exports (UPX Packer can do this */
-+ if (!Thunks) continue;
-+
-+ TRACE("Creating Bound Descriptor for this DLL\n");
-+
-+ /* Create Bound Import Descriptor */
-+ BoundImportDescriptor = BindpCreateBoundImportDescriptor (ImportedLibrary,
-+ LoadedLibrary,
-+ BoundImportDescriptors);
-+
-+ /* Count how many Thunks we have */
-+ ThunkCount = 0;
-+ TempThunk = Thunks;
-+ while (TempThunk->u1.AddressOfData) {
-+ ThunkCount++;
-+ TempThunk++;
-+ }
-+
-+ /* Allocate Memory for the Thunks we will Bind */
-+ SizeOfThunks = ThunkCount * sizeof(*TempBoundThunk);
-+ BoundThunks = GlobalAlloc(GMEM_ZEROINIT, SizeOfThunks);
-+
-+ TRACE("Binding Thunks %p\n",BoundThunks);
-+
-+ /* Bind the Thunks */
-+ TempThunk = Thunks;
-+ TempBoundThunk = BoundThunks;
-+ for (Thunk=0; Thunk < ThunkCount; Thunk++) {
-+ BindpBindThunk (TempThunk,
-+ File,
-+ TempBoundThunk,
-+ LoadedLibrary,
-+ Exports,
-+ BoundImportDescriptor,
-+ DllPath);
-+ TempThunk++;
-+ TempBoundThunk++;
-+ }
-+
-+ /* Load the Second Thunk Array */
-+ TempThunk = ImageRvaToVa (File->FileHeader,
-+ File->MappedAddress,
-+ (ULONG)Imports->FirstThunk,
-+ &File->LastRvaSection);
-+
-+ TRACE("Copying Bound Thunks %p\n",TempThunk);
-+
-+ /* Copy the Pointers */
-+ if (memcmp(TempThunk, BoundThunks, SizeOfThunks)) {
-+ RtlCopyMemory(TempThunk, BoundThunks, SizeOfThunks);
-+ }
-+
-+ /* Set the TimeStamp */
-+ if (Imports->TimeDateStamp != 0xFFFFFFFF) {
-+ Imports->TimeDateStamp = 0xFFFFFFFF;
-+ }
-+
-+ /* Free the Allocated Memory */
-+ GlobalFree(BoundThunks);
-+
-+ TRACE("Moving to next File\n");
-+ }
-+
-+ TRACE("Creating Bound Import Section\n");
-+
-+ /* Create the Bound Import Table */
-+ BoundImportTable = BindpCreateBoundImportSection(BoundImportDescriptors, &BoundImportTableSize);
-+
-+ /* Zero out the Bound Import Table */
-+ File->FileHeader->OptionalHeader.DataDirectory
-+ [IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;
-+ File->FileHeader->OptionalHeader.DataDirectory
-+ [IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0;
-+
-+ /* Check if we have enough space */
-+ FirstFreeByte = GetImageUnusedHeaderBytes(File, &VirtBytesFree);
-+ HeaderBytesFree = File->Sections->VirtualAddress -
-+ File->FileHeader->OptionalHeader.SizeOfHeaders + VirtBytesFree;
-+ PhysBytesFree = File->Sections->PointerToRawData -
-+ File->FileHeader->OptionalHeader.SizeOfHeaders + VirtBytesFree;
-+
-+ TRACE("Calculating Space, %lx bytes free\n",PhysBytesFree);
-+
-+ if (BoundImportTableSize > VirtBytesFree) {
-+ if (BoundImportTableSize > HeaderBytesFree) {
-+ TRACE("Only %lx bytes free. Not enough Space\n",HeaderBytesFree);
-+ return; /* Fail...not enough space */
-+ }
-+ if (BoundImportTableSize <= PhysBytesFree) {
-+
-+ TRACE("Header Recalculation\n");
-+ /* We have enough NULLs to add it, simply enlarge header data */
-+ File->FileHeader->OptionalHeader.SizeOfHeaders = File->FileHeader->OptionalHeader.SizeOfHeaders -
-+ VirtBytesFree +
-+ BoundImportTableSize +
-+ ((File->FileHeader->OptionalHeader.FileAlignment - 1)
-+ & ~(File->FileHeader->OptionalHeader.FileAlignment - 1));
-+
-+ } else {
-+
-+ /* Resize the Headers */
-+ FIXME("Add support for Header Resizing\n");
-+
-+ /* Recalculate Headers */
-+ FileHeader = &File->FileHeader->FileHeader;
-+ OptionalHeader32 = &File->FileHeader->OptionalHeader;
-+ }
-+ }
-+
-+ /* Set Bound Import Table Data */
-+ File->FileHeader->OptionalHeader.DataDirectory
-+ [IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = FirstFreeByte;
-+ File->FileHeader->OptionalHeader.DataDirectory
-+ [IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = BoundImportTableSize;
-+
-+ TRACE("Copying Bound Import Table\n");
-+
-+ /* Copy the Bound Import Table */
-+ RtlCopyMemory(File->MappedAddress + FirstFreeByte, BoundImportTable, BoundImportTableSize);
-+
-+ /* Free out local copy */
-+ GlobalFree(BoundImportTable);
-+}
-
- /***********************************************************************
- * BindImage (IMAGEHLP.@)
-@@ -42,21 +703,80 @@
- return BindImageEx(0, ImageName, DllPath, SymbolPath, NULL);
- }
-
--/***********************************************************************
-- * BindImageEx (IMAGEHLP.@)
-+/*
-+ * BindImageEx
-+ *
-+ * FUNCTION:
-+ * Binds a PE Image File to its imported Libraries
-+ * ARGUMENTS:
-+ * Flags - Caller Specified Flags
-+ * ImageName - Name of Imagefile to Bind
-+ * DllPath - Path to search DLL Files in, can be NULL to use Default
-+ * SymbolPath - Path to search Symbol Files in, can be NULL to use Default
-+ * StatusRoutine - Callback routine to notify of Bind Events, can be NULL to disable.
-+ *
-+ * RETURNS:
-+ * TRUE if Success.
- */
--BOOL WINAPI BindImageEx(
-- DWORD Flags, LPSTR ImageName, LPSTR DllPath, LPSTR SymbolPath,
-- PIMAGEHLP_STATUS_ROUTINE StatusRoutine)
--{
-- FIXME("(%ld, %s, %s, %s, %p): stub\n",
-- Flags, debugstr_a(ImageName), debugstr_a(DllPath),
-- debugstr_a(SymbolPath), StatusRoutine
-- );
-- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-- return FALSE;
--}
-+BOOL
-+WINAPI
-+BindImageEx(
-+ IN DWORD Flags,
-+ IN LPSTR ImageName,
-+ IN LPSTR DllPath,
-+ IN LPSTR SymbolPath,
-+ IN PIMAGEHLP_STATUS_ROUTINE StatusRoutine
-+ )
-+{
-+ LOADED_IMAGE FileData;
-+ PLOADED_IMAGE File;
-+ ULONG CheckSum, HeaderSum, OldChecksum;
-+ SYSTEMTIME SystemTime;
-+ FILETIME LastWriteTime;
-+
-+ TRACE("BindImageEx Called for: %s \n", ImageName);
-+
-+ /* Set and Clear Buffer */
-+ File = &FileData;
-+ RtlZeroMemory(File, sizeof(*File));
-+
-+ /* Request Image Data */
-+ if (MapAndLoad(ImageName, DllPath, File, TRUE, FALSE)) {
-+
-+ TRACE("Image Mapped and Loaded\n");
-+
-+ /* Read Import Table */
-+ BindpWalkAndBindImports(File, DllPath);
-
-+ TRACE("Binding Completed, getting Checksum\n");
-+
-+ /* Update Checksum */
-+ OldChecksum = File->FileHeader->OptionalHeader.CheckSum;
-+ CheckSumMappedFile (File->MappedAddress,
-+ GetFileSize(File->hFile, NULL),
-+ &HeaderSum,
-+ &CheckSum);
-+ File->FileHeader->OptionalHeader.CheckSum = CheckSum;
-+
-+ TRACE("Saving Changes to file\n");
-+
-+ /* Save Changes */
-+ UnmapViewOfFile(File->MappedAddress);
-+
-+ TRACE("Setting time\n");
-+
-+ /* Save new Modified Time */
-+ GetSystemTime(&SystemTime);
-+ SystemTimeToFileTime(&SystemTime, &LastWriteTime);
-+ SetFileTime(File->hFile, NULL, NULL, &LastWriteTime);
-+
-+ /* Close Handle */
-+ CloseHandle(File->hFile);
-+ }
-+
-+ TRACE("Done\n");
-+ return TRUE;
-+}
-
- /***********************************************************************
- * CheckSum (internal)
-
-
#define UNDNAME_NO_ARGUMENTS 8192
#define UNDNAME_NO_SPECIAL_SYMS 16384
-#define _IMAGEHLPAPI WINAPI
+#ifdef _IMAGEHLP_SOURCE_
+ #define IMAGEAPI __stdcall
+ #define DBHLP_DEPRECIATED
+#else
+ #define IMAGEAPI DECLSPEC_IMPORT __stdcall
+ #if (_MSC_VER >= 1300) && !defined(MIDL_PASS)
+ #define DBHLP_DEPRECIATED __declspec(deprecated)
+ #else
+ #define DBHLP_DEPRECIATED
+ #endif
+#endif
+
+#define DBHLPAPI IMAGEAPI
#ifndef RC_INVOKED
typedef PVOID DIGEST_HANDLE;
typedef BOOL(WINAPI*DIGEST_FUNCTION)(DIGEST_HANDLE refdata,PBYTE pData,DWORD dwLength);
-PIMAGE_NT_HEADERS _IMAGEHLPAPI CheckSumMappedFile(LPVOID,DWORD,LPDWORD,LPDWORD);
-DWORD _IMAGEHLPAPI MapFileAndCheckSumA(LPSTR,LPDWORD,LPDWORD);
-DWORD _IMAGEHLPAPI MapFileAndCheckSumW(PWSTR,LPDWORD,LPDWORD);
-BOOL _IMAGEHLPAPI TouchFileTimes(HANDLE,LPSYSTEMTIME);
-BOOL _IMAGEHLPAPI SplitSymbols(LPSTR,LPSTR,LPSTR,DWORD);
-HANDLE _IMAGEHLPAPI FindDebugInfoFile(LPSTR,LPSTR,LPSTR);
-HANDLE _IMAGEHLPAPI FindExecutableImage(LPSTR,LPSTR,LPSTR);
-BOOL _IMAGEHLPAPI UpdateDebugInfoFile(LPSTR,LPSTR,LPSTR,PIMAGE_NT_HEADERS);
-BOOL _IMAGEHLPAPI UpdateDebugInfoFileEx(LPSTR,LPSTR,LPSTR,PIMAGE_NT_HEADERS,DWORD);
-BOOL _IMAGEHLPAPI BindImage(IN LPSTR,IN LPSTR,IN LPSTR);
-BOOL _IMAGEHLPAPI BindImageEx(IN DWORD,IN LPSTR,IN LPSTR,IN LPSTR,IN PIMAGEHLP_STATUS_ROUTINE);
-BOOL _IMAGEHLPAPI ReBaseImage(IN LPSTR,IN LPSTR,IN BOOL, IN BOOL,IN BOOL, IN ULONG, OUT ULONG*, OUT ULONG*, OUT ULONG*, IN OUT ULONG*, IN ULONG);
+PIMAGE_NT_HEADERS IMAGEAPI CheckSumMappedFile(LPVOID,DWORD,LPDWORD,LPDWORD);
+DWORD IMAGEAPI MapFileAndCheckSumA(LPSTR,LPDWORD,LPDWORD);
+DWORD IMAGEAPI MapFileAndCheckSumW(PWSTR,LPDWORD,LPDWORD);
+BOOL IMAGEAPI TouchFileTimes(HANDLE,LPSYSTEMTIME);
+BOOL IMAGEAPI SplitSymbols(LPSTR,LPSTR,LPSTR,DWORD);
+HANDLE IMAGEAPI FindDebugInfoFile(LPSTR,LPSTR,LPSTR);
+HANDLE IMAGEAPI FindExecutableImage(LPSTR,LPSTR,LPSTR);
+BOOL IMAGEAPI UpdateDebugInfoFile(LPSTR,LPSTR,LPSTR,PIMAGE_NT_HEADERS);
+BOOL IMAGEAPI UpdateDebugInfoFileEx(LPSTR,LPSTR,LPSTR,PIMAGE_NT_HEADERS,DWORD);
+BOOL IMAGEAPI BindImage(IN LPSTR,IN LPSTR,IN LPSTR);
+BOOL IMAGEAPI BindImageEx(IN DWORD,IN LPSTR,IN LPSTR,IN LPSTR,IN PIMAGEHLP_STATUS_ROUTINE);
+BOOL IMAGEAPI ReBaseImage(IN LPSTR,IN LPSTR,IN BOOL, IN BOOL,IN BOOL, IN ULONG, OUT ULONG*, OUT ULONG*, OUT ULONG*, IN OUT ULONG*, IN ULONG);
-PLOADED_IMAGE _IMAGEHLPAPI ImageLoad(LPSTR,LPSTR);
-BOOL _IMAGEHLPAPI ImageUnload(PLOADED_IMAGE);
-PIMAGE_NT_HEADERS _IMAGEHLPAPI ImageNtHeader(IN PVOID);
-PVOID _IMAGEHLPAPI ImageDirectoryEntryToData(IN PVOID,IN BOOLEAN,IN USHORT,OUT PULONG);
-PVOID _IMAGEHLPAPI ImageDirectoryEntryToDataEx(IN PVOID Base, IN BOOLEAN MappedAsImage, IN USHORT DirectoryEntry, OUT PULONG Size, OUT PIMAGE_SECTION_HEADER *FoundSection OPTIONAL);
-PVOID _IMAGEHLPAPI ImageDirectoryEntryToData32(PVOID Base, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size, PIMAGE_SECTION_HEADER *FoundHeader OPTIONAL, PIMAGE_FILE_HEADER FileHeader, PIMAGE_OPTIONAL_HEADER OptionalHeader);
-PIMAGE_SECTION_HEADER _IMAGEHLPAPI ImageRvaToSection(IN PIMAGE_NT_HEADERS,IN PVOID,IN ULONG);
-PVOID _IMAGEHLPAPI ImageRvaToVa(IN PIMAGE_NT_HEADERS,IN PVOID,IN ULONG,IN OUT PIMAGE_SECTION_HEADER*);
-BOOL _IMAGEHLPAPI MapAndLoad(LPSTR,LPSTR,PLOADED_IMAGE,BOOL,BOOL);
-BOOL _IMAGEHLPAPI GetImageConfigInformation(PLOADED_IMAGE,PIMAGE_LOAD_CONFIG_DIRECTORY);
-DWORD _IMAGEHLPAPI GetImageUnusedHeaderBytes(PLOADED_IMAGE,LPDWORD);
-BOOL _IMAGEHLPAPI SetImageConfigInformation(PLOADED_IMAGE,PIMAGE_LOAD_CONFIG_DIRECTORY);
-BOOL _IMAGEHLPAPI UnMapAndLoad(PLOADED_IMAGE);
-PIMAGE_DEBUG_INFORMATION _IMAGEHLPAPI MapDebugInformation(HANDLE,LPSTR,LPSTR,DWORD);
-BOOL _IMAGEHLPAPI UnmapDebugInformation(PIMAGE_DEBUG_INFORMATION);
-HANDLE _IMAGEHLPAPI FindExecutableImage(LPSTR,LPSTR,LPSTR);
-BOOL _IMAGEHLPAPI SearchTreeForFile(LPSTR,LPSTR,LPSTR);
-BOOL _IMAGEHLPAPI MakeSureDirectoryPathExists(LPCSTR);
-DWORD _IMAGEHLPAPI WINAPI UnDecorateSymbolName(LPCSTR,LPSTR,DWORD, DWORD);
+PLOADED_IMAGE IMAGEAPI ImageLoad(LPSTR,LPSTR);
+BOOL IMAGEAPI ImageUnload(PLOADED_IMAGE);
+PIMAGE_NT_HEADERS IMAGEAPI ImageNtHeader(IN PVOID);
+PVOID IMAGEAPI ImageDirectoryEntryToData(IN PVOID,IN BOOLEAN,IN USHORT,OUT PULONG);
+PVOID IMAGEAPI ImageDirectoryEntryToDataEx(IN PVOID Base, IN BOOLEAN MappedAsImage, IN USHORT DirectoryEntry, OUT PULONG Size, OUT PIMAGE_SECTION_HEADER *FoundSection OPTIONAL);
+PVOID IMAGEAPI ImageDirectoryEntryToData32(PVOID Base, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size, PIMAGE_SECTION_HEADER *FoundHeader OPTIONAL, PIMAGE_FILE_HEADER FileHeader, PIMAGE_OPTIONAL_HEADER OptionalHeader);
+PIMAGE_SECTION_HEADER IMAGEAPI ImageRvaToSection(IN PIMAGE_NT_HEADERS,IN PVOID,IN ULONG);
+PVOID IMAGEAPI ImageRvaToVa(IN PIMAGE_NT_HEADERS,IN PVOID,IN ULONG,IN OUT PIMAGE_SECTION_HEADER*);
+BOOL IMAGEAPI MapAndLoad(LPSTR,LPSTR,PLOADED_IMAGE,BOOL,BOOL);
+BOOL IMAGEAPI GetImageConfigInformation(PLOADED_IMAGE,PIMAGE_LOAD_CONFIG_DIRECTORY);
+DWORD IMAGEAPI GetImageUnusedHeaderBytes(PLOADED_IMAGE,LPDWORD);
+BOOL IMAGEAPI SetImageConfigInformation(PLOADED_IMAGE,PIMAGE_LOAD_CONFIG_DIRECTORY);
+BOOL IMAGEAPI UnMapAndLoad(PLOADED_IMAGE);
+PIMAGE_DEBUG_INFORMATION IMAGEAPI MapDebugInformation(HANDLE,LPSTR,LPSTR,DWORD);
+BOOL IMAGEAPI UnmapDebugInformation(PIMAGE_DEBUG_INFORMATION);
+HANDLE IMAGEAPI FindExecutableImage(LPSTR,LPSTR,LPSTR);
+BOOL IMAGEAPI SearchTreeForFile(LPSTR,LPSTR,LPSTR);
+BOOL IMAGEAPI MakeSureDirectoryPathExists(LPCSTR);
+DWORD IMAGEAPI WINAPI UnDecorateSymbolName(LPCSTR,LPSTR,DWORD, DWORD);
BOOL
-_IMAGEHLPAPI
+IMAGEAPI
StackWalk(DWORD,HANDLE,HANDLE,LPSTACKFRAME,LPVOID,PREAD_PROCESS_MEMORY_ROUTINE,PFUNCTION_TABLE_ACCESS_ROUTINE,PGET_MODULE_BASE_ROUTINE,PTRANSLATE_ADDRESS_ROUTINE);
-LPAPI_VERSION _IMAGEHLPAPI ImagehlpApiVersion(VOID);
-LPAPI_VERSION _IMAGEHLPAPI ImagehlpApiVersionEx(LPAPI_VERSION);
-DWORD _IMAGEHLPAPI GetTimestampForLoadedLibrary(HMODULE);
-BOOL _IMAGEHLPAPI RemovePrivateCvSymbolic(PCHAR,PCHAR*,ULONG*);
-VOID _IMAGEHLPAPI RemoveRelocations(PCHAR);
-DWORD _IMAGEHLPAPI SymSetOptions(IN DWORD);
-DWORD _IMAGEHLPAPI SymGetOptions(VOID);
-BOOL _IMAGEHLPAPI SymCleanup(IN HANDLE);
-BOOL _IMAGEHLPAPI SymEnumerateModules(IN HANDLE,IN PSYM_ENUMMODULES_CALLBACK,IN PVOID);
-BOOL _IMAGEHLPAPI SymEnumerateSymbols(IN HANDLE,IN DWORD,IN PSYM_ENUMSYMBOLS_CALLBACK,IN PVOID);
-BOOL _IMAGEHLPAPI EnumerateLoadedModules(IN HANDLE,IN PENUMLOADED_MODULES_CALLBACK,IN PVOID);
-LPVOID _IMAGEHLPAPI SymFunctionTableAccess(HANDLE,DWORD);
-BOOL _IMAGEHLPAPI SymGetModuleInfo(IN HANDLE,IN DWORD,OUT PIMAGEHLP_MODULE);
-DWORD _IMAGEHLPAPI SymGetModuleBase(IN HANDLE,IN DWORD);
-BOOL _IMAGEHLPAPI SymGetSymFromAddr(IN HANDLE,IN DWORD,OUT PDWORD,OUT PIMAGEHLP_SYMBOL);
-BOOL _IMAGEHLPAPI SymGetSymFromName(IN HANDLE,IN LPSTR,OUT PIMAGEHLP_SYMBOL);
-BOOL _IMAGEHLPAPI SymGetSymNext(IN HANDLE,IN OUT PIMAGEHLP_SYMBOL);
-BOOL _IMAGEHLPAPI SymGetSymPrev(IN HANDLE,IN OUT PIMAGEHLP_SYMBOL);
-BOOL _IMAGEHLPAPI SymGetLineFromAddr(IN HANDLE,IN DWORD,OUT PDWORD,OUT PIMAGEHLP_LINE);
-BOOL _IMAGEHLPAPI SymGetLineFromName(IN HANDLE,IN LPSTR,IN LPSTR,IN DWORD,OUT PLONG,IN OUT PIMAGEHLP_LINE);
-BOOL _IMAGEHLPAPI SymGetLineNext(IN HANDLE,IN OUT PIMAGEHLP_LINE);
-BOOL _IMAGEHLPAPI SymGetLinePrev(IN HANDLE,IN OUT PIMAGEHLP_LINE);
-BOOL _IMAGEHLPAPI SymMatchFileName(IN LPSTR,IN LPSTR,OUT LPSTR*,OUT LPSTR*);
-BOOL _IMAGEHLPAPI SymInitialize(IN HANDLE,IN LPSTR,IN BOOL);
-BOOL _IMAGEHLPAPI SymGetSearchPath(IN HANDLE,OUT LPSTR,IN DWORD);
-BOOL _IMAGEHLPAPI SymSetSearchPath(IN HANDLE,IN LPSTR);
-BOOL _IMAGEHLPAPI SymLoadModule(IN HANDLE,IN HANDLE,IN PSTR,IN PSTR,IN DWORD,IN DWORD);
-BOOL _IMAGEHLPAPI SymUnloadModule(IN HANDLE,IN DWORD);
-BOOL _IMAGEHLPAPI SymUnDName(IN PIMAGEHLP_SYMBOL,OUT LPSTR,IN DWORD);
-BOOL _IMAGEHLPAPI SymRegisterCallback(IN HANDLE,IN PSYMBOL_REGISTERED_CALLBACK,IN PVOID);
-BOOL _IMAGEHLPAPI ImageGetDigestStream(IN HANDLE,IN DWORD,IN DIGEST_FUNCTION,IN DIGEST_HANDLE);
-//BOOL _IMAGEHLPAPI ImageAddCertificate(IN HANDLE,IN LPWIN_CERTIFICATE,OUT PDWORD);
-BOOL _IMAGEHLPAPI ImageRemoveCertificate(IN HANDLE,IN DWORD);
-BOOL _IMAGEHLPAPI ImageEnumerateCertificates(IN HANDLE,IN WORD,OUT PDWORD,IN OUT PDWORD OPTIONAL,IN OUT DWORD OPTIONAL);
-//BOOL _IMAGEHLPAPI ImageGetCertificateData(IN HANDLE,IN DWORD,OUT LPWIN_CERTIFICATE,IN OUT PDWORD);
-//BOOL _IMAGEHLPAPI ImageGetCertificateHeader(IN HANDLE,IN DWORD,IN OUT LPWIN_CERTIFICATE);
-BOOL _IMAGEHLPAPI CopyPdb(CHAR const*,CHAR const*,BOOL);
-BOOL _IMAGEHLPAPI RemovePrivateCvSymbolicEx(PCHAR,ULONG,PCHAR*,ULONG*);
+LPAPI_VERSION IMAGEAPI ImagehlpApiVersion(VOID);
+LPAPI_VERSION IMAGEAPI ImagehlpApiVersionEx(LPAPI_VERSION);
+DWORD IMAGEAPI GetTimestampForLoadedLibrary(HMODULE);
+BOOL IMAGEAPI RemovePrivateCvSymbolic(PCHAR,PCHAR*,ULONG*);
+VOID IMAGEAPI RemoveRelocations(PCHAR);
+DWORD IMAGEAPI SymSetOptions(IN DWORD);
+DWORD IMAGEAPI SymGetOptions(VOID);
+BOOL IMAGEAPI SymCleanup(IN HANDLE);
+BOOL IMAGEAPI SymEnumerateModules(IN HANDLE,IN PSYM_ENUMMODULES_CALLBACK,IN PVOID);
+BOOL IMAGEAPI SymEnumerateSymbols(IN HANDLE,IN DWORD,IN PSYM_ENUMSYMBOLS_CALLBACK,IN PVOID);
+BOOL IMAGEAPI EnumerateLoadedModules(IN HANDLE,IN PENUMLOADED_MODULES_CALLBACK,IN PVOID);
+LPVOID IMAGEAPI SymFunctionTableAccess(HANDLE,DWORD);
+BOOL IMAGEAPI SymGetModuleInfo(IN HANDLE,IN DWORD,OUT PIMAGEHLP_MODULE);
+DWORD IMAGEAPI SymGetModuleBase(IN HANDLE,IN DWORD);
+BOOL IMAGEAPI SymGetSymFromAddr(IN HANDLE,IN DWORD,OUT PDWORD,OUT PIMAGEHLP_SYMBOL);
+BOOL IMAGEAPI SymGetSymFromName(IN HANDLE,IN LPSTR,OUT PIMAGEHLP_SYMBOL);
+BOOL IMAGEAPI SymGetSymNext(IN HANDLE,IN OUT PIMAGEHLP_SYMBOL);
+BOOL IMAGEAPI SymGetSymPrev(IN HANDLE,IN OUT PIMAGEHLP_SYMBOL);
+BOOL IMAGEAPI SymGetLineFromAddr(IN HANDLE,IN DWORD,OUT PDWORD,OUT PIMAGEHLP_LINE);
+BOOL IMAGEAPI SymGetLineFromName(IN HANDLE,IN LPSTR,IN LPSTR,IN DWORD,OUT PLONG,IN OUT PIMAGEHLP_LINE);
+BOOL IMAGEAPI SymGetLineNext(IN HANDLE,IN OUT PIMAGEHLP_LINE);
+BOOL IMAGEAPI SymGetLinePrev(IN HANDLE,IN OUT PIMAGEHLP_LINE);
+BOOL IMAGEAPI SymMatchFileName(IN LPSTR,IN LPSTR,OUT LPSTR*,OUT LPSTR*);
+BOOL IMAGEAPI SymInitialize(IN HANDLE,IN LPSTR,IN BOOL);
+BOOL IMAGEAPI SymGetSearchPath(IN HANDLE,OUT LPSTR,IN DWORD);
+BOOL IMAGEAPI SymSetSearchPath(IN HANDLE,IN LPSTR);
+DWORD IMAGEAPI SymLoadModule(IN HANDLE,IN HANDLE,IN PSTR,IN PSTR,IN DWORD,IN DWORD);
+BOOL IMAGEAPI SymUnloadModule(IN HANDLE,IN DWORD);
+BOOL IMAGEAPI SymUnDName(IN PIMAGEHLP_SYMBOL,OUT LPSTR,IN DWORD);
+BOOL IMAGEAPI SymRegisterCallback(IN HANDLE,IN PSYMBOL_REGISTERED_CALLBACK,IN PVOID);
+BOOL IMAGEAPI ImageGetDigestStream(IN HANDLE,IN DWORD,IN DIGEST_FUNCTION,IN DIGEST_HANDLE);
+//BOOL IMAGEAPI ImageAddCertificate(IN HANDLE,IN LPWIN_CERTIFICATE,OUT PDWORD);
+BOOL IMAGEAPI ImageRemoveCertificate(IN HANDLE,IN DWORD);
+BOOL IMAGEAPI ImageEnumerateCertificates(IN HANDLE,IN WORD,OUT PDWORD,IN OUT PDWORD OPTIONAL,IN OUT DWORD OPTIONAL);
+//BOOL IMAGEAPI ImageGetCertificateData(IN HANDLE,IN DWORD,OUT LPWIN_CERTIFICATE,IN OUT PDWORD);
+//BOOL IMAGEAPI ImageGetCertificateHeader(IN HANDLE,IN DWORD,IN OUT LPWIN_CERTIFICATE);
+BOOL IMAGEAPI CopyPdb(CHAR const*,CHAR const*,BOOL);
+BOOL IMAGEAPI RemovePrivateCvSymbolicEx(PCHAR,ULONG,PCHAR*,ULONG*);
#endif /* RC_INVOKED */
#define IMAGE_SUBSYSTEM_OS2_CUI 5
#define IMAGE_SUBSYSTEM_POSIX_CUI 7
#define IMAGE_SUBSYSTEM_XBOX 14
+#define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION 0x0200
+#define IMAGE_DLLCHARACTERISTICS_NO_SEH 0x0400
+#define IMAGE_DLLCHARACTERISTICS_NO_BIND 0x0800
+#define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 0x2000
+#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000
#define IMAGE_FIRST_SECTION(h) ((PIMAGE_SECTION_HEADER) ((DWORD)h+FIELD_OFFSET(IMAGE_NT_HEADERS,OptionalHeader)+((PIMAGE_NT_HEADERS)(h))->FileHeader.SizeOfOptionalHeader))
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0
#define IMAGE_DIRECTORY_ENTRY_IMPORT 1