Module: wine Branch: master Commit: 8477ae27a87355d98035153927548b4b57d856f7 URL: http://source.winehq.org/git/wine.git/?a=commit;h=8477ae27a87355d98035153927...
Author: Alexandre Julliard julliard@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@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 );