mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 23:03:00 +00:00
Move code around files to be more like Wine. No code change.
svn path=/trunk/; revision=23504
This commit is contained in:
parent
918b7c6c45
commit
887690f26d
5 changed files with 833 additions and 813 deletions
|
@ -15,126 +15,45 @@
|
||||||
*
|
*
|
||||||
* 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
|
BOOL IMAGEAPI GetImageConfigInformation(
|
||||||
ImageDirectoryEntryToData32(PVOID Base,
|
PLOADED_IMAGE LoadedImage,
|
||||||
BOOLEAN MappedAsImage,
|
PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation)
|
||||||
USHORT DirectoryEntry,
|
|
||||||
PULONG Size,
|
|
||||||
PIMAGE_SECTION_HEADER *FoundHeader OPTIONAL,
|
|
||||||
PIMAGE_FILE_HEADER FileHeader,
|
|
||||||
PIMAGE_OPTIONAL_HEADER OptionalHeader)
|
|
||||||
{
|
{
|
||||||
ULONG i;
|
FIXME("(%p, %p): stub\n",
|
||||||
PIMAGE_SECTION_HEADER CurrentSection;
|
LoadedImage, ImageConfigInformation
|
||||||
ULONG DirectoryEntryVA;
|
);
|
||||||
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
/* Check if this entry is invalid */
|
return FALSE;
|
||||||
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
|
* GetImageUnusedHeaderBytes (IMAGEHLP.@)
|
||||||
*/
|
*/
|
||||||
DWORD
|
DWORD IMAGEAPI GetImageUnusedHeaderBytes(
|
||||||
IMAGEAPI
|
PLOADED_IMAGE LoadedImage,
|
||||||
GetTimestampForLoadedLibrary(HMODULE Module)
|
LPDWORD SizeUnusedHeaderBytes)
|
||||||
{
|
|
||||||
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;
|
SIZE_T FirstFreeByte;
|
||||||
PIMAGE_OPTIONAL_HEADER OptionalHeader = NULL;
|
PIMAGE_OPTIONAL_HEADER OptionalHeader = NULL;
|
||||||
|
@ -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)
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -15,42 +15,42 @@
|
||||||
*
|
*
|
||||||
* 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)
|
||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
DisableThreadLibraryCalls(hinstDLL);
|
DisableThreadLibraryCalls(hinstDLL);
|
||||||
IMAGEHLP_hHeap = HeapCreate(0, 0x10000, 0);
|
IMAGEHLP_hHeap = HeapCreate(0, 0x10000, 0);
|
||||||
break;
|
break;
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
HeapDestroy(IMAGEHLP_hHeap);
|
HeapDestroy(IMAGEHLP_hHeap);
|
||||||
IMAGEHLP_hHeap = NULL;
|
IMAGEHLP_hHeap = NULL;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return TRUE;
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,36 +311,33 @@ 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",
|
||||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
FileHandle, DigestLevel, DigestFunction, DigestHandle
|
||||||
return FALSE;
|
);
|
||||||
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
|
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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/*
|
/*
|
||||||
* IMAGEHLP library
|
* IMAGEHLP library
|
||||||
*
|
*
|
||||||
* Copyright 1998 Patrik Stridvall
|
* Copyright 1998 Patrik Stridvall
|
||||||
* Copyright 2005 Alex Ionescu
|
* Copyright 2005 Alex Ionescu
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -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 */
|
/* Save the time stamp */
|
||||||
*BoundImportsSize = BoundImportTableSize +
|
Descriptor->TimeDateStamp = Image->FileHeader->FileHeader.TimeDateStamp;
|
||||||
((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 */
|
/* Return the descriptor */
|
||||||
BoundLibraryNames = (LPSTR)BoundTable + BoundImportTableSize;
|
return Descriptor;
|
||||||
|
|
||||||
/* Copy the Library Names */
|
|
||||||
RtlCopyMemory(BoundLibraryNames, BoundLibraries, BoundLibraryNamesSize);
|
|
||||||
|
|
||||||
/* Now loop both tables */
|
|
||||||
BoundTableEntry = BoundTable;
|
|
||||||
NextDescriptor = BoundImportDescriptor;
|
|
||||||
while ((Descriptor = *NextDescriptor))
|
|
||||||
{
|
|
||||||
/* Copy the data */
|
|
||||||
BoundTableEntry->TimeDateStamp = Descriptor->TimeDateStamp;
|
|
||||||
BoundTableEntry->OffsetModuleName = (USHORT)(BoundImportTableSize +
|
|
||||||
(Descriptor->ModuleName -
|
|
||||||
(ULONG_PTR)BoundLibraries));
|
|
||||||
BoundTableEntry->NumberOfModuleForwarderRefs = Descriptor->ForwaderReferences;
|
|
||||||
|
|
||||||
/* Now loop the forwarders */
|
|
||||||
BoundForwarder = (PIMAGE_BOUND_FORWARDER_REF)BoundTableEntry + 1;
|
|
||||||
NextForwarder = &Descriptor->Forwarders;
|
|
||||||
while ((Forwarder = *NextForwarder))
|
|
||||||
{
|
|
||||||
/* Copy the data */
|
|
||||||
BoundForwarder->TimeDateStamp = Forwarder->TimeDateStamp;
|
|
||||||
BoundForwarder->OffsetModuleName = (USHORT)(BoundImportTableSize +
|
|
||||||
(Forwarder->ModuleName -
|
|
||||||
(ULONG_PTR)BoundLibraries));
|
|
||||||
|
|
||||||
/* Move to the next new forwarder, and move to the next entry */
|
|
||||||
BoundForwarder++;
|
|
||||||
NextForwarder = &Forwarder->Next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Move to next Bound Import Table Entry */
|
|
||||||
BoundTableEntry = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)BoundForwarder;
|
|
||||||
|
|
||||||
/* Move to the next descriptor */
|
|
||||||
NextDescriptor = &Descriptor->Next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Loop the descriptors and forwarders to free them */
|
|
||||||
NextDescriptor = BoundImportDescriptor;
|
|
||||||
while ((Descriptor = *NextDescriptor))
|
|
||||||
{
|
|
||||||
/* Read next internal descriptor */
|
|
||||||
*NextDescriptor = Descriptor->Next;
|
|
||||||
|
|
||||||
/* Loop its forwarders */
|
|
||||||
NextForwarder = &Descriptor->Forwarders;
|
|
||||||
while ((Forwarder = *NextForwarder))
|
|
||||||
{
|
|
||||||
/* Next Forwarder */
|
|
||||||
*NextForwarder = Forwarder->Next;
|
|
||||||
|
|
||||||
/* Free it */
|
|
||||||
HeapFree(IMAGEHLP_hHeap, 0, Forwarder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free it */
|
|
||||||
HeapFree(IMAGEHLP_hHeap, 0, Descriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the Bound Import Table */
|
|
||||||
return BoundTable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PCHAR
|
static 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;
|
||||||
{
|
|
||||||
/* Save the time stamp */
|
/* Size of the whole table, dword aligned */
|
||||||
Descriptor->TimeDateStamp = Image->FileHeader->FileHeader.TimeDateStamp;
|
*BoundImportsSize = BoundImportTableSize +
|
||||||
}
|
((BoundLibraryNamesSize + sizeof(ULONG) - 1) &
|
||||||
|
~(sizeof(ULONG) - 1));
|
||||||
|
|
||||||
|
/* Allocate it */
|
||||||
|
BoundTable = HeapAlloc(IMAGEHLP_hHeap, HEAP_ZERO_MEMORY, *BoundImportsSize);
|
||||||
|
|
||||||
/* Return the descriptor */
|
/* Pointer Library Names inside the Bound Import Table */
|
||||||
return Descriptor;
|
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 */
|
||||||
|
BoundTableEntry->TimeDateStamp = Descriptor->TimeDateStamp;
|
||||||
|
BoundTableEntry->OffsetModuleName = (USHORT)(BoundImportTableSize +
|
||||||
|
(Descriptor->ModuleName -
|
||||||
|
(ULONG_PTR)BoundLibraries));
|
||||||
|
BoundTableEntry->NumberOfModuleForwarderRefs = Descriptor->ForwaderReferences;
|
||||||
|
|
||||||
|
/* Now loop the forwarders */
|
||||||
|
BoundForwarder = (PIMAGE_BOUND_FORWARDER_REF)BoundTableEntry + 1;
|
||||||
|
NextForwarder = &Descriptor->Forwarders;
|
||||||
|
while ((Forwarder = *NextForwarder))
|
||||||
|
{
|
||||||
|
/* Copy the data */
|
||||||
|
BoundForwarder->TimeDateStamp = Forwarder->TimeDateStamp;
|
||||||
|
BoundForwarder->OffsetModuleName = (USHORT)(BoundImportTableSize +
|
||||||
|
(Forwarder->ModuleName -
|
||||||
|
(ULONG_PTR)BoundLibraries));
|
||||||
|
|
||||||
|
/* Move to the next new forwarder, and move to the next entry */
|
||||||
|
BoundForwarder++;
|
||||||
|
NextForwarder = &Forwarder->Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move to next Bound Import Table Entry */
|
||||||
|
BoundTableEntry = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)BoundForwarder;
|
||||||
|
|
||||||
|
/* Move to the next descriptor */
|
||||||
|
NextDescriptor = &Descriptor->Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loop the descriptors and forwarders to free them */
|
||||||
|
NextDescriptor = BoundImportDescriptor;
|
||||||
|
while ((Descriptor = *NextDescriptor))
|
||||||
|
{
|
||||||
|
/* Read next internal descriptor */
|
||||||
|
*NextDescriptor = Descriptor->Next;
|
||||||
|
|
||||||
|
/* Loop its forwarders */
|
||||||
|
NextForwarder = &Descriptor->Forwarders;
|
||||||
|
while ((Forwarder = *NextForwarder))
|
||||||
|
{
|
||||||
|
/* Next Forwarder */
|
||||||
|
*NextForwarder = Forwarder->Next;
|
||||||
|
|
||||||
|
/* Free it */
|
||||||
|
HeapFree(IMAGEHLP_hHeap, 0, Forwarder);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free it */
|
||||||
|
HeapFree(IMAGEHLP_hHeap, 0, Descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the Bound Import Table */
|
||||||
|
return BoundTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
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;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue