Alexandre Julliard : ntdll: Load wow64.dll in 64-bit Wow64 processes.

Alexandre Julliard julliard at winehq.org
Wed Jul 21 16:04:30 CDT 2021


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Jul 21 14:52:58 2021 +0200

ntdll: Load wow64.dll in 64-bit Wow64 processes.

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

---

 dlls/ntdll/loader.c | 54 +++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 46 insertions(+), 8 deletions(-)

diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index b5127327e3d..3339596944a 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -3681,7 +3681,41 @@ static void load_global_options(void)
 }
 
 
-#ifndef _WIN64
+
+#ifdef _WIN64
+
+static void (WINAPI *pWow64LdrpInitialize)( CONTEXT *ctx );
+
+static void init_wow64( CONTEXT *context )
+{
+    if (!imports_fixup_done)
+    {
+        HMODULE wow64;
+        WINE_MODREF *wm;
+        NTSTATUS status;
+        static const WCHAR wow64_path[] = L"C:\\windows\\system32\\wow64.dll";
+
+        if ((status = load_dll( NULL, wow64_path, NULL, 0, &wm )))
+        {
+            ERR( "could not load %s, status %x\n", debugstr_w(wow64_path), status );
+            NtTerminateProcess( GetCurrentProcess(), status );
+        }
+        wow64 = wm->ldr.DllBase;
+#define GET_PTR(name) \
+        if (!(p ## name = RtlFindExportedRoutineByName( wow64, #name ))) ERR( "failed to load %s\n", #name )
+
+        GET_PTR( Wow64LdrpInitialize );
+#undef GET_PTR
+        imports_fixup_done = TRUE;
+    }
+
+    RtlLeaveCriticalSection( &loader_section );
+    pWow64LdrpInitialize( context );
+}
+
+
+#else
+
 void *Wow64Transition = NULL;
 
 static void map_wow64cpu(void)
@@ -3712,13 +3746,13 @@ static void map_wow64cpu(void)
     NtClose( file );
 }
 
-static void init_wow64(void)
+static void init_wow64( CONTEXT *context )
 {
     PEB *peb = NtCurrentTeb()->Peb;
-    PEB64 *peb64;
+    PEB64 *peb64 = UlongToPtr( NtCurrentTeb64()->Peb );
+
+    if (Wow64Transition) return;  /* already initialized */
 
-    if (!NtCurrentTeb64()) return;
-    peb64 = UlongToPtr( NtCurrentTeb64()->Peb );
     peb64->OSMajorVersion   = peb->OSMajorVersion;
     peb64->OSMinorVersion   = peb->OSMinorVersion;
     peb64->OSBuildNumber    = peb->OSBuildNumber;
@@ -3791,14 +3825,14 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, ULONG_PTR unknown2, ULONG_PTR
         init_user_process_params();
         load_global_options();
         version_init();
-#ifndef _WIN64
-        init_wow64();
-#endif
+
         wm = build_main_module();
         wm->ldr.LoadCount = -1;
 
         build_ntdll_module();
 
+        if (NtCurrentTeb()->WowTebOffset) init_wow64( context );
+
         if ((status = load_dll( NULL, L"kernel32.dll", NULL, 0, &kernel32 )) != STATUS_SUCCESS)
         {
             MESSAGE( "wine: could not load kernel32.dll, status %x\n", status );
@@ -3831,6 +3865,10 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, ULONG_PTR unknown2, ULONG_PTR
     }
     else wm = get_modref( NtCurrentTeb()->Peb->ImageBaseAddress );
 
+#ifdef _WIN64
+    if (NtCurrentTeb()->WowTebOffset) init_wow64( context );
+#endif
+
     RtlAcquirePebLock();
     InsertHeadList( &tls_links, &NtCurrentTeb()->TlsLinks );
     RtlReleasePebLock();




More information about the wine-cvs mailing list