Move code around files to be more like Wine. No code change.

svn path=/trunk/; revision=23504
This commit is contained in:
Hervé Poussineau 2006-08-06 18:37:39 +00:00
parent 918b7c6c45
commit 887690f26d
5 changed files with 833 additions and 813 deletions

View file

@ -15,125 +15,44 @@
* *
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
/* INCLUDES ******************************************************************/
#include "precomp.h" #include "precomp.h"
//#define NDEBUG //#define NDEBUG
#include <debug.h> #include <debug.h>
#define _WINNT_H
#include "wine/debug.h"
/* DATA **********************************************************************/ WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
/***********************************************************************
* Data
*/
BOOLEAN DllListInitialized; BOOLEAN DllListInitialized;
LIST_ENTRY ImageLoadListHead; LIST_ENTRY ImageLoadListHead;
/* FUNCTIONS *****************************************************************/ /***********************************************************************
* GetImageConfigInformation (IMAGEHLP.@)
PVOID
IMAGEAPI
ImageDirectoryEntryToData32(PVOID Base,
BOOLEAN MappedAsImage,
USHORT DirectoryEntry,
PULONG Size,
PIMAGE_SECTION_HEADER *FoundHeader OPTIONAL,
PIMAGE_FILE_HEADER FileHeader,
PIMAGE_OPTIONAL_HEADER OptionalHeader)
{
ULONG i;
PIMAGE_SECTION_HEADER CurrentSection;
ULONG DirectoryEntryVA;
/* Check if this entry is invalid */
if (DirectoryEntry >= OptionalHeader->NumberOfRvaAndSizes)
{
/* Nothing found */
*Size = 0;
return NULL;
}
/* Get the VA of the Directory Requested */
DirectoryEntryVA = OptionalHeader->DataDirectory[DirectoryEntry].VirtualAddress;
if (!DirectoryEntryVA)
{
/* It doesn't exist */
*Size = 0;
return NULL;
}
/* Get the size of the Directory Requested */
*Size = OptionalHeader->DataDirectory[DirectoryEntry].Size;
/* Check if it was mapped as an image or if the entry is within the headers */
if ((MappedAsImage) || (DirectoryEntryVA < OptionalHeader->SizeOfHeaders))
{
/* No header found */
if (FoundHeader) *FoundHeader = NULL;
/* And simply return the VA */
return (PVOID)((ULONG_PTR)Base + DirectoryEntryVA);
}
/* Read the first Section */
CurrentSection = (PIMAGE_SECTION_HEADER)((ULONG_PTR)OptionalHeader +
FileHeader->SizeOfOptionalHeader);
/* Loop through every section*/
for (i = 0; i < FileHeader->NumberOfSections; i++)
{
/* If the Directory VA is located inside this section's VA, then this section belongs to this Directory */
if ((DirectoryEntryVA >= CurrentSection->VirtualAddress) &&
(DirectoryEntryVA < (CurrentSection->VirtualAddress +
CurrentSection->SizeOfRawData)))
{
/* Return the section header */
if (FoundHeader) *FoundHeader = CurrentSection;
return ((PVOID)((ULONG_PTR)Base +
(DirectoryEntryVA - CurrentSection->VirtualAddress) +
CurrentSection->PointerToRawData));
}
/* Move to the next section */
CurrentSection++;
}
/* If we got here, then we didn't find anything */
return NULL;
}
/*
* @unimplemented
*/ */
DWORD BOOL IMAGEAPI GetImageConfigInformation(
IMAGEAPI PLOADED_IMAGE LoadedImage,
GetTimestampForLoadedLibrary(HMODULE Module)
{
UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
BOOL
IMAGEAPI
GetImageConfigInformation(PLOADED_IMAGE LoadedImage,
PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation) PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation)
{ {
UNIMPLEMENTED; FIXME("(%p, %p): stub\n",
LoadedImage, ImageConfigInformation
);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE; return FALSE;
} }
/* /***********************************************************************
* @implemented * GetImageUnusedHeaderBytes (IMAGEHLP.@)
*/ */
DWORD DWORD IMAGEAPI GetImageUnusedHeaderBytes(
IMAGEAPI PLOADED_IMAGE LoadedImage,
GetImageUnusedHeaderBytes(PLOADED_IMAGE LoadedImage,
LPDWORD SizeUnusedHeaderBytes) LPDWORD SizeUnusedHeaderBytes)
{ {
SIZE_T FirstFreeByte; SIZE_T FirstFreeByte;
@ -182,61 +101,10 @@ GetImageUnusedHeaderBytes(PLOADED_IMAGE LoadedImage,
return (DWORD)FirstFreeByte; return (DWORD)FirstFreeByte;
} }
/* /***********************************************************************
* @implemented * ImageLoad (IMAGEHLP.@)
*/ */
PVOID PLOADED_IMAGE IMAGEAPI ImageLoad(LPSTR DllName, LPSTR DllPath)
IMAGEAPI
ImageDirectoryEntryToData(PVOID Base,
BOOLEAN MappedAsImage,
USHORT DirectoryEntry,
PULONG Size)
{
/* Let the extended function handle it */
return ImageDirectoryEntryToDataEx(Base,
MappedAsImage,
DirectoryEntry,
Size,
NULL);
}
/*
* @implemented
*/
PVOID
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;
/* Get the optional header ourselves */
NtHeader = ImageNtHeader(Base);
FileHeader = &NtHeader->FileHeader;
OptionalHeader = &NtHeader->OptionalHeader;
/* FIXME: Read image type and call appropriate function (32, 64, ROM) */
return ImageDirectoryEntryToData32(Base,
MappedAsImage,
DirectoryEntry,
Size,
FoundSection,
FileHeader,
OptionalHeader);
}
/*
* @implemented
*/
PLOADED_IMAGE
IMAGEAPI
ImageLoad(LPSTR DllName,
LPSTR DllPath)
{ {
PLIST_ENTRY Head, Next; PLIST_ENTRY Head, Next;
PLOADED_IMAGE LoadedImage; PLOADED_IMAGE LoadedImage;
@ -324,6 +192,353 @@ ImageLoad(LPSTR DllName,
return LoadedImage; return LoadedImage;
} }
/***********************************************************************
* ImageUnload (IMAGEHLP.@)
*/
BOOL IMAGEAPI ImageUnload(PLOADED_IMAGE pLoadedImage)
{
/* If the image list isn't empty, remove this entry */
if (!IsListEmpty(&pLoadedImage->Links)) RemoveEntryList(&pLoadedImage->Links);
/* Unmap and unload it */
UnMapAndLoad(pLoadedImage);
/* Free the structure */
HeapFree(IMAGEHLP_hHeap, 0, pLoadedImage);
/* Return success */
return TRUE;
}
/***********************************************************************
* MapAndLoad (IMAGEHLP.@)
*/
BOOL IMAGEAPI MapAndLoad(
LPSTR ImageName, LPSTR DllPath, PLOADED_IMAGE pLoadedImage,
BOOL DotDll, BOOL ReadOnly)
{
HANDLE hFile;
HANDLE hFileMapping;
ULONG Tried = 0;
UCHAR Buffer[MAX_PATH];
LPSTR FilePart;
LPSTR FileToOpen;
PIMAGE_NT_HEADERS NtHeader;
/* So we can add the DLL Path later */
FileToOpen = ImageName;
/* Assume failure */
pLoadedImage->hFile = INVALID_HANDLE_VALUE;
/* Start open loop */
while (TRUE)
{
/* 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;
}
/* 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;
}
/* Get a pointer to the file */
pLoadedImage->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 */
pLoadedImage->SizeOfImage = GetFileSize(hFile, NULL);
/* Get the Nt Header */
NtHeader = ImageNtHeader(pLoadedImage->MappedAddress);
/* Allocate memory for the name and save it */
pLoadedImage->ModuleName = HeapAlloc(IMAGEHLP_hHeap,
0,
strlen(FileToOpen) + 16);
strcpy(pLoadedImage->ModuleName, FileToOpen);
/* Save the NT Header */
pLoadedImage->FileHeader = NtHeader;
/* Save the section data */
pLoadedImage->Sections = IMAGE_FIRST_SECTION(NtHeader);
pLoadedImage->NumberOfSections = NtHeader->FileHeader.NumberOfSections;
/* Setup other data */
pLoadedImage->SizeOfImage = NtHeader->OptionalHeader.SizeOfImage;
pLoadedImage->Characteristics = NtHeader->FileHeader.Characteristics;
pLoadedImage->LastRvaSection = pLoadedImage->Sections;
pLoadedImage->fSystemImage = FALSE; /* FIXME */
pLoadedImage->fDOSImage = FALSE; /* FIXME */
InitializeListHead(&pLoadedImage->Links);
/* Check if it was read-only */
if (ReadOnly)
{
/* It was, so close our handle and write it as invalid */
CloseHandle(hFile);
pLoadedImage->hFile = INVALID_HANDLE_VALUE;
}
else
{
/* Write our file handle */
pLoadedImage->hFile = hFile;
}
/* Return Success */
return TRUE;
}
/***********************************************************************
* SetImageConfigInformation (IMAGEHLP.@)
*/
BOOL IMAGEAPI SetImageConfigInformation(
PLOADED_IMAGE LoadedImage,
PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation)
{
FIXME("(%p, %p): stub\n",
LoadedImage, ImageConfigInformation
);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/***********************************************************************
* UnMapAndLoad (IMAGEHLP.@)
*/
BOOL IMAGEAPI UnMapAndLoad(PLOADED_IMAGE Image)
{
PIMAGE_NT_HEADERS NtHeader;
DWORD HeaderCheckSum, CheckSum;
/* Check if the image was read-only */
if (Image->hFile == INVALID_HANDLE_VALUE)
{
/* We'll only unmap the view */
UnmapViewOfFile(Image->MappedAddress);
}
else
{
/* Calculate the checksum */
CheckSumMappedFile(Image->MappedAddress,
Image->SizeOfImage,
&HeaderCheckSum,
&CheckSum);
/* Get the NT Header */
NtHeader = Image->FileHeader;
/* Write the new checksum to it */
NtHeader->OptionalHeader.CheckSum = CheckSum;
/* Now flush and unmap the image */
FlushViewOfFile(Image->MappedAddress, Image->SizeOfImage);
UnmapViewOfFile(Image->MappedAddress);
/* Check if the size changed */
if (Image->SizeOfImage != GetFileSize(Image->hFile, NULL))
{
/* Update the file pointer */
SetFilePointer(Image->hFile, Image->SizeOfImage, NULL, FILE_BEGIN);
SetEndOfFile(Image->hFile);
}
}
/* Check if the image had a valid handle, and close it */
if (Image->hFile != INVALID_HANDLE_VALUE) CloseHandle(Image->hFile);
/* Return success */
return TRUE;
}
PVOID
IMAGEAPI
ImageDirectoryEntryToData32(PVOID Base,
BOOLEAN MappedAsImage,
USHORT DirectoryEntry,
PULONG Size,
PIMAGE_SECTION_HEADER *FoundHeader OPTIONAL,
PIMAGE_FILE_HEADER FileHeader,
PIMAGE_OPTIONAL_HEADER OptionalHeader)
{
ULONG i;
PIMAGE_SECTION_HEADER CurrentSection;
ULONG DirectoryEntryVA;
/* Check if this entry is invalid */
if (DirectoryEntry >= OptionalHeader->NumberOfRvaAndSizes)
{
/* Nothing found */
*Size = 0;
return NULL;
}
/* Get the VA of the Directory Requested */
DirectoryEntryVA = OptionalHeader->DataDirectory[DirectoryEntry].VirtualAddress;
if (!DirectoryEntryVA)
{
/* It doesn't exist */
*Size = 0;
return NULL;
}
/* Get the size of the Directory Requested */
*Size = OptionalHeader->DataDirectory[DirectoryEntry].Size;
/* Check if it was mapped as an image or if the entry is within the headers */
if ((MappedAsImage) || (DirectoryEntryVA < OptionalHeader->SizeOfHeaders))
{
/* No header found */
if (FoundHeader) *FoundHeader = NULL;
/* And simply return the VA */
return (PVOID)((ULONG_PTR)Base + DirectoryEntryVA);
}
/* Read the first Section */
CurrentSection = (PIMAGE_SECTION_HEADER)((ULONG_PTR)OptionalHeader +
FileHeader->SizeOfOptionalHeader);
/* Loop through every section*/
for (i = 0; i < FileHeader->NumberOfSections; i++)
{
/* If the Directory VA is located inside this section's VA, then this section belongs to this Directory */
if ((DirectoryEntryVA >= CurrentSection->VirtualAddress) &&
(DirectoryEntryVA < (CurrentSection->VirtualAddress +
CurrentSection->SizeOfRawData)))
{
/* Return the section header */
if (FoundHeader) *FoundHeader = CurrentSection;
return ((PVOID)((ULONG_PTR)Base +
(DirectoryEntryVA - CurrentSection->VirtualAddress) +
CurrentSection->PointerToRawData));
}
/* Move to the next section */
CurrentSection++;
}
/* If we got here, then we didn't find anything */
return NULL;
}
/*
* @unimplemented
*/
DWORD
IMAGEAPI
GetTimestampForLoadedLibrary(HMODULE Module)
{
UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @implemented
*/
PVOID
IMAGEAPI
ImageDirectoryEntryToData(PVOID Base,
BOOLEAN MappedAsImage,
USHORT DirectoryEntry,
PULONG Size)
{
/* Let the extended function handle it */
return ImageDirectoryEntryToDataEx(Base,
MappedAsImage,
DirectoryEntry,
Size,
NULL);
}
/*
* @implemented
*/
PVOID
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;
/* Get the optional header ourselves */
NtHeader = ImageNtHeader(Base);
FileHeader = &NtHeader->FileHeader;
OptionalHeader = &NtHeader->OptionalHeader;
/* FIXME: Read image type and call appropriate function (32, 64, ROM) */
return ImageDirectoryEntryToData32(Base,
MappedAsImage,
DirectoryEntry,
Size,
FoundSection,
FileHeader,
OptionalHeader);
}
/* /*
* @implemented * @implemented
*/ */
@ -392,229 +607,6 @@ ImageRvaToVa(IN PIMAGE_NT_HEADERS NtHeaders,
Section->PointerToRawData); Section->PointerToRawData);
} }
/*
* @implemented
*/
BOOL
IMAGEAPI
ImageUnload(PLOADED_IMAGE LoadedImage)
{
/* If the image list isn't empty, remove this entry */
if (!IsListEmpty(&LoadedImage->Links)) RemoveEntryList(&LoadedImage->Links);
/* Unmap and unload it */
UnMapAndLoad(LoadedImage);
/* Free the structure */
HeapFree(IMAGEHLP_hHeap, 0, LoadedImage);
/* Return success */
return TRUE;
}
/*
* @implemented
*/
BOOL
IMAGEAPI
MapAndLoad(LPSTR ImageName,
LPSTR DllPath,
PLOADED_IMAGE LoadedImage,
BOOL DotDll,
BOOL ReadOnly)
{
HANDLE hFile;
HANDLE hFileMapping;
ULONG Tried = 0;
UCHAR Buffer[MAX_PATH];
LPSTR FilePart;
LPSTR FileToOpen;
PIMAGE_NT_HEADERS NtHeader;
/* So we can add the DLL Path later */
FileToOpen = ImageName;
/* Assume failure */
LoadedImage->hFile = INVALID_HANDLE_VALUE;
/* Start open loop */
while (TRUE)
{
/* 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;
}
/* 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;
}
/* Get a pointer to the file */
LoadedImage->MappedAddress = MapViewOfFile(hFileMapping,
ReadOnly ? FILE_MAP_READ :
FILE_MAP_WRITE,
0,
0,
0);
/* Close the handle to the map, we don't need it anymore */
CloseHandle(hFileMapping);
/* Write the image size */
LoadedImage->SizeOfImage = GetFileSize(hFile, NULL);
/* Get the Nt Header */
NtHeader = ImageNtHeader(LoadedImage->MappedAddress);
/* Allocate memory for the name and save it */
LoadedImage->ModuleName = HeapAlloc(IMAGEHLP_hHeap,
0,
strlen(FileToOpen) + 16);
strcpy(LoadedImage->ModuleName, FileToOpen);
/* Save the NT Header */
LoadedImage->FileHeader = NtHeader;
/* Save the section data */
LoadedImage->Sections = IMAGE_FIRST_SECTION(NtHeader);
LoadedImage->NumberOfSections = NtHeader->FileHeader.NumberOfSections;
/* Setup other data */
LoadedImage->SizeOfImage = NtHeader->OptionalHeader.SizeOfImage;
LoadedImage->Characteristics = NtHeader->FileHeader.Characteristics;
LoadedImage->LastRvaSection = LoadedImage->Sections;
LoadedImage->fSystemImage = FALSE; /* FIXME */
LoadedImage->fDOSImage = FALSE; /* FIXME */
InitializeListHead(&LoadedImage->Links);
/* Check if it was read-only */
if (ReadOnly)
{
/* It was, so close our handle and write it as invalid */
CloseHandle(hFile);
LoadedImage->hFile = INVALID_HANDLE_VALUE;
}
else
{
/* Write our file handle */
LoadedImage->hFile = hFile;
}
/* 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)
{
/* We'll only unmap the view */
UnmapViewOfFile(Image->MappedAddress);
}
else
{
/* Calculate the checksum */
CheckSumMappedFile(Image->MappedAddress,
Image->SizeOfImage,
&HeaderCheckSum,
&CheckSum);
/* Get the NT Header */
NtHeader = Image->FileHeader;
/* Write the new checksum to it */
NtHeader->OptionalHeader.CheckSum = CheckSum;
/* Now flush and unmap the image */
FlushViewOfFile(Image->MappedAddress, Image->SizeOfImage);
UnmapViewOfFile(Image->MappedAddress);
/* Check if the size changed */
if (Image->SizeOfImage != GetFileSize(Image->hFile, NULL))
{
/* Update the file pointer */
SetFilePointer(Image->hFile, Image->SizeOfImage, NULL, FILE_BEGIN);
SetEndOfFile(Image->hFile);
}
}
/* Check if the image had a valid handle, and close it */
if (Image->hFile != INVALID_HANDLE_VALUE) CloseHandle(Image->hFile);
/* Return success */
return TRUE;
}
BOOL BOOL
IMAGEAPI IMAGEAPI
UnloadAllImages(VOID) UnloadAllImages(VOID)

View file

@ -5,6 +5,7 @@
<define name="_WIN32_WINNT">0x600</define> <define name="_WIN32_WINNT">0x600</define>
<define name="WINVER">0x0600</define> <define name="WINVER">0x0600</define>
<define name="_IMAGEHLP_SOURCE_"></define> <define name="_IMAGEHLP_SOURCE_"></define>
<library>wine</library>
<library>ntdll</library> <library>ntdll</library>
<library>kernel32</library> <library>kernel32</library>
<file>access.c</file> <file>access.c</file>

View file

@ -15,28 +15,29 @@
* *
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/
#include "precomp.h" #include "precomp.h"
//#define NDEBUG //#define NDEBUG
#include <debug.h> #include <debug.h>
#define _WINNT_H
#include "wine/debug.h"
/* DATA **********************************************************************/ WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
/**********************************************************************/
HANDLE IMAGEHLP_hHeap = NULL; HANDLE IMAGEHLP_hHeap = NULL;
/* FUNCTIONS *****************************************************************/ /***********************************************************************
* DllMain (IMAGEHLP.init)
BOOL */
IMAGEAPI BOOL IMAGEAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
DllMain(HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved)
{ {
switch(fdwReason) switch(fdwReason)
{ {
@ -51,6 +52,5 @@ DllMain(HINSTANCE hinstDLL,
default: default:
break; break;
} }
return TRUE; return TRUE;
} }

View file

@ -16,7 +16,7 @@
* *
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
/* /*
@ -30,6 +30,10 @@
//#define NDEBUG //#define NDEBUG
#include <debug.h> #include <debug.h>
#define _WINNT_H
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
@ -44,7 +48,8 @@ IMAGEHLP_GetSecurityDirOffset(HANDLE handle,
DWORD count; DWORD count;
BOOL r; BOOL r;
IMAGE_DATA_DIRECTORY *sd; IMAGE_DATA_DIRECTORY *sd;
DPRINT("handle %p\n", handle );
TRACE("handle %p\n", handle );
/* read the DOS header */ /* read the DOS header */
count = SetFilePointer( handle, 0, NULL, FILE_BEGIN ); count = SetFilePointer( handle, 0, NULL, FILE_BEGIN );
@ -71,19 +76,21 @@ IMAGEHLP_GetSecurityDirOffset(HANDLE handle,
sd = &nt_hdr.OptionalHeader. sd = &nt_hdr.OptionalHeader.
DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY]; DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY];
DPRINT("size = %lx addr = %lx\n", sd->Size, sd->VirtualAddress); TRACE("size = %lx addr = %lx\n", sd->Size, sd->VirtualAddress);
*pdwSize = sd->Size; *pdwSize = sd->Size;
*pdwOfs = sd->VirtualAddress; *pdwOfs = sd->VirtualAddress;
return TRUE; return TRUE;
} }
static /***********************************************************************
BOOL * IMAGEHLP_GetCertificateOffset (INTERNAL)
IMAGEHLP_GetCertificateOffset(HANDLE handle, *
DWORD num, * Read a file's PE header, and return the offset and size of the
DWORD *pdwOfs, * security directory.
DWORD *pdwSize) */
static BOOL IMAGEHLP_GetCertificateOffset( HANDLE handle, DWORD num,
DWORD *pdwOfs, DWORD *pdwSize )
{ {
DWORD size, count, offset, len, sd_VirtualAddr; DWORD size, count, offset, len, sd_VirtualAddr;
BOOL r; BOOL r;
@ -124,7 +131,8 @@ IMAGEHLP_GetCertificateOffset(HANDLE handle,
*pdwOfs = sd_VirtualAddr + offset; *pdwOfs = sd_VirtualAddr + offset;
*pdwSize = len; *pdwSize = len;
DPRINT("len = %lx addr = %lx\n", len, sd_VirtualAddr + offset); TRACE("len = %lx addr = %lx\n", len, sd_VirtualAddr + offset);
return TRUE; return TRUE;
} }
@ -167,28 +175,24 @@ ImageAddCertificate(HANDLE FileHandle,
return FALSE; return FALSE;
} }
/* /***********************************************************************
* @unimplemented * ImageEnumerateCertificates (IMAGEHLP.@)
*/ */
BOOL BOOL IMAGEAPI ImageEnumerateCertificates(
IMAGEAPI HANDLE FileHandle, WORD TypeFilter, PDWORD CertificateCount,
ImageEnumerateCertificates(HANDLE FileHandle, PDWORD Indices, DWORD IndexCount)
WORD TypeFilter,
PDWORD CertificateCount,
PDWORD Indices,
DWORD IndexCount)
{ {
DWORD size, count, offset, sd_VirtualAddr; DWORD size, count, offset, sd_VirtualAddr;
WIN_CERTIFICATE hdr; WIN_CERTIFICATE hdr;
const size_t cert_hdr_size = sizeof hdr - sizeof hdr.bCertificate; const size_t cert_hdr_size = sizeof hdr - sizeof hdr.bCertificate;
BOOL r; BOOL r;
DPRINT("%p %hd %p %p %ld\n", TRACE("%p %hd %p %p %ld\n",
FileHandle, TypeFilter, CertificateCount, Indices, IndexCount); FileHandle, TypeFilter, CertificateCount, Indices, IndexCount);
if( Indices ) if( Indices )
{ {
DPRINT1("Indicies not FileHandled!\n"); FIXME("Indicies not handled!\n");
return FALSE; return FALSE;
} }
@ -211,7 +215,8 @@ ImageEnumerateCertificates(HANDLE FileHandle,
if( count != cert_hdr_size ) if( count != cert_hdr_size )
return FALSE; return FALSE;
DPRINT("Size = %08lx id = %08hx\n", hdr.dwLength, hdr.wCertificateType ); TRACE("Size = %08lx id = %08hx\n",
hdr.dwLength, hdr.wCertificateType );
/* check the certificate is not too big or too small */ /* check the certificate is not too big or too small */
if( hdr.dwLength < cert_hdr_size ) if( hdr.dwLength < cert_hdr_size )
@ -232,18 +237,18 @@ ImageEnumerateCertificates(HANDLE FileHandle,
return TRUE; return TRUE;
} }
/* /***********************************************************************
* @implemented * ImageGetCertificateData (IMAGEHLP.@)
*
* FIXME: not sure that I'm dealing with the Index the right way
*/ */
BOOL BOOL IMAGEAPI ImageGetCertificateData(
IMAGEAPI HANDLE handle, DWORD Index,
ImageGetCertificateData(HANDLE handle, LPWIN_CERTIFICATE Certificate, PDWORD RequiredLength)
DWORD Index,
LPWIN_CERTIFICATE Certificate,
PDWORD RequiredLength)
{ {
DWORD r, offset, ofs, size, count; 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_GetCertificateOffset( handle, Index, &ofs, &size ) ) if( !IMAGEHLP_GetCertificateOffset( handle, Index, &ofs, &size ) )
return FALSE; return FALSE;
@ -273,18 +278,16 @@ ImageGetCertificateData(HANDLE handle,
if( count != size ) if( count != size )
return FALSE; return FALSE;
DPRINT("OK\n"); TRACE("OK\n");
return TRUE; return TRUE;
} }
/* /***********************************************************************
* @unimplemented * ImageGetCertificateHeader (IMAGEHLP.@)
*/ */
BOOL BOOL IMAGEAPI ImageGetCertificateHeader(
IMAGEAPI HANDLE FileHandle, DWORD CertificateIndex, LPWIN_CERTIFICATE Certificateheader)
ImageGetCertificateHeader(HANDLE FileHandle,
DWORD CertificateIndex,
LPWIN_CERTIFICATE Certificateheader)
{ {
DWORD r, offset, ofs, size, count; DWORD r, offset, ofs, size, count;
const size_t cert_hdr_size = sizeof *Certificateheader - const size_t cert_hdr_size = sizeof *Certificateheader -
@ -308,34 +311,31 @@ ImageGetCertificateHeader(HANDLE FileHandle,
if( count != cert_hdr_size ) if( count != cert_hdr_size )
return FALSE; return FALSE;
DPRINT("OK\n"); TRACE("OK\n");
return TRUE; return TRUE;
} }
/* /***********************************************************************
* @unimplemented * ImageGetDigestStream (IMAGEHLP.@)
*/ */
BOOL BOOL IMAGEAPI ImageGetDigestStream(
IMAGEAPI HANDLE FileHandle, DWORD DigestLevel,
ImageGetDigestStream(HANDLE FileHandle, DIGEST_FUNCTION DigestFunction, DIGEST_HANDLE DigestHandle)
DWORD DigestLevel,
DIGEST_FUNCTION DigestFunction,
DIGEST_HANDLE DigestHandle)
{ {
UNIMPLEMENTED; FIXME("(%p, %ld, %p, %p): stub\n",
FileHandle, DigestLevel, DigestFunction, DigestHandle
);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE; return FALSE;
} }
/* /***********************************************************************
* @unimplemented * ImageRemoveCertificate (IMAGEHLP.@)
*/ */
BOOL BOOL IMAGEAPI ImageRemoveCertificate(HANDLE FileHandle, DWORD Index)
IMAGEAPI
ImageRemoveCertificate(HANDLE FileHandle,
DWORD Index)
{ {
UNIMPLEMENTED; FIXME("(%p, %ld): stub\n", FileHandle, Index);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE; return FALSE;
} }
@ -392,137 +392,3 @@ CheckSumMappedFile(LPVOID BaseAddress,
return Header; 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;
}

View file

@ -16,24 +16,33 @@
* *
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
/* INCLUDES ******************************************************************/
#include "precomp.h" #include "precomp.h"
//#define NDEBUG //#define NDEBUG
#include <debug.h> #include <debug.h>
#define _WINNT_H
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
/* DATA **********************************************************************/ /* DATA **********************************************************************/
CHAR BoundLibraries[4096]; CHAR BoundLibraries[4096];
LPSTR BoundLibrariesPointer; LPSTR BoundLibrariesPointer;
/* FUNCTIONS *****************************************************************/ /***********************************************************************
* BindImage (IMAGEHLP.@)
*/
BOOL WINAPI BindImage(
LPSTR ImageName, LPSTR DllPath, LPSTR SymbolPath)
{
return BindImageEx(0, ImageName, DllPath, SymbolPath, NULL);
}
LPSTR static LPSTR
IMAGEAPI IMAGEAPI
BindpCaptureImportModuleName(LPSTR ModuleName) BindpCaptureImportModuleName(LPSTR ModuleName)
{ {
@ -68,128 +77,46 @@ BindpCaptureImportModuleName(LPSTR ModuleName)
return Name; return Name;
} }
PIMAGE_BOUND_IMPORT_DESCRIPTOR
static PIMPORT_DESCRIPTOR
IMAGEAPI IMAGEAPI
BindpCreateNewImportSection(PIMPORT_DESCRIPTOR *BoundImportDescriptor, BindpAddImportDescriptor(PIMPORT_DESCRIPTOR *BoundImportDescriptor,
PULONG BoundImportsSize) PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor,
LPSTR DllName,
PLOADED_IMAGE Image)
{ {
ULONG BoundLibraryNamesSize = 0, BoundImportTableSize = 0;
PBOUND_FORWARDER_REFS Forwarder, *NextForwarder;
PIMPORT_DESCRIPTOR Descriptor, *NextDescriptor; PIMPORT_DESCRIPTOR Descriptor, *NextDescriptor;
LPSTR BoundLibraryNames;
PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundTableEntry, BoundTable;
PIMAGE_BOUND_FORWARDER_REF BoundForwarder;
/* Zero the outoging size */ /* Loop descriptors and check if this library has already been bound */
*BoundImportsSize = 0;
/* Loop the descriptors and forwarders to get the size */
NextDescriptor = BoundImportDescriptor; NextDescriptor = BoundImportDescriptor;
while ((Descriptor = *NextDescriptor)) while ((Descriptor = *NextDescriptor))
{ {
/* Add to the size of the Bound Import Table */ /* Compare the names and return the descriptor if found */
BoundImportTableSize += sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR); if (!_stricmp(Descriptor->ModuleName, DllName)) return Descriptor;
/* Check Forwarders */ /* Move to the next one */
NextForwarder = &Descriptor->Forwarders;
while ((Forwarder = *NextForwarder))
{
/* Add to size of Bound Import Table */
BoundImportTableSize += sizeof(IMAGE_BOUND_FORWARDER_REF);
/* Next Forwarder */
NextForwarder = &Forwarder->Next;
}
/* Read Next Internal Descriptor */
NextDescriptor = &Descriptor->Next; NextDescriptor = &Descriptor->Next;
} }
/* Add Terminator for PE Loader*/ /* Allocate a new descriptor */
BoundImportTableSize += sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR); Descriptor = HeapAlloc(IMAGEHLP_hHeap,
DPRINT("Table size: %lx\n", BoundImportTableSize); HEAP_ZERO_MEMORY,
sizeof(IMPORT_DESCRIPTOR));
/* Name of Libraries Bound in Bound Import Table */ /* Set its Data and check if we have a valid loaded image */
BoundLibraryNamesSize = (ULONG)((ULONG_PTR)BoundLibrariesPointer - Descriptor->ModuleName = BindpCaptureImportModuleName(DllName);
(ULONG_PTR)BoundLibraries); *NextDescriptor = Descriptor;
BoundLibrariesPointer = NULL; if (Image)
/* Size of the whole table, dword aligned */
*BoundImportsSize = BoundImportTableSize +
((BoundLibraryNamesSize + sizeof(ULONG) - 1) &
~(sizeof(ULONG) - 1));
/* Allocate it */
BoundTable = HeapAlloc(IMAGEHLP_hHeap, HEAP_ZERO_MEMORY, *BoundImportsSize);
/* Pointer Library Names inside the Bound Import Table */
BoundLibraryNames = (LPSTR)BoundTable + BoundImportTableSize;
/* Copy the Library Names */
RtlCopyMemory(BoundLibraryNames, BoundLibraries, BoundLibraryNamesSize);
/* Now loop both tables */
BoundTableEntry = BoundTable;
NextDescriptor = BoundImportDescriptor;
while ((Descriptor = *NextDescriptor))
{ {
/* Copy the data */ /* Save the time stamp */
BoundTableEntry->TimeDateStamp = Descriptor->TimeDateStamp; Descriptor->TimeDateStamp = Image->FileHeader->FileHeader.TimeDateStamp;
BoundTableEntry->OffsetModuleName = (USHORT)(BoundImportTableSize +
(Descriptor->ModuleName -
(ULONG_PTR)BoundLibraries));
BoundTableEntry->NumberOfModuleForwarderRefs = Descriptor->ForwaderReferences;
/* Now loop the forwarders */
BoundForwarder = (PIMAGE_BOUND_FORWARDER_REF)BoundTableEntry + 1;
NextForwarder = &Descriptor->Forwarders;
while ((Forwarder = *NextForwarder))
{
/* Copy the data */
BoundForwarder->TimeDateStamp = Forwarder->TimeDateStamp;
BoundForwarder->OffsetModuleName = (USHORT)(BoundImportTableSize +
(Forwarder->ModuleName -
(ULONG_PTR)BoundLibraries));
/* Move to the next new forwarder, and move to the next entry */
BoundForwarder++;
NextForwarder = &Forwarder->Next;
} }
/* Move to next Bound Import Table Entry */ /* Return the descriptor */
BoundTableEntry = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)BoundForwarder; return Descriptor;
/* Move to the next descriptor */
NextDescriptor = &Descriptor->Next;
} }
/* Loop the descriptors and forwarders to free them */ static PCHAR
NextDescriptor = BoundImportDescriptor;
while ((Descriptor = *NextDescriptor))
{
/* Read next internal descriptor */
*NextDescriptor = Descriptor->Next;
/* Loop its forwarders */
NextForwarder = &Descriptor->Forwarders;
while ((Forwarder = *NextForwarder))
{
/* Next Forwarder */
*NextForwarder = Forwarder->Next;
/* Free it */
HeapFree(IMAGEHLP_hHeap, 0, Forwarder);
}
/* Free it */
HeapFree(IMAGEHLP_hHeap, 0, Descriptor);
}
/* Return the Bound Import Table */
return BoundTable;
}
PCHAR
IMAGEAPI IMAGEAPI
BindpAddForwarderReference(LPSTR ModuleName, BindpAddForwarderReference(LPSTR ModuleName,
LPSTR ImportName, LPSTR ImportName,
@ -370,7 +297,7 @@ NextForwarder:
return ForwarderString; return ForwarderString;
} }
BOOL static BOOL
IMAGEAPI IMAGEAPI
BindpLookupThunk(PIMAGE_THUNK_DATA Thunk, BindpLookupThunk(PIMAGE_THUNK_DATA Thunk,
PLOADED_IMAGE Image, PLOADED_IMAGE Image,
@ -527,45 +454,128 @@ BindpLookupThunk(PIMAGE_THUNK_DATA Thunk,
return TRUE; return TRUE;
} }
PIMPORT_DESCRIPTOR static PIMAGE_BOUND_IMPORT_DESCRIPTOR
IMAGEAPI IMAGEAPI
BindpAddImportDescriptor(PIMPORT_DESCRIPTOR *BoundImportDescriptor, BindpCreateNewImportSection(PIMPORT_DESCRIPTOR *BoundImportDescriptor,
PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor, PULONG BoundImportsSize)
LPSTR DllName,
PLOADED_IMAGE Image)
{ {
ULONG BoundLibraryNamesSize = 0, BoundImportTableSize = 0;
PBOUND_FORWARDER_REFS Forwarder, *NextForwarder;
PIMPORT_DESCRIPTOR Descriptor, *NextDescriptor; PIMPORT_DESCRIPTOR Descriptor, *NextDescriptor;
LPSTR BoundLibraryNames;
PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundTableEntry, BoundTable;
PIMAGE_BOUND_FORWARDER_REF BoundForwarder;
/* Loop descriptors and check if this library has already been bound */ /* Zero the outoging size */
*BoundImportsSize = 0;
/* Loop the descriptors and forwarders to get the size */
NextDescriptor = BoundImportDescriptor; NextDescriptor = BoundImportDescriptor;
while ((Descriptor = *NextDescriptor)) while ((Descriptor = *NextDescriptor))
{ {
/* Compare the names and return the descriptor if found */ /* Add to the size of the Bound Import Table */
if (!_stricmp(Descriptor->ModuleName, DllName)) return Descriptor; BoundImportTableSize += sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR);
/* Move to the next one */ /* Check Forwarders */
NextForwarder = &Descriptor->Forwarders;
while ((Forwarder = *NextForwarder))
{
/* Add to size of Bound Import Table */
BoundImportTableSize += sizeof(IMAGE_BOUND_FORWARDER_REF);
/* Next Forwarder */
NextForwarder = &Forwarder->Next;
}
/* Read Next Internal Descriptor */
NextDescriptor = &Descriptor->Next; NextDescriptor = &Descriptor->Next;
} }
/* Allocate a new descriptor */ /* Add Terminator for PE Loader*/
Descriptor = HeapAlloc(IMAGEHLP_hHeap, BoundImportTableSize += sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR);
HEAP_ZERO_MEMORY, DPRINT("Table size: %lx\n", BoundImportTableSize);
sizeof(IMPORT_DESCRIPTOR));
/* Set its Data and check if we have a valid loaded image */ /* Name of Libraries Bound in Bound Import Table */
Descriptor->ModuleName = BindpCaptureImportModuleName(DllName); BoundLibraryNamesSize = (ULONG)((ULONG_PTR)BoundLibrariesPointer -
*NextDescriptor = Descriptor; (ULONG_PTR)BoundLibraries);
if (Image) BoundLibrariesPointer = NULL;
/* Size of the whole table, dword aligned */
*BoundImportsSize = BoundImportTableSize +
((BoundLibraryNamesSize + sizeof(ULONG) - 1) &
~(sizeof(ULONG) - 1));
/* Allocate it */
BoundTable = HeapAlloc(IMAGEHLP_hHeap, HEAP_ZERO_MEMORY, *BoundImportsSize);
/* Pointer Library Names inside the Bound Import Table */
BoundLibraryNames = (LPSTR)BoundTable + BoundImportTableSize;
/* Copy the Library Names */
RtlCopyMemory(BoundLibraryNames, BoundLibraries, BoundLibraryNamesSize);
/* Now loop both tables */
BoundTableEntry = BoundTable;
NextDescriptor = BoundImportDescriptor;
while ((Descriptor = *NextDescriptor))
{ {
/* Save the time stamp */ /* Copy the data */
Descriptor->TimeDateStamp = Image->FileHeader->FileHeader.TimeDateStamp; BoundTableEntry->TimeDateStamp = Descriptor->TimeDateStamp;
BoundTableEntry->OffsetModuleName = (USHORT)(BoundImportTableSize +
(Descriptor->ModuleName -
(ULONG_PTR)BoundLibraries));
BoundTableEntry->NumberOfModuleForwarderRefs = Descriptor->ForwaderReferences;
/* Now loop the forwarders */
BoundForwarder = (PIMAGE_BOUND_FORWARDER_REF)BoundTableEntry + 1;
NextForwarder = &Descriptor->Forwarders;
while ((Forwarder = *NextForwarder))
{
/* Copy the data */
BoundForwarder->TimeDateStamp = Forwarder->TimeDateStamp;
BoundForwarder->OffsetModuleName = (USHORT)(BoundImportTableSize +
(Forwarder->ModuleName -
(ULONG_PTR)BoundLibraries));
/* Move to the next new forwarder, and move to the next entry */
BoundForwarder++;
NextForwarder = &Forwarder->Next;
} }
/* Return the descriptor */ /* Move to next Bound Import Table Entry */
return Descriptor; BoundTableEntry = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)BoundForwarder;
/* Move to the next descriptor */
NextDescriptor = &Descriptor->Next;
} }
VOID /* Loop the descriptors and forwarders to free them */
NextDescriptor = BoundImportDescriptor;
while ((Descriptor = *NextDescriptor))
{
/* Read next internal descriptor */
*NextDescriptor = Descriptor->Next;
/* Loop its forwarders */
NextForwarder = &Descriptor->Forwarders;
while ((Forwarder = *NextForwarder))
{
/* Next Forwarder */
*NextForwarder = Forwarder->Next;
/* Free it */
HeapFree(IMAGEHLP_hHeap, 0, Forwarder);
}
/* Free it */
HeapFree(IMAGEHLP_hHeap, 0, Descriptor);
}
/* Return the Bound Import Table */
return BoundTable;
}
static VOID
IMAGEAPI IMAGEAPI
BindpWalkAndProcessImports(PLOADED_IMAGE File, BindpWalkAndProcessImports(PLOADED_IMAGE File,
LPSTR DllPath, LPSTR DllPath,
@ -864,16 +874,12 @@ BindpWalkAndProcessImports(PLOADED_IMAGE File,
} }
/* /***********************************************************************
* @implemented * BindImageEx (IMAGEHLP.@)
*/ */
BOOL BOOL IMAGEAPI BindImageEx(
IMAGEAPI DWORD Flags, LPSTR ImageName, LPSTR DllPath, LPSTR SymbolPath,
BindImageEx(IN DWORD Flags, PIMAGEHLP_STATUS_ROUTINE StatusRoutine)
IN LPSTR ImageName,
IN LPSTR DllPath,
IN LPSTR SymbolPath,
IN PIMAGEHLP_STATUS_ROUTINE StatusRoutine)
{ {
LOADED_IMAGE FileData; LOADED_IMAGE FileData;
PLOADED_IMAGE File; PLOADED_IMAGE File;
@ -969,70 +975,7 @@ Skip:
return TRUE; return TRUE;
} }
/* /* FUNCTIONS *****************************************************************/
* @implemented
*/
BOOL
IMAGEAPI
BindImage(LPSTR ImageName,
LPSTR DllPath,
LPSTR SymbolPath)
{
/* Call the newer API */
return BindImageEx(0,
ImageName,
DllPath,
SymbolPath,
NULL);
}
/*
* @unimplemented
*/
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)
{
UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @unimplemented
*/
VOID
IMAGEAPI
RemoveRelocations(PCHAR ImageName)
{
UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
}
/*
* @unimplemented
*/
BOOL
IMAGEAPI
SplitSymbols(LPSTR ImageName,
LPSTR SymbolsPath,
LPSTR SymbolFilePath,
DWORD Flags)
{
UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/* /*
* @implemented * @implemented
@ -1058,3 +1001,221 @@ TouchFileTimes(HANDLE FileHandle,
NULL, NULL,
&FileTime)); &FileTime));
} }
/***********************************************************************
* MapFileAndCheckSumA (IMAGEHLP.@)
*/
DWORD IMAGEAPI 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 IMAGEAPI 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 IMAGEAPI ReBaseImage(
LPSTR CurrentImageName, LPSTR SymbolPath, BOOL fReBase,
BOOL fRebaseSysfileOk, BOOL fGoingDown, ULONG CheckImageSize,
ULONG *OldImageSize, ULONG *OldImageBase, ULONG *NewImageSize,
ULONG *NewImageBase, ULONG TimeStamp)
{
FIXME(
"(%s, %s, %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 IMAGEAPI 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 IMAGEAPI RemoveRelocations(PCHAR ImageName)
{
FIXME("(%p): stub\n", ImageName);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
}
/***********************************************************************
* SplitSymbols (IMAGEHLP.@)
*/
BOOL IMAGEAPI 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 IMAGEAPI 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 IMAGEAPI 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;
}