Alexandre Julliard : ntdll: Fixup imports in the first thread that runs, even if it's not the main one.

Alexandre Julliard julliard at winehq.org
Mon Nov 20 16:01:35 CST 2017


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Nov 20 17:09:29 2017 +0100

ntdll: Fixup imports in the first thread that runs, even if it's not the main one.

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

---

 dlls/kernel32/tests/process.c |  1 -
 dlls/ntdll/loader.c           | 85 ++++++++++++++++++++++++-------------------
 dlls/ntdll/ntdll_misc.h       |  2 +-
 dlls/ntdll/thread.c           |  4 +-
 4 files changed, 50 insertions(+), 42 deletions(-)

diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index bb91ec9..6790185 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -3060,7 +3060,6 @@ static void test_SuspendProcessNewThread(void)
     ok(exit_code == 0x1234, "Invalid remote thread exit code\n");
 
     ret = are_imports_resolved(pi.hProcess, exe_base, &nt_header);
-    todo_wine
     ok(ret, "EXE IAT entry not resolved\n");
 
     if (thread_handle)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 9c89d57..820398b 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -64,6 +64,7 @@ WINE_DECLARE_DEBUG_CHANNEL(pid);
 typedef DWORD (CALLBACK *DLLENTRYPROC)(HMODULE,DWORD,LPVOID);
 typedef void  (CALLBACK *LDRENUMPROC)(LDR_MODULE *, void *, BOOLEAN *);
 
+static BOOL imports_fixup_done = FALSE;  /* set once the imports have been fixed up, before attaching them */
 static BOOL process_detaching = FALSE;  /* set on process detach to avoid deadlocks with thread detach */
 static int free_lib_count;   /* recursion depth of LdrUnloadDll calls */
 
@@ -1326,28 +1327,16 @@ static void process_detach(void)
 }
 
 /*************************************************************************
- *		MODULE_DllThreadAttach
+ *		thread_attach
  *
  * Send DLL thread attach notifications. These are sent in the
  * reverse sequence of process detach notification.
- *
+ * The loader_section must be locked while calling this function.
  */
-NTSTATUS MODULE_DllThreadAttach( LPVOID lpReserved )
+static void thread_attach(void)
 {
     PLIST_ENTRY mark, entry;
     PLDR_MODULE mod;
-    NTSTATUS    status;
-
-    /* don't do any attach calls if process is exiting */
-    if (process_detaching) return STATUS_SUCCESS;
-
-    RtlEnterCriticalSection( &loader_section );
-
-    RtlAcquirePebLock();
-    InsertHeadList( &tls_links, &NtCurrentTeb()->TlsLinks );
-    RtlReleasePebLock();
-
-    if ((status = alloc_thread_tls()) != STATUS_SUCCESS) goto done;
 
     mark = &NtCurrentTeb()->Peb->LdrData->InInitializationOrderModuleList;
     for (entry = mark->Flink; entry != mark; entry = entry->Flink)
@@ -1359,13 +1348,8 @@ NTSTATUS MODULE_DllThreadAttach( LPVOID lpReserved )
         if ( mod->Flags & LDR_NO_DLL_CALLS )
             continue;
 
-        MODULE_InitDLL( CONTAINING_RECORD(mod, WINE_MODREF, ldr),
-                        DLL_THREAD_ATTACH, lpReserved );
+        MODULE_InitDLL( CONTAINING_RECORD(mod, WINE_MODREF, ldr), DLL_THREAD_ATTACH, NULL );
     }
-
-done:
-    RtlLeaveCriticalSection( &loader_section );
-    return status;
 }
 
 /******************************************************************
@@ -3014,25 +2998,57 @@ PIMAGE_NT_HEADERS WINAPI RtlImageNtHeader(HMODULE hModule)
 
 
 /***********************************************************************
- *           attach_process_dlls
+ *           attach_dlls
  *
- * Initial attach to all the dlls loaded by the process.
+ * Attach to all the loaded dlls.
+ * If this is the first time, perform the full process initialization.
  */
-static NTSTATUS attach_process_dlls( void *wm )
+NTSTATUS attach_dlls( void *reserved )
 {
     NTSTATUS status;
+    WINE_MODREF *wm;
+    LPCWSTR load_path = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer;
 
     pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL );
 
+    if (process_detaching) return STATUS_SUCCESS;
+
     RtlEnterCriticalSection( &loader_section );
-    if ((status = process_attach( wm, (LPVOID)1 )) != STATUS_SUCCESS)
+
+    wm = get_modref( NtCurrentTeb()->Peb->ImageBaseAddress );
+    assert( wm );
+
+    if (!imports_fixup_done)
     {
-        if (last_failed_modref)
-            ERR( "%s failed to initialize, aborting\n",
-                 debugstr_w(last_failed_modref->ldr.BaseDllName.Buffer) + 1 );
-        return status;
+        actctx_init();
+        if ((status = fixup_imports( wm, load_path )) != STATUS_SUCCESS) goto done;
+        imports_fixup_done = TRUE;
     }
-    attach_implicitly_loaded_dlls( (LPVOID)1 );
+
+    RtlAcquirePebLock();
+    InsertHeadList( &tls_links, &NtCurrentTeb()->TlsLinks );
+    RtlReleasePebLock();
+
+    if ((status = alloc_thread_tls()) != STATUS_SUCCESS) goto done;
+
+    if (!(wm->ldr.Flags & LDR_PROCESS_ATTACHED))  /* first time around */
+    {
+        if ((status = process_attach( wm, reserved )) != STATUS_SUCCESS)
+        {
+            if (last_failed_modref)
+                ERR( "%s failed to initialize, aborting\n",
+                     debugstr_w(last_failed_modref->ldr.BaseDllName.Buffer) + 1 );
+            goto done;
+        }
+        attach_implicitly_loaded_dlls( reserved );
+    }
+    else
+    {
+        thread_attach();
+        status = STATUS_SUCCESS;
+    }
+
+done:
     RtlLeaveCriticalSection( &loader_section );
     return status;
 }
@@ -3109,7 +3125,6 @@ void WINAPI LdrInitializeThunk( void *kernel_start, ULONG_PTR unknown2,
     static const WCHAR globalflagW[] = {'G','l','o','b','a','l','F','l','a','g',0};
     NTSTATUS status;
     WINE_MODREF *wm;
-    LPCWSTR load_path;
     PEB *peb = NtCurrentTeb()->Peb;
     CONTEXT context = { 0 };
 
@@ -3134,6 +3149,7 @@ void WINAPI LdrInitializeThunk( void *kernel_start, ULONG_PTR unknown2,
 
     LdrQueryImageFileExecutionOptions( &peb->ProcessParameters->ImagePathName, globalflagW,
                                        REG_DWORD, &peb->NtGlobalFlag, sizeof(peb->NtGlobalFlag), NULL );
+    heap_set_debug_flags( GetProcessHeap() );
 
     /* the main exe needs to be the first in the load order list */
     RemoveEntryList( &wm->ldr.InLoadOrderModuleList );
@@ -3144,12 +3160,7 @@ void WINAPI LdrInitializeThunk( void *kernel_start, ULONG_PTR unknown2,
     if ((status = virtual_alloc_thread_stack( NtCurrentTeb(), 0, 0 )) != STATUS_SUCCESS) goto error;
     if ((status = server_init_process_done( &context )) != STATUS_SUCCESS) goto error;
 
-    actctx_init();
-    load_path = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer;
-    if ((status = fixup_imports( wm, load_path )) != STATUS_SUCCESS) goto error;
-    heap_set_debug_flags( GetProcessHeap() );
-
-    status = wine_call_on_stack( attach_process_dlls, wm, (char *)NtCurrentTeb()->Tib.StackBase - page_size );
+    status = wine_call_on_stack( attach_dlls, (void *)1, (char *)NtCurrentTeb()->Tib.StackBase - page_size );
     if (status != STATUS_SUCCESS) goto error;
 
     virtual_release_address_space();
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 907bbdd..e469afd 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -104,7 +104,7 @@ extern NTSTATUS validate_open_object_attributes( const OBJECT_ATTRIBUTES *attr )
 
 /* module handling */
 extern LIST_ENTRY tls_links DECLSPEC_HIDDEN;
-extern NTSTATUS MODULE_DllThreadAttach( LPVOID lpReserved ) DECLSPEC_HIDDEN;
+extern NTSTATUS attach_dlls( void *unused ) DECLSPEC_HIDDEN;
 extern FARPROC RELAY_GetProcAddress( HMODULE module, const IMAGE_EXPORT_DIRECTORY *exports,
                                      DWORD exp_size, FARPROC proc, DWORD ordinal, const WCHAR *user ) DECLSPEC_HIDDEN;
 extern FARPROC SNOOP_GetProcAddress( HMODULE hmod, const IMAGE_EXPORT_DIRECTORY *exports, DWORD exp_size,
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index 85ceb2b..ce0ba68 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -349,7 +349,6 @@ HANDLE thread_init(void)
     thread_data->wait_fd[0] = -1;
     thread_data->wait_fd[1] = -1;
     thread_data->debug_info = &debug_info;
-    InsertHeadList( &tls_links, &teb->TlsLinks );
 
     signal_init_thread( teb );
     virtual_init_threading();
@@ -488,9 +487,8 @@ static void start_thread( struct startup_info *info )
 
     signal_init_thread( teb );
     server_init_thread( func );
-    pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL );
 
-    MODULE_DllThreadAttach( NULL );
+    attach_dlls( (void *)1 );
 
     if (TRACE_ON(relay))
         DPRINTF( "%04x:Starting thread proc %p (arg=%p)\n", GetCurrentThreadId(), func, arg );




More information about the wine-cvs mailing list