LOAD_LIBRARY_AS_DATAFILE modules must be mapped like normal files, not
like PE images. Fixed resource loading to handle that.
This commit is contained in:
parent
f94462fb75
commit
cd3afa895b
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue