Skip to content
Snippets Groups Projects
Commit cd3afa89 authored by Alexandre Julliard's avatar Alexandre Julliard
Browse files

LOAD_LIBRARY_AS_DATAFILE modules must be mapped like normal files, not

like PE images. Fixed resource loading to handle that.
parent f94462fb
No related branches found
No related tags found
No related merge requests found
......@@ -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);
......
......@@ -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 */
......
......@@ -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);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment