Module: wine Branch: master Commit: 8d82ab4ae7e3375e3e100f2bfaa0b6bf1466877d URL: http://source.winehq.org/git/wine.git/?a=commit;h=8d82ab4ae7e3375e3e100f2bfa...
Author: Alexandre Julliard julliard@winehq.org Date: Mon Aug 28 14:19:47 2017 +0200
kernel32: Add support for LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE flag.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/kernel32/module.c | 13 +++++++------ dlls/kernel32/tests/loader.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 6 deletions(-)
diff --git a/dlls/kernel32/module.c b/dlls/kernel32/module.c index 8abf195..16356f1 100644 --- a/dlls/kernel32/module.c +++ b/dlls/kernel32/module.c @@ -936,7 +936,7 @@ WCHAR *MODULE_get_dll_load_path( LPCWSTR module ) /****************************************************************** * load_library_as_datafile */ -static BOOL load_library_as_datafile( LPCWSTR name, HMODULE* hmod) +static BOOL load_library_as_datafile( LPCWSTR name, HMODULE *hmod, DWORD flags ) { static const WCHAR dotDLL[] = {'.','d','l','l',0};
@@ -944,14 +944,16 @@ static BOOL load_library_as_datafile( LPCWSTR name, HMODULE* hmod) HANDLE hFile = INVALID_HANDLE_VALUE; HANDLE mapping; HMODULE module; + DWORD sharing = FILE_SHARE_READ;
*hmod = 0;
+ if (!(flags & LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)) sharing |= FILE_SHARE_WRITE; + if (SearchPathW( NULL, name, dotDLL, sizeof(filenameW) / sizeof(filenameW[0]), filenameW, NULL )) { - hFile = CreateFileW( filenameW, GENERIC_READ, FILE_SHARE_READ, - NULL, OPEN_EXISTING, 0, 0 ); + hFile = CreateFileW( filenameW, GENERIC_READ, sharing, NULL, OPEN_EXISTING, 0, 0 ); } if (hFile == INVALID_HANDLE_VALUE) return FALSE;
@@ -987,7 +989,6 @@ static HMODULE load_library( const UNICODE_STRING *libname, DWORD flags ) static const DWORD unsupported_flags = load_library_search_flags | LOAD_IGNORE_CODE_AUTHZ_LEVEL | LOAD_LIBRARY_AS_IMAGE_RESOURCE | - LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE | LOAD_LIBRARY_REQUIRE_SIGNED_TARGET | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR;
@@ -998,7 +999,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 );
- if (flags & LOAD_LIBRARY_AS_DATAFILE) + if (flags & (LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)) { ULONG_PTR magic;
@@ -1014,7 +1015,7 @@ static HMODULE load_library( const UNICODE_STRING *libname, DWORD flags ) /* The method in load_library_as_datafile allows searching for the * 'native' libraries only */ - if (load_library_as_datafile( libname->Buffer, &hModule )) goto done; + if (load_library_as_datafile( libname->Buffer, &hModule, flags )) goto done; flags |= DONT_RESOLVE_DLL_REFERENCES; /* Just in case */ /* Fallback to normal behaviour */ } diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c index 09c21d8..1c44257 100644 --- a/dlls/kernel32/tests/loader.c +++ b/dlls/kernel32/tests/loader.c @@ -523,6 +523,7 @@ static void test_Loader(void) }; int i; DWORD file_size; + HANDLE h; HMODULE hlib, hlib_as_data_file; char temp_path[MAX_PATH]; char dll_name[MAX_PATH]; @@ -706,9 +707,37 @@ static void test_Loader(void) ok(!hlib, "GetModuleHandle should fail\n");
SetLastError(0xdeadbeef); + h = CreateFileA( dll_name, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 ); + ok( h != INVALID_HANDLE_VALUE, "open failed err %u\n", GetLastError() ); + CloseHandle( h ); + + SetLastError(0xdeadbeef); ret = FreeLibrary(hlib_as_data_file); ok(ret, "FreeLibrary error %d\n", GetLastError());
+ SetLastError(0xdeadbeef); + hlib_as_data_file = LoadLibraryExA(dll_name, 0, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE); + if (!((ULONG_PTR)hlib_as_data_file & 1) || /* winxp */ + (!hlib_as_data_file && GetLastError() == ERROR_INVALID_PARAMETER)) /* w2k3 */ + { + win_skip( "LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE not supported\n" ); + FreeLibrary(hlib_as_data_file); + } + else + { + ok(hlib_as_data_file != 0, "LoadLibraryEx error %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + h = CreateFileA( dll_name, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 ); + todo_wine ok( h == INVALID_HANDLE_VALUE, "open succeeded\n" ); + todo_wine ok( GetLastError() == ERROR_SHARING_VIOLATION, "wrong error %u\n", GetLastError() ); + CloseHandle( h ); + + SetLastError(0xdeadbeef); + ret = FreeLibrary(hlib_as_data_file); + ok(ret, "FreeLibrary error %d\n", GetLastError()); + } + query_image_section( i, dll_name, &nt_header ); } else