kernel32: Implement the LOAD_LIBRARY_AS_IMAGE_RESOURCE flag.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
9f103a9e78
commit
e1d8c176ef
|
@ -1125,12 +1125,14 @@ static BOOL load_library_as_datafile( LPCWSTR name, HMODULE *hmod, DWORD flags )
|
||||||
WCHAR filenameW[MAX_PATH];
|
WCHAR filenameW[MAX_PATH];
|
||||||
HANDLE hFile = INVALID_HANDLE_VALUE;
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
||||||
HANDLE mapping;
|
HANDLE mapping;
|
||||||
HMODULE module;
|
HMODULE module = 0;
|
||||||
|
DWORD protect = PAGE_READONLY;
|
||||||
DWORD sharing = FILE_SHARE_READ;
|
DWORD sharing = FILE_SHARE_READ;
|
||||||
|
|
||||||
*hmod = 0;
|
*hmod = 0;
|
||||||
|
|
||||||
if (!(flags & LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)) sharing |= FILE_SHARE_WRITE;
|
if (!(flags & LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)) sharing |= FILE_SHARE_WRITE;
|
||||||
|
if (flags & LOAD_LIBRARY_AS_IMAGE_RESOURCE) protect |= SEC_IMAGE;
|
||||||
|
|
||||||
if (SearchPathW( NULL, name, dotDLL, sizeof(filenameW) / sizeof(filenameW[0]),
|
if (SearchPathW( NULL, name, dotDLL, sizeof(filenameW) / sizeof(filenameW[0]),
|
||||||
filenameW, NULL ))
|
filenameW, NULL ))
|
||||||
|
@ -1139,22 +1141,28 @@ static BOOL load_library_as_datafile( LPCWSTR name, HMODULE *hmod, DWORD flags )
|
||||||
}
|
}
|
||||||
if (hFile == INVALID_HANDLE_VALUE) return FALSE;
|
if (hFile == INVALID_HANDLE_VALUE) return FALSE;
|
||||||
|
|
||||||
mapping = CreateFileMappingW( hFile, NULL, PAGE_READONLY, 0, 0, NULL );
|
mapping = CreateFileMappingW( hFile, NULL, protect, 0, 0, NULL );
|
||||||
CloseHandle( hFile );
|
if (!mapping) goto failed;
|
||||||
if (!mapping) return FALSE;
|
|
||||||
|
|
||||||
module = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
|
module = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
|
||||||
CloseHandle( mapping );
|
CloseHandle( mapping );
|
||||||
if (!module) return FALSE;
|
if (!module) goto failed;
|
||||||
|
|
||||||
/* make sure it's a valid PE file */
|
if (!(flags & LOAD_LIBRARY_AS_IMAGE_RESOURCE))
|
||||||
if (!RtlImageNtHeader(module))
|
|
||||||
{
|
{
|
||||||
UnmapViewOfFile( module );
|
/* make sure it's a valid PE file */
|
||||||
return FALSE;
|
if (!RtlImageNtHeader( module )) goto failed;
|
||||||
|
*hmod = (HMODULE)((char *)module + 1); /* set bit 0 for data file module */
|
||||||
}
|
}
|
||||||
*hmod = (HMODULE)((char *)module + 1); /* set low bit of handle to indicate datafile module */
|
else *hmod = (HMODULE)((char *)module + 2); /* set bit 1 for image resource module */
|
||||||
|
|
||||||
|
CloseHandle( hFile );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
failed:
|
||||||
|
if (module) UnmapViewOfFile( module );
|
||||||
|
CloseHandle( hFile );
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1174,7 +1182,6 @@ static HMODULE load_library( const UNICODE_STRING *libname, DWORD flags )
|
||||||
LOAD_LIBRARY_SEARCH_SYSTEM32 |
|
LOAD_LIBRARY_SEARCH_SYSTEM32 |
|
||||||
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
|
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
|
||||||
const DWORD unsupported_flags = (LOAD_IGNORE_CODE_AUTHZ_LEVEL |
|
const DWORD unsupported_flags = (LOAD_IGNORE_CODE_AUTHZ_LEVEL |
|
||||||
LOAD_LIBRARY_AS_IMAGE_RESOURCE |
|
|
||||||
LOAD_LIBRARY_REQUIRE_SIGNED_TARGET);
|
LOAD_LIBRARY_REQUIRE_SIGNED_TARGET);
|
||||||
|
|
||||||
if (!(flags & load_library_search_flags)) flags |= default_search_flags;
|
if (!(flags & load_library_search_flags)) flags |= default_search_flags;
|
||||||
|
@ -1188,7 +1195,7 @@ static HMODULE load_library( const UNICODE_STRING *libname, DWORD flags )
|
||||||
load_path = MODULE_get_dll_load_path( flags & LOAD_WITH_ALTERED_SEARCH_PATH ? libname->Buffer : NULL, -1 );
|
load_path = MODULE_get_dll_load_path( flags & LOAD_WITH_ALTERED_SEARCH_PATH ? libname->Buffer : NULL, -1 );
|
||||||
if (!load_path) return 0;
|
if (!load_path) return 0;
|
||||||
|
|
||||||
if (flags & (LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE))
|
if (flags & (LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE | LOAD_LIBRARY_AS_IMAGE_RESOURCE))
|
||||||
{
|
{
|
||||||
ULONG_PTR magic;
|
ULONG_PTR magic;
|
||||||
|
|
||||||
|
@ -1337,11 +1344,9 @@ BOOL WINAPI DECLSPEC_HOTPATCH FreeLibrary(HINSTANCE hLibModule)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ULONG_PTR)hLibModule & 1)
|
if ((ULONG_PTR)hLibModule & 3) /* this is a datafile module */
|
||||||
{
|
{
|
||||||
/* this is a LOAD_LIBRARY_AS_DATAFILE module */
|
return UnmapViewOfFile( (void *)((ULONG_PTR)hLibModule & ~3) );
|
||||||
char *ptr = (char *)hLibModule - 1;
|
|
||||||
return UnmapViewOfFile( ptr );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((nts = LdrUnloadDll( hLibModule )) == STATUS_SUCCESS) retv = TRUE;
|
if ((nts = LdrUnloadDll( hLibModule )) == STATUS_SUCCESS) retv = TRUE;
|
||||||
|
|
|
@ -849,7 +849,7 @@ static void test_Loader(void)
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
hlib_as_data_file = LoadLibraryExA(dll_name, 0, LOAD_LIBRARY_AS_DATAFILE);
|
hlib_as_data_file = LoadLibraryExA(dll_name, 0, LOAD_LIBRARY_AS_DATAFILE);
|
||||||
ok(hlib_as_data_file != 0, "LoadLibraryEx error %u\n", GetLastError());
|
ok(hlib_as_data_file != 0, "LoadLibraryEx error %u\n", GetLastError());
|
||||||
ok((ULONG_PTR)hlib_as_data_file & 1, "hlib_as_data_file is even\n");
|
ok(((ULONG_PTR)hlib_as_data_file & 3) == 1, "hlib_as_data_file got %p\n", hlib_as_data_file);
|
||||||
|
|
||||||
hlib = GetModuleHandleA(dll_name);
|
hlib = GetModuleHandleA(dll_name);
|
||||||
ok(!hlib, "GetModuleHandle should fail\n");
|
ok(!hlib, "GetModuleHandle should fail\n");
|
||||||
|
@ -865,7 +865,7 @@ static void test_Loader(void)
|
||||||
|
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
hlib_as_data_file = LoadLibraryExA(dll_name, 0, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE);
|
hlib_as_data_file = LoadLibraryExA(dll_name, 0, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE);
|
||||||
if (!((ULONG_PTR)hlib_as_data_file & 1) || /* winxp */
|
if (!((ULONG_PTR)hlib_as_data_file & 3) || /* winxp */
|
||||||
(!hlib_as_data_file && GetLastError() == ERROR_INVALID_PARAMETER)) /* w2k3 */
|
(!hlib_as_data_file && GetLastError() == ERROR_INVALID_PARAMETER)) /* w2k3 */
|
||||||
{
|
{
|
||||||
win_skip( "LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE not supported\n" );
|
win_skip( "LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE not supported\n" );
|
||||||
|
@ -886,6 +886,28 @@ static void test_Loader(void)
|
||||||
ok(ret, "FreeLibrary error %d\n", GetLastError());
|
ok(ret, "FreeLibrary error %d\n", GetLastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
hlib_as_data_file = LoadLibraryExA(dll_name, 0, LOAD_LIBRARY_AS_IMAGE_RESOURCE);
|
||||||
|
if (!((ULONG_PTR)hlib_as_data_file & 3) || /* winxp */
|
||||||
|
(!hlib_as_data_file && GetLastError() == ERROR_INVALID_PARAMETER)) /* w2k3 */
|
||||||
|
{
|
||||||
|
win_skip( "LOAD_LIBRARY_AS_IMAGE_RESOURCE not supported\n" );
|
||||||
|
FreeLibrary(hlib_as_data_file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ok(hlib_as_data_file != 0, "LoadLibraryEx error %u\n", GetLastError());
|
||||||
|
ok(((ULONG_PTR)hlib_as_data_file & 3) == 2, "hlib_as_data_file got %p\n",
|
||||||
|
hlib_as_data_file);
|
||||||
|
|
||||||
|
hlib = GetModuleHandleA(dll_name);
|
||||||
|
ok(!hlib, "GetModuleHandle should fail\n");
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = FreeLibrary(hlib_as_data_file);
|
||||||
|
ok(ret, "FreeLibrary error %d\n", GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
query_image_section( i, dll_name, &nt_header, NULL );
|
query_image_section( i, dll_name, &nt_header, NULL );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue