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