Alexandre Julliard : kernel32: Add support for LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE flag.

Alexandre Julliard julliard at winehq.org
Mon Aug 28 14:05:17 CDT 2017


Module: wine
Branch: master
Commit: 8d82ab4ae7e3375e3e100f2bfaa0b6bf1466877d
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=8d82ab4ae7e3375e3e100f2bfaa0b6bf1466877d

Author: Alexandre Julliard <julliard at 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 at 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




More information about the wine-cvs mailing list