From cd3afa895bf8b588006d92821822c3eed3cbd687 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 31 Jan 2002 23:32:57 +0000 Subject: [PATCH] LOAD_LIBRARY_AS_DATAFILE modules must be mapped like normal files, not like PE images. Fixed resource loading to handle that. --- loader/module.c | 13 +++++++++++- loader/pe_image.c | 1 - loader/pe_resource.c | 50 +++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 59 insertions(+), 5 deletions(-) diff --git a/loader/module.c b/loader/module.c index c8f716d8c71..08efd213aae 100644 --- a/loader/module.c +++ b/loader/module.c @@ -1284,7 +1284,18 @@ HMODULE WINAPI LoadLibraryExA(LPCSTR libname, HANDLE hfile, DWORD flags) NULL, OPEN_EXISTING, 0, 0 ); if (hFile != INVALID_HANDLE_VALUE) { - hmod = PE_LoadImage( hFile, filename, flags ); + DWORD type; + MODULE_GetBinaryType( hFile, filename, &type ); + if (type == SCS_32BIT_BINARY) + { + HANDLE mapping = CreateFileMappingA( hFile, NULL, PAGE_READONLY, + 0, 0, NULL ); + if (mapping) + { + hmod = (HMODULE)MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 ); + CloseHandle( mapping ); + } + } CloseHandle( hFile ); } if (hmod) return (HMODULE)((ULONG_PTR)hmod + 1); diff --git a/loader/pe_image.c b/loader/pe_image.c index 74628d12262..8b6513f05f0 100644 --- a/loader/pe_image.c +++ b/loader/pe_image.c @@ -477,7 +477,6 @@ HMODULE PE_LoadImage( HANDLE hFile, LPCSTR filename, DWORD flags ) if (!base) return 0; hModule = (HMODULE)base; - if (flags & LOAD_LIBRARY_AS_DATAFILE) return hModule; /* nothing else to do */ /* perform base relocation, if necessary */ diff --git a/loader/pe_resource.c b/loader/pe_resource.c index 12f14557cd9..a14a9bcddf0 100644 --- a/loader/pe_resource.c +++ b/loader/pe_resource.c @@ -46,6 +46,39 @@ static const void *get_module_base( HMODULE hmod ) } +/********************************************************************** + * is_data_file_module + * + * Check if a module handle is for a LOAD_LIBRARY_AS_DATAFILE module. + */ +inline static int is_data_file_module( HMODULE hmod ) +{ + return (ULONG_PTR)hmod & 1; +} + + +/********************************************************************** + * get_data_file_ptr + * + * Get a pointer to a given offset in a file mapped as data file. + */ +static const void *get_data_file_ptr( const void *base, DWORD offset ) +{ + const IMAGE_NT_HEADERS *nt = PE_HEADER(base); + const IMAGE_SECTION_HEADER *sec = (IMAGE_SECTION_HEADER *)((char *)&nt->OptionalHeader + + nt->FileHeader.SizeOfOptionalHeader); + int i; + + /* find the section containing the virtual address */ + for (i = 0; i < nt->FileHeader.NumberOfSections; i++, sec++) + { + if ((sec->VirtualAddress <= offset) && (sec->VirtualAddress + sec->SizeOfRawData > offset)) + return (char *)base + sec->PointerToRawData + (offset - sec->VirtualAddress); + } + return NULL; +} + + /********************************************************************** * get_resdir * @@ -61,7 +94,10 @@ static const IMAGE_RESOURCE_DIRECTORY* get_resdir( HMODULE hmod ) { dir = &PE_HEADER(base)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]; if (dir->Size && dir->VirtualAddress) - ret = (IMAGE_RESOURCE_DIRECTORY *)((char *)base + dir->VirtualAddress); + { + if (is_data_file_module(hmod)) ret = get_data_file_ptr( base, dir->VirtualAddress ); + else ret = (IMAGE_RESOURCE_DIRECTORY *)((char *)base + dir->VirtualAddress); + } } return ret; } @@ -274,9 +310,17 @@ HRSRC PE_FindResourceW( HMODULE hmod, LPCWSTR name, LPCWSTR type ) */ HGLOBAL PE_LoadResource( HMODULE hmod, HRSRC hRsrc ) { + DWORD offset; const void *base = get_module_base( hmod ); - if (!hRsrc) return 0; - return (HANDLE)((char *)base + ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData); + + if (!hRsrc || !base) return 0; + + offset = ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData; + + if (is_data_file_module(hmod)) + return (HANDLE)get_data_file_ptr( base, offset ); + else + return (HANDLE)((char *)base + offset); }