From: Billy Laws blaws05@gmail.com
--- dlls/ntdll/loader.c | 13 +++++++++++++ dlls/ntdll/tests/thread.c | 12 ++++++------ dlls/ntdll/unix/thread.c | 9 +++++++-- 3 files changed, 26 insertions(+), 8 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 6b089c990b5..8ef5f69b9ca 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -3909,6 +3909,12 @@ void WINAPI LdrShutdownThread(void) /* don't do any detach calls if process is exiting */ if (process_detaching) return;
+ if (NtCurrentTeb()->SkipThreadAttach) + { + heap_thread_detach(); + return; + } + RtlProcessFlsData( NtCurrentTeb()->FlsSlots, 1 );
RtlEnterCriticalSection( &loader_section ); @@ -4474,6 +4480,13 @@ void loader_init( CONTEXT *context, void **entry ) #ifdef __arm64ec__ arm64ec_thread_init(); #endif + + if (NtCurrentTeb()->SkipThreadAttach) + { + RtlLeaveCriticalSection( &loader_section ); + return; + } + wm = get_modref( NtCurrentTeb()->Peb->ImageBaseAddress ); }
diff --git a/dlls/ntdll/tests/thread.c b/dlls/ntdll/tests/thread.c index 926e3b0bc8c..9fd23809488 100644 --- a/dlls/ntdll/tests/thread.c +++ b/dlls/ntdll/tests/thread.c @@ -424,17 +424,17 @@ static void test_skip_thread_attach(void)
status = pNtCreateThreadEx( &thread, THREAD_ALL_ACCESS, NULL, GetCurrentProcess(), test_skip_thread_attach_proc, &args, THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH, 0, 0, 0, NULL ); - todo_wine ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status ); + ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status );
WaitForSingleObject( thread, INFINITE );
CloseHandle( thread );
- todo_wine ok( !*seen_thread_attach, "Unexpected\n" ); - todo_wine ok( !*seen_thread_detach, "Unexpected\n" ); - todo_wine ok( args.teb_flag, "Unexpected\n" ); - todo_wine ok( !args.teb_tls_pointer, "Unexpected\n" ); - todo_wine ok( !args.teb_fls_slots, "Unexpected\n" ); + ok( !*seen_thread_attach, "Unexpected\n" ); + ok( !*seen_thread_detach, "Unexpected\n" ); + ok( args.teb_flag, "Unexpected\n" ); + ok( !args.teb_tls_pointer, "Unexpected\n" ); + ok( !args.teb_fls_slots, "Unexpected\n" );
FreeLibrary(module); delete: diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index 6c1ea2d0a00..be5fd876a6b 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -1315,8 +1315,8 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT ULONG flags, ULONG_PTR zero_bits, SIZE_T stack_commit, SIZE_T stack_reserve, PS_ATTRIBUTE_LIST *attr_list ) { - static const ULONG supported_flags = THREAD_CREATE_FLAGS_CREATE_SUSPENDED | THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER | - THREAD_CREATE_FLAGS_BYPASS_PROCESS_FREEZE; + static const ULONG supported_flags = THREAD_CREATE_FLAGS_CREATE_SUSPENDED | THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH | + THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER | THREAD_CREATE_FLAGS_BYPASS_PROCESS_FREEZE; sigset_t sigset; pthread_t pthread_id; pthread_attr_t pthread_attr; @@ -1326,6 +1326,7 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT DWORD tid = 0; int request_pipe[2]; TEB *teb; + WOW_TEB *wow_teb; unsigned int status;
if (flags & ~supported_flags) @@ -1411,6 +1412,10 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT
set_thread_id( teb, GetCurrentProcessId(), tid );
+ teb->SkipThreadAttach = !!(flags & THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH); + wow_teb = get_wow_teb( teb ); + if (wow_teb) wow_teb->SkipThreadAttach = teb->SkipThreadAttach; + thread_data = (struct ntdll_thread_data *)&teb->GdiTebBatch; thread_data->request_fd = request_pipe[1]; thread_data->start = start;