diff --git a/reactos/lib/imagehlp/access.c b/reactos/lib/imagehlp/access.c index 764ff029ac7..7f2ce9b7663 100644 --- a/reactos/lib/imagehlp/access.c +++ b/reactos/lib/imagehlp/access.c @@ -1,564 +1,634 @@ /* - * 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 -#include -#include "windef.h" -#include "winbase.h" -#include "winnt.h" -#include "winerror.h" -#include "wine/debug.h" -#include "imagehlp.h" +/* INCLUDES ******************************************************************/ -/* Couple of Hacks */ -extern inline DWORD WINAPI GetLastError(void) -{ - DWORD ret; - __asm__ __volatile__( ".byte 0x64\n\tmovl 0x60,%0" : "=r" (ret) ); - return ret; -} +#include "precomp.h" -#define InitializeListHead(ListHead) (\ - (ListHead)->Flink = (ListHead)->Blink = (ListHead)) +//#define NDEBUG +#include -#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);\ - } +/* DATA **********************************************************************/ -WINE_DEFAULT_DEBUG_CHANNEL(imagehlp); - -/*********************************************************************** - * 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; -/*********************************************************************** - * GetTimestampForLoadedLibrary (IMAGEHLP.@) - */ -DWORD WINAPI GetTimestampForLoadedLibrary(HMODULE Module) -{ - FIXME("(%p): stub\n", Module); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} + /* Check if this entry is invalid */ + if (DirectoryEntry >= OptionalHeader->NumberOfRvaAndSizes) + { + /* Nothing found */ + *Size = 0; + return NULL; + } -/*********************************************************************** - * GetImageConfigInformation (IMAGEHLP.@) - */ -BOOL WINAPI GetImageConfigInformation( - PLOADED_IMAGE LoadedImage, - PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation) -{ - FIXME("(%p, %p): stub\n", - LoadedImage, ImageConfigInformation - ); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} + /* Get the VA of the Directory Requested */ + DirectoryEntryVA = OptionalHeader->DataDirectory[DirectoryEntry].VirtualAddress; + if (!DirectoryEntryVA) + { + /* It doesn't exist */ + *Size = 0; + return NULL; + } -/*********************************************************************** - * GetImageUnusedHeaderBytes (IMAGEHLP.@) - */ -DWORD -WINAPI -GetImageUnusedHeaderBytes( - PLOADED_IMAGE LoadedImage, - LPDWORD SizeUnusedHeaderBytes - ) -{ - DWORD FirstFreeByte; - PIMAGE_OPTIONAL_HEADER OptionalHeader32 = NULL; - PIMAGE_NT_HEADERS NtHeaders; - ULONG i; + /* Get the size of the Directory Requested */ + *Size = OptionalHeader->DataDirectory[DirectoryEntry].Size; - /* Read the NT Headers */ - NtHeaders = LoadedImage->FileHeader; + /* 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); + } - /* 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; iNumberOfRvaAndSizes; 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; - } - } + /* 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)); } - /* Return the unused Header Bytes */ - *SizeUnusedHeaderBytes = OptionalHeader32->SizeOfHeaders - FirstFreeByte; + /* Move to the next section */ + CurrentSection++; + } - /* And return the first free byte*/ - return FirstFreeByte; + /* If we got here, then we didn't find anything */ + return NULL; } -/*********************************************************************** - * ImageDirectoryEntryToData (IMAGEHLP.@) +/* + * @unimplemented + */ +DWORD +IMAGEAPI +GetTimestampForLoadedLibrary(HMODULE Module) +{ + UNIMPLEMENTED; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; +} + +/* + * @unimplemented + */ +BOOL +IMAGEAPI +GetImageConfigInformation(PLOADED_IMAGE LoadedImage, + PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation) +{ + UNIMPLEMENTED; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +/* + * @implemented + */ +DWORD +IMAGEAPI +GetImageUnusedHeaderBytes(PLOADED_IMAGE LoadedImage, + LPDWORD SizeUnusedHeaderBytes) +{ + SIZE_T FirstFreeByte; + PIMAGE_OPTIONAL_HEADER OptionalHeader = 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 */ + 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 = OptionalHeader->SizeOfHeaders - (DWORD)FirstFreeByte; + + /* And return the first free byte*/ + return (DWORD)FirstFreeByte; +} + +/* + * @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.@) +/* + * @implemented */ -PVOID -STDCALL -ImageDirectoryEntryToData32 ( - PVOID Base, - BOOLEAN MappedAsImage, - USHORT DirectoryEntry, - PULONG Size, - PIMAGE_SECTION_HEADER *FoundHeader OPTIONAL, - PIMAGE_FILE_HEADER FileHeader, - PIMAGE_OPTIONAL_HEADER OptionalHeader - ) +PLOADED_IMAGE +IMAGEAPI +ImageLoad(LPSTR DllName, + LPSTR DllPath) { - 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; iNumberOfSections; 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.@) - */ -PLOADED_IMAGE WINAPI 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 the Names Match */ - if (!lstrcmpi( DllName, LoadedImage->ModuleName )) { - //FIXME("Found it, returning it\n"); + /* Check if we didn't have a complete name */ + if (!CompleteName) + { + /* Split this module's name */ + _splitpath(LoadedImage->ModuleName, NULL, NULL, Filename, Ext); + + /* 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 */ + 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); - /* Allocate memory for the Structure, and write the Module Name under */ - LoadedImage = HeapAlloc(IMAGEHLP_hHeap, 0, sizeof(*LoadedImage) + lstrlen(DllName) + 1); + /* Copy the Module Name */ + strcpy(LoadedImage->ModuleName, DllName); - /* Module Name will be after structure */ - LoadedImage->ModuleName = (LPSTR)LoadedImage + 1; + /* Now Load it */ + if (MapAndLoad(DllName, DllPath, LoadedImage, TRUE, TRUE)) + { + /* Add it to our list and return it */ + InsertTailList(&ImageLoadListHead, &LoadedImage->Links); + return LoadedImage; + } - /* Copy the Moduel Name */ - lstrcpy(LoadedImage->ModuleName, DllName); - - /* 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; + /* If the image list isn't empty, remove this entry */ + if (!IsListEmpty(&LoadedImage->Links)) RemoveEntryList(&LoadedImage->Links); - TRACE("(%p)\n", pLoadedImage); - - if(!IMAGEHLP_pFirstLoadedImage || !pLoadedImage) - { - /* No image loaded or null pointer */ - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } + /* Unmap and unload it */ + UnMapAndLoad(LoadedImage); - 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; - } + /* Free the structure */ + HeapFree(IMAGEHLP_hHeap, 0, 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; - - 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; + 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; + /* 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 */ + + /* Success, break out */ + break; + } + + /* Create the File Mapping */ + hFileMapping = CreateFileMappingA(hFile, + NULL, + ReadOnly ? PAGE_READONLY : + PAGE_READWRITE, + 0, + 0, + NULL); + if (!hFileMapping) + { + /* Fail */ + SetLastError(GetLastError()); + CloseHandle(hFile); return FALSE; } - /* Create the File Mapping */ - if (!(hFileMapping = CreateFileMappingA (LoadedImage->hFile, - NULL, - ReadOnly ? PAGE_READONLY : PAGE_READWRITE, - 0, - 0, - NULL))) + /* 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) { - DWORD dwLastError = GetLastError(); - SetLastError(dwLastError); - goto Error; + /* It was, so close our handle and write it as invalid */ + CloseHandle(hFile); + LoadedImage->hFile = INVALID_HANDLE_VALUE; + } + else + { + /* Write our file handle */ + LoadedImage->hFile = hFile; } - /* Get a pointer to the file */ - if(!(LoadedImage->MappedAddress = MapViewOfFile(hFileMapping, - ReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE, - 0, - 0, - 0))) + /* Return Success */ + return TRUE; +} + +/* + * @unimplemented + */ +BOOL +IMAGEAPI +SetImageConfigInformation(PLOADED_IMAGE LoadedImage, + PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation) +{ + UNIMPLEMENTED; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +/* + * @implemented + */ +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) { - DWORD dwLastError = GetLastError(); - SetLastError(dwLastError); - goto Error; + /* 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); + } } - /* Close the handle to the map, we don't need it anymore */ - CloseHandle(hFileMapping); - hFileMapping=NULL; + /* Check if the image had a valid handle, and close it */ + if (Image->hFile != INVALID_HANDLE_VALUE) CloseHandle(Image->hFile); - /* 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.@) - */ -BOOL WINAPI SetImageConfigInformation( - PLOADED_IMAGE LoadedImage, - PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation) +BOOL +IMAGEAPI +UnloadAllImages(VOID) { - FIXME("(%p, %p): stub\n", - LoadedImage, ImageConfigInformation - ); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} + PLIST_ENTRY Head, Entry; + PLOADED_IMAGE CurrentImage; -/*********************************************************************** - * UnMapAndLoad (IMAGEHLP.@) - */ -BOOL WINAPI UnMapAndLoad(PLOADED_IMAGE LoadedImage) -{ - FIXME("(%p): stub\n", LoadedImage); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + /* 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; } diff --git a/reactos/lib/imagehlp/debug.c b/reactos/lib/imagehlp/debug.c deleted file mode 100644 index d73c9f8cf95..00000000000 --- a/reactos/lib/imagehlp/debug.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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 - -#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; -} diff --git a/reactos/lib/imagehlp/imagehlp.def b/reactos/lib/imagehlp/imagehlp.def index 21c9bce242f..646c19782cc 100644 --- a/reactos/lib/imagehlp/imagehlp.def +++ b/reactos/lib/imagehlp/imagehlp.def @@ -1,63 +1,111 @@ 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 diff --git a/reactos/lib/imagehlp/imagehlp.xml b/reactos/lib/imagehlp/imagehlp.xml index 57784852030..a118d6df157 100644 --- a/reactos/lib/imagehlp/imagehlp.xml +++ b/reactos/lib/imagehlp/imagehlp.xml @@ -1,25 +1,17 @@ . - include/wine - - - 0x600 - 0x501 - 0x501 - - - 0x10000L - wine + 0x600 + 0x0600 + ntdll kernel32 access.c - debug.c imagehlp_main.c integrity.c - internal.c modify.c - symbol.c imagehlp.rc + precomp.h + -enable-stdcall-fixup diff --git a/reactos/lib/imagehlp/imagehlp_main.c b/reactos/lib/imagehlp/imagehlp_main.c index 89e3c857768..9442182a62c 100644 --- a/reactos/lib/imagehlp/imagehlp_main.c +++ b/reactos/lib/imagehlp/imagehlp_main.c @@ -1,154 +1,43 @@ /* - * 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 +/* 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 -/**********************************************************************/ +/* 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; } diff --git a/reactos/lib/imagehlp/integrity.c b/reactos/lib/imagehlp/integrity.c index 2b4c5b58281..d93dcf9e062 100644 --- a/reactos/lib/imagehlp/integrity.c +++ b/reactos/lib/imagehlp/integrity.c @@ -1,61 +1,37 @@ /* - * 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 - -#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 + +/* 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 ); @@ -80,18 +56,35 @@ static BOOL IMAGEHLP_GetSecurityDirOffset( HANDLE handle, DWORD num, 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; + + 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; - size = sd->Size; - /* 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; @@ -115,57 +108,131 @@ static BOOL IMAGEHLP_GetSecurityDirOffset( HANDLE handle, DWORD num, 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)); +} + +/* + * @unimplemented + */ +BOOL +IMAGEAPI +ImageAddCertificate(HANDLE FileHandle, + LPWIN_CERTIFICATE Certificate, + PDWORD Index) +{ + UNIMPLEMENTED; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +/* + * @unimplemented + */ +BOOL +IMAGEAPI +ImageEnumerateCertificates(HANDLE FileHandle, + WORD TypeFilter, + PDWORD CertificateCount, + PDWORD Indices, + DWORD IndexCount) +{ + 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; } - -/*********************************************************************** - * ImageAddCertificate (IMAGEHLP.@) +/* + * @implemented */ - -BOOL WINAPI ImageAddCertificate( - HANDLE FileHandle, LPWIN_CERTIFICATE Certificate, PDWORD Index) -{ - FIXME("(%p, %p, %p): stub\n", - FileHandle, Certificate, Index - ); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - -/*********************************************************************** - * ImageEnumerateCertificates (IMAGEHLP.@) - */ -BOOL WINAPI 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; -} - -/*********************************************************************** - * ImageGetCertificateData (IMAGEHLP.@) - * - * FIXME: not sure that I'm dealing with the Index the right way - */ -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 ) @@ -193,45 +260,256 @@ BOOL WINAPI ImageGetCertificateData( if( count != size ) return FALSE; - TRACE("OK\n"); - + DPRINT("OK\n"); return TRUE; } -/*********************************************************************** - * ImageGetCertificateHeader (IMAGEHLP.@) +/* + * @unimplemented */ -BOOL WINAPI ImageGetCertificateHeader( - HANDLE FileHandle, DWORD CertificateIndex, - LPWIN_CERTIFICATE Certificateheader) +BOOL +IMAGEAPI +ImageGetCertificateHeader(HANDLE FileHandle, + DWORD CertificateIndex, + LPWIN_CERTIFICATE Certificateheader) { - FIXME("(%p, %ld, %p): stub\n", - FileHandle, CertificateIndex, Certificateheader - ); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + 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; } -/*********************************************************************** - * ImageGetDigestStream (IMAGEHLP.@) +/* + * @unimplemented */ -BOOL WINAPI ImageGetDigestStream( - HANDLE FileHandle, DWORD DigestLevel, - DIGEST_FUNCTION DigestFunction, DIGEST_HANDLE DigestHandle) +BOOL +IMAGEAPI +ImageGetDigestStream(HANDLE FileHandle, + DWORD DigestLevel, + DIGEST_FUNCTION DigestFunction, + DIGEST_HANDLE DigestHandle) { - FIXME("(%p, %ld, %p, %p): stub\n", - FileHandle, DigestLevel, DigestFunction, DigestHandle - ); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + UNIMPLEMENTED; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } -/*********************************************************************** - * ImageRemoveCertificate (IMAGEHLP.@) +/* + * @unimplemented */ -BOOL WINAPI ImageRemoveCertificate(HANDLE FileHandle, DWORD Index) +BOOL +IMAGEAPI +ImageRemoveCertificate(HANDLE FileHandle, + DWORD Index) { - FIXME("(%p, %ld): stub\n", FileHandle, Index); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + UNIMPLEMENTED; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + + +/* + * @implemented + */ +PIMAGE_NT_HEADERS +IMAGEAPI +CheckSumMappedFile(LPVOID BaseAddress, + DWORD FileLength, + LPDWORD HeaderSum, + LPDWORD CheckSum) +{ + 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; +} + +/* + * @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 + */ +DWORD +IMAGEAPI +MapFileAndCheckSumW(LPWSTR Filename, + LPDWORD HeaderSum, + LPDWORD CheckSum) +{ + 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; } diff --git a/reactos/lib/imagehlp/internal.c b/reactos/lib/imagehlp/internal.c deleted file mode 100644 index 2da3cd221c3..00000000000 --- a/reactos/lib/imagehlp/internal.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * 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 - -#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; -} diff --git a/reactos/lib/imagehlp/modify.c b/reactos/lib/imagehlp/modify.c index 971254742f0..5c524c1dea6 100644 --- a/reactos/lib/imagehlp/modify.c +++ b/reactos/lib/imagehlp/modify.c @@ -1,1118 +1,1032 @@ /* - * 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 +/* 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 -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); + LPSTR Name = BoundLibraries; - /* Set and Clear Buffer */ - File = &FileData; - RtlZeroMemory(File, sizeof(*File)); + /* Check if it hasn't been initialized yet */ + if (!BoundLibrariesPointer) + { + /* Start with a null char and set the pointer */ + *Name = ANSI_NULL; + BoundLibrariesPointer = Name; + } - /* Request Image Data */ - if (MapAndLoad(ImageName, DllPath, File, TRUE, FALSE)) { + /* Loop the current buffer */ + while (*Name) + { + /* Try to match this DLL's name and return it */ + if (!_stricmp(Name, ModuleName)) return Name; - //FIXME("Image Mapped and Loaded\n"); + /* Move on to the next DLL Name */ + Name += strlen(Name) + sizeof(CHAR); + } - /* Read Import Table */ - BindpWalkAndBindImports(File, DllPath); + /* If we got here, we didn't find one, so add this one to our buffer */ + strcpy(Name, ModuleName); - //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; + /* Set the new position of the buffer, and null-terminate it */ + BoundLibrariesPointer = Name + strlen(Name) + sizeof(CHAR); + *BoundLibrariesPointer = ANSI_NULL; - //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; + /* Return the pointer to the name */ + return Name; } -/* - * 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); -} - - -/* - * 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; + 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 Sizes */ + /* 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; + /* 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; - /* 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; + /* 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)); - /* 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++; + /* 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 next Internal Descriptor */ - CurrentBoundImportDescriptor++; - } + /* Move to the next descriptor */ + NextDescriptor = &Descriptor->Next; + } - /* Now put the pointer back at the beginning and clear the buffer */ - RtlZeroMemory(BoundLibraries, 4096); - BoundLibrariesPointer = BoundLibraries; + /* Loop the descriptors and forwarders to free them */ + NextDescriptor = BoundImportDescriptor; + while ((Descriptor = *NextDescriptor)) + { + /* Read next internal descriptor */ + *NextDescriptor = Descriptor->Next; - return BoundImportTable; + /* Loop its forwarders */ + NextForwarder = &Descriptor->Forwarders; + while ((Forwarder = *NextForwarder)) + { + /* Next Forwarder */ + *NextForwarder = Forwarder->Next; + + /* Free it */ + HeapFree(IMAGEHLP_hHeap, 0, Forwarder); + } + + /* Free it */ + HeapFree(IMAGEHLP_hHeap, 0, Descriptor); + } + + /* 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; + +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; +} + +BOOL +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_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) + { + /* Get the ordinal number and pointer to the name */ + OrdinalNumber = (IMAGE_ORDINAL(Thunk->u1.Ordinal) - Exports->Base); + ImportName = (PIMAGE_IMPORT_BY_NAME)NameBuffer; + + /* 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; + } + } + + /* 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 TRUE; +} + +PIMPORT_DESCRIPTOR +IMAGEAPI +BindpAddImportDescriptor(PIMPORT_DESCRIPTOR *BoundImportDescriptor, + PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor, + LPSTR DllName, + PLOADED_IMAGE Image) +{ + 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 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; + } + + /* Now load the Exports */ + DPRINT("DLL Loaded at: %p \n", LoadedLibrary->MappedAddress); + Exports = ImageDirectoryEntryToData(LoadedLibrary->MappedAddress, + FALSE, + IMAGE_DIRECTORY_ENTRY_EXPORT, + &SizeOfExports); + + /* 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++; + } + } + + /* 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 */ + } + + /* 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); + } + } /* - * 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 + * @implemented */ -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 - ) +BOOL +IMAGEAPI +BindImageEx(IN DWORD Flags, + IN LPSTR ImageName, + IN LPSTR DllPath, + IN LPSTR SymbolPath, + IN PIMAGEHLP_STATUS_ROUTINE StatusRoutine) { - 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; + 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); - /* 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); + /* Set and Clear Buffer */ + File = &FileData; + RtlZeroMemory(File, sizeof(*File)); - //FIXME("Binding a Thunk\n"); + /* Request Image Data */ + if (MapAndLoad(ImageName, DllPath, File, TRUE, FALSE)) + { + /* Write the image's name */ + DPRINT("Image Mapped and Loaded\n"); + File->ModuleName = ImageName; - /* 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); + /* 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; - 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; + /* Check if this image should be bound */ + if (OptionalHeader->DllCharacteristics & + IMAGE_DLLCHARACTERISTICS_NO_BIND) + { + /* Don't bind it */ + goto Skip; } - } - } - /* Fail if we still didn't find anything */ - if (!OrdinalNumber) return FALSE; + /* Check if the image has security data */ + if ((ImageDirectoryEntryToData(File->MappedAddress, + FALSE, + IMAGE_DIRECTORY_ENTRY_SECURITY, + &DataSize)) || DataSize) + { + /* It does, skip it */ + goto Skip; + } - /* Write the Pointer */ - BoundThunk->u1.Function = (PDWORD)(AddressOfPointers[OrdinalNumber] + LibraryOptionalHeader32->ImageBase); + /* Read Import Table */ + BindpWalkAndProcessImports(File, DllPath, &UpdateImage); - /* 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)) { + /* Check if we need to update the image */ + if ((UpdateImage) && (File->hFile != INVALID_HANDLE_VALUE)) + { + /* FIXME: Update symbols */ - //FIXME("This Thunk is a forward...calling forward thunk bounder\n"); + /* 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; - /* Replace the Forwarder String by the actual Pointer */ - BoundThunk->u1.Function = (PDWORD)BindpAddBoundForwarder (BoundImportDescriptor, - DllPath, - ImageRvaToVa (LoadedLibrary->FileHeader, - LoadedLibrary->MappedAddress, - AddressOfPointers[OrdinalNumber], - &LoadedLibrary->LastRvaSection)); + /* 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); + } + } + } - /* Return Success */ +Skip: + + /* Unmap the image */ + UnmapViewOfFile(File->MappedAddress); + + /* Close the handle if it's valid */ + if (File->hFile != INVALID_HANDLE_VALUE) CloseHandle(File->hFile); + + /* 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; } /* - * 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. + * @implemented */ -ULONG -STDCALL -BindpAddBoundForwarder( - PBOUND_IMPORT_DESCRIPTOR BoundImportDescriptor, - LPSTR DllPath, - PUCHAR ForwarderString - ) +BOOL +IMAGEAPI +BindImage(LPSTR ImageName, + LPSTR DllPath, + LPSTR SymbolPath) { - 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); - 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; - } - } - - 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; + /* Call the newer API */ + return BindImageEx(0, + ImageName, + DllPath, + SymbolPath, + NULL); } /* - * 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 + * @unimplemented */ -PBOUND_IMPORT_DESCRIPTOR -STDCALL -BindpCreateBoundImportDescriptor( - LPSTR LibraryName, - PLOADED_IMAGE Library, - PULONG BoundImportDescriptor - ) +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) { - 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; + UNIMPLEMENTED; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } -/*********************************************************************** - * BindImage (IMAGEHLP.@) +/* + * @unimplemented */ -BOOL WINAPI BindImage( - LPSTR ImageName, LPSTR DllPath, LPSTR SymbolPath) +VOID +IMAGEAPI +RemoveRelocations(PCHAR ImageName) { - return BindImageEx(0, ImageName, DllPath, SymbolPath, NULL); + UNIMPLEMENTED; + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); } -/*********************************************************************** - * CheckSum (internal) +/* + * @implemented */ -static WORD CalcCheckSum( - DWORD StartValue, LPVOID BaseAddress, DWORD WordCount) +BOOL +IMAGEAPI +TouchFileTimes(HANDLE FileHandle, + LPSYSTEMTIME lpSystemTime) { - LPWORD Ptr; - DWORD Sum; - DWORD i; + FILETIME FileTime; + SYSTEMTIME SystemTime; + + if(lpSystemTime == NULL) + { + GetSystemTime(&SystemTime); + lpSystemTime = &SystemTime; + } - 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)); -} - - -/*********************************************************************** - * 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; -} - -/*********************************************************************** - * 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; -} - -/*********************************************************************** - * 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; -} - -/*********************************************************************** - * 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; -} - -/*********************************************************************** - * 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; -} - -/*********************************************************************** - * RemoveRelocations (IMAGEHLP.@) - */ -VOID WINAPI RemoveRelocations(PCHAR ImageName) -{ - FIXME("(%p): stub\n", ImageName); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); -} - -/*********************************************************************** - * SplitSymbols (IMAGEHLP.@) - */ -BOOL WINAPI SplitSymbols( - LPSTR ImageName, LPSTR SymbolsPath, - LPSTR SymbolFilePath, DWORD Flags) -{ - FIXME("(%s, %s, %s, %ld): stub\n", - debugstr_a(ImageName), debugstr_a(SymbolsPath), - debugstr_a(SymbolFilePath), Flags - ); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - -/*********************************************************************** - * UpdateDebugInfoFile (IMAGEHLP.@) - */ -BOOL WINAPI UpdateDebugInfoFile( - LPSTR ImageFileName, LPSTR SymbolPath, - LPSTR DebugFilePath, PIMAGE_NT_HEADERS NtHeaders) -{ - FIXME("(%s, %s, %s, %p): stub\n", - debugstr_a(ImageFileName), debugstr_a(SymbolPath), - debugstr_a(DebugFilePath), NtHeaders - ); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - -/*********************************************************************** - * UpdateDebugInfoFileEx (IMAGEHLP.@) - */ -BOOL WINAPI UpdateDebugInfoFileEx( - LPSTR ImageFileName, LPSTR SymbolPath, LPSTR DebugFilePath, - PIMAGE_NT_HEADERS NtHeaders, DWORD OldChecksum) -{ - 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; + return (SystemTimeToFileTime(lpSystemTime, + &FileTime) && + SetFileTime(FileHandle, + NULL, + NULL, + &FileTime)); } diff --git a/reactos/lib/imagehlp/precomp.h b/reactos/lib/imagehlp/precomp.h new file mode 100644 index 00000000000..3835a51ae1c --- /dev/null +++ b/reactos/lib/imagehlp/precomp.h @@ -0,0 +1,53 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS System Libraries + * FILE: lib/imagehlp/precomp.h + * PURPOSE: Imagehlp Libary Header + * PROGRAMMER: Alex Ionescu (alex@relsoft.net) + */ + +/* INCLUDES ******************************************************************/ + +/* Definitions */ +#define _CRT_SECURE_NO_DEPRECATE +#define NTOS_MODE_USER +#define WIN32_NO_STATUS + +/* PSDK/NDK Headers */ +#include +#include +#include +#include + +/* C STDLIB Headers */ +#include + +/* TYPES *********************************************************************/ + +typedef struct _BOUND_FORWARDER_REFS +{ + struct _BOUND_FORWARDER_REFS *Next; + ULONG TimeDateStamp; + LPSTR ModuleName; +} BOUND_FORWARDER_REFS, *PBOUND_FORWARDER_REFS; + +typedef struct _IMPORT_DESCRIPTOR +{ + struct _IMPORT_DESCRIPTOR *Next; + LPSTR ModuleName; + ULONG TimeDateStamp; + USHORT ForwaderReferences; + PBOUND_FORWARDER_REFS Forwarders; +} IMPORT_DESCRIPTOR, *PIMPORT_DESCRIPTOR; + +/* DATA **********************************************************************/ + +extern HANDLE IMAGEHLP_hHeap; + +/* FUNCTIONS *****************************************************************/ + +BOOL +IMAGEAPI +UnloadAllImages(VOID); + +/* EOF */ diff --git a/reactos/lib/imagehlp/symbol.c b/reactos/lib/imagehlp/symbol.c deleted file mode 100644 index 6ab4428e5e6..00000000000 --- a/reactos/lib/imagehlp/symbol.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * 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 - -#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; -} diff --git a/reactos/lib/imagehlp/winehq2ros.patch b/reactos/lib/imagehlp/winehq2ros.patch deleted file mode 100644 index b4c8ae8a521..00000000000 --- a/reactos/lib/imagehlp/winehq2ros.patch +++ /dev/null @@ -1,1064 +0,0 @@ - -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; iNumberOfRvaAndSizes; 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) - - diff --git a/reactos/w32api/include/imagehlp.h b/reactos/w32api/include/imagehlp.h index 5e64e7d46f4..9139547b6b3 100644 --- a/reactos/w32api/include/imagehlp.h +++ b/reactos/w32api/include/imagehlp.h @@ -75,7 +75,19 @@ extern "C" { #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 @@ -241,79 +253,79 @@ typedef struct _IMAGEHLP_DUPLICATE_SYMBOL { 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 */ diff --git a/reactos/w32api/include/winnt.h b/reactos/w32api/include/winnt.h index 0109bdb3fa8..08281be6780 100644 --- a/reactos/w32api/include/winnt.h +++ b/reactos/w32api/include/winnt.h @@ -952,6 +952,11 @@ typedef enum #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