Alexandre Julliard : ntdll: Replace image mapping by the builtin module directly in NtMapViewOfSection().

Alexandre Julliard julliard at winehq.org
Mon Mar 22 17:15:52 CDT 2021


Module: wine
Branch: master
Commit: 24a5a101426e16aa3f9ab9981af67c2edc72adcf
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=24a5a101426e16aa3f9ab9981af67c2edc72adcf

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Mar 22 09:56:57 2021 +0100

ntdll: Replace image mapping by the builtin module directly in NtMapViewOfSection().

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/unix/loader.c       | 68 ++++++++++++++++++++++++++++++++++++++++++
 dlls/ntdll/unix/unix_private.h |  2 ++
 dlls/ntdll/unix/virtual.c      |  7 +++--
 3 files changed, 75 insertions(+), 2 deletions(-)

diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
index 25be205c696..fd30c5ac939 100644
--- a/dlls/ntdll/unix/loader.c
+++ b/dlls/ntdll/unix/loader.c
@@ -1421,6 +1421,74 @@ static NTSTATUS CDECL load_builtin_dll( UNICODE_STRING *nt_name, void **module,
 }
 
 
+/***********************************************************************
+ *           load_builtin
+ *
+ * Load the builtin dll if specified by load order configuration.
+ * Return STATUS_IMAGE_ALREADY_LOADED if we should keep the native one that we have found.
+ */
+NTSTATUS load_builtin( const pe_image_info_t *image_info, const WCHAR *filename,
+                       void **module, SIZE_T *size )
+{
+    NTSTATUS status;
+    UNICODE_STRING nt_name;
+    SECTION_IMAGE_INFORMATION info;
+    enum loadorder loadorder;
+    const WCHAR *app_name = NULL;
+
+    if (NtCurrentTeb()->Peb->ImageBaseAddress)
+        app_name = NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer;
+
+    init_unicode_string( &nt_name, filename );
+    loadorder = get_load_order( app_name, &nt_name );
+
+    if (image_info->image_flags & IMAGE_FLAGS_WineBuiltin)
+    {
+        switch (loadorder)
+        {
+        case LO_NATIVE_BUILTIN:
+        case LO_BUILTIN:
+        case LO_BUILTIN_NATIVE:
+        case LO_DEFAULT:
+            status = find_builtin_dll( &nt_name, module, size, &info, FALSE );
+            if (status == STATUS_DLL_NOT_FOUND) return STATUS_IMAGE_ALREADY_LOADED;
+            return status;
+        default:
+            return STATUS_DLL_NOT_FOUND;
+        }
+    }
+    if (image_info->image_flags & IMAGE_FLAGS_WineFakeDll)
+    {
+        TRACE( "%s is a fake Wine dll\n", debugstr_us(&nt_name) );
+        switch (loadorder)
+        {
+        case LO_NATIVE_BUILTIN:
+        case LO_BUILTIN:
+        case LO_BUILTIN_NATIVE:
+        case LO_DEFAULT:
+            return find_builtin_dll( &nt_name, module, size, &info, FALSE );
+        default:
+            return STATUS_DLL_NOT_FOUND;
+        }
+    }
+    switch (loadorder)
+    {
+    case LO_NATIVE:
+    case LO_NATIVE_BUILTIN:
+        return STATUS_IMAGE_ALREADY_LOADED;
+    case LO_BUILTIN:
+        return find_builtin_dll( &nt_name, module, size, &info, FALSE );
+    case LO_BUILTIN_NATIVE:
+    case LO_DEFAULT:
+        status = find_builtin_dll( &nt_name, module, size, &info, (loadorder == LO_DEFAULT) );
+        if (status == STATUS_DLL_NOT_FOUND) return STATUS_IMAGE_ALREADY_LOADED;
+        return status;
+    default:
+        return STATUS_DLL_NOT_FOUND;
+    }
+}
+
+
 #ifdef __FreeBSD__
 /* The PT_LOAD segments are sorted in increasing order, and the first
  * starts at the beginning of the ELF file. By parsing the file, we can
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index e527f5f799b..5e9eacb3bf8 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -141,6 +141,8 @@ extern DWORD ntdll_umbstowcs( const char *src, DWORD srclen, WCHAR *dst, DWORD d
 extern int ntdll_wcstoumbs( const WCHAR *src, DWORD srclen, char *dst, DWORD dstlen, BOOL strict ) DECLSPEC_HIDDEN;
 extern char **build_envp( const WCHAR *envW ) DECLSPEC_HIDDEN;
 extern NTSTATUS exec_wineloader( char **argv, int socketfd, const pe_image_info_t *pe_info ) DECLSPEC_HIDDEN;
+extern NTSTATUS load_builtin( const pe_image_info_t *image_info, const WCHAR *filename,
+                              void **addr_ptr, SIZE_T *size_ptr ) DECLSPEC_HIDDEN;
 extern void start_server( BOOL debug ) DECLSPEC_HIDDEN;
 extern ULONG_PTR get_image_address(void) DECLSPEC_HIDDEN;
 
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index a38b8478371..69592892840 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -2531,8 +2531,11 @@ static NTSTATUS virtual_map_section( HANDLE handle, PVOID *addr_ptr, unsigned sh
     if (image_info)
     {
         filename = (WCHAR *)(image_info + 1);
-        res = virtual_map_image( handle, access, addr_ptr, size_ptr, zero_bits_64, shared_file,
-                                 alloc_type, image_info, filename, FALSE );
+        /* check if we can replace that mapping with the builtin */
+        res = load_builtin( image_info, filename, addr_ptr, size_ptr );
+        if (res == STATUS_IMAGE_ALREADY_LOADED)
+            res = virtual_map_image( handle, access, addr_ptr, size_ptr, zero_bits_64, shared_file,
+                                     alloc_type, image_info, filename, FALSE );
         if (shared_file) NtClose( shared_file );
         free( image_info );
         return res;




More information about the wine-cvs mailing list