Alexandre Julliard : kernel32: Implement the LOAD_LIBRARY_AS_IMAGE_RESOURCE flag.
Alexandre Julliard
julliard at winehq.org
Thu Mar 1 13:34:44 CST 2018
Module: wine
Branch: master
Commit: e1d8c176efdd04fb2a0f99426e1ad9962589b9ec
URL: https://source.winehq.org/git/wine.git/?a=commit;h=e1d8c176efdd04fb2a0f99426e1ad9962589b9ec
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu Mar 1 17:18:03 2018 +0100
kernel32: Implement the LOAD_LIBRARY_AS_IMAGE_RESOURCE flag.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/kernel32/module.c | 37 +++++++++++++++++++++----------------
dlls/kernel32/tests/loader.c | 26 ++++++++++++++++++++++++--
2 files changed, 45 insertions(+), 18 deletions(-)
diff --git a/dlls/kernel32/module.c b/dlls/kernel32/module.c
index a5346db..d232d7d 100644
--- a/dlls/kernel32/module.c
+++ b/dlls/kernel32/module.c
@@ -1125,12 +1125,14 @@ static BOOL load_library_as_datafile( LPCWSTR name, HMODULE *hmod, DWORD flags )
WCHAR filenameW[MAX_PATH];
HANDLE hFile = INVALID_HANDLE_VALUE;
HANDLE mapping;
- HMODULE module;
+ HMODULE module = 0;
+ DWORD protect = PAGE_READONLY;
DWORD sharing = FILE_SHARE_READ;
*hmod = 0;
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]),
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;
- mapping = CreateFileMappingW( hFile, NULL, PAGE_READONLY, 0, 0, NULL );
- CloseHandle( hFile );
- if (!mapping) return FALSE;
+ mapping = CreateFileMappingW( hFile, NULL, protect, 0, 0, NULL );
+ if (!mapping) goto failed;
module = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
CloseHandle( mapping );
- if (!module) return FALSE;
+ if (!module) goto failed;
- /* make sure it's a valid PE file */
- if (!RtlImageNtHeader(module))
+ if (!(flags & LOAD_LIBRARY_AS_IMAGE_RESOURCE))
{
- UnmapViewOfFile( module );
- return FALSE;
+ /* make sure it's a valid PE file */
+ 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;
+
+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_DEFAULT_DIRS);
const DWORD unsupported_flags = (LOAD_IGNORE_CODE_AUTHZ_LEVEL |
- LOAD_LIBRARY_AS_IMAGE_RESOURCE |
LOAD_LIBRARY_REQUIRE_SIGNED_TARGET);
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 );
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;
@@ -1337,11 +1344,9 @@ BOOL WINAPI DECLSPEC_HOTPATCH FreeLibrary(HINSTANCE hLibModule)
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 */
- char *ptr = (char *)hLibModule - 1;
- return UnmapViewOfFile( ptr );
+ return UnmapViewOfFile( (void *)((ULONG_PTR)hLibModule & ~3) );
}
if ((nts = LdrUnloadDll( hLibModule )) == STATUS_SUCCESS) retv = TRUE;
diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c
index 0a65bcd..4d1b3e2 100644
--- a/dlls/kernel32/tests/loader.c
+++ b/dlls/kernel32/tests/loader.c
@@ -849,7 +849,7 @@ static void test_Loader(void)
SetLastError(0xdeadbeef);
hlib_as_data_file = LoadLibraryExA(dll_name, 0, LOAD_LIBRARY_AS_DATAFILE);
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);
ok(!hlib, "GetModuleHandle should fail\n");
@@ -865,7 +865,7 @@ static void test_Loader(void)
SetLastError(0xdeadbeef);
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 */
{
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());
}
+ 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 );
}
else
More information about the wine-cvs
mailing list