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