From: Billy Laws blaws05@gmail.com
--- dlls/ntdll/tests/thread.c | 32 ++++++++++++++++++++++++++++++++ include/winternl.h | 5 +++-- 2 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/tests/thread.c b/dlls/ntdll/tests/thread.c index 436b1bf89e0..0a8facc45ed 100644 --- a/dlls/ntdll/tests/thread.c +++ b/dlls/ntdll/tests/thread.c @@ -31,6 +31,9 @@ static NTSTATUS (WINAPI *pNtCreateThreadEx)( HANDLE *, ACCESS_MASK, OBJECT_ATTRIBUTES *, HANDLE, PRTL_THREAD_START_ROUTINE, void *, ULONG, ULONG_PTR, SIZE_T, SIZE_T, PS_ATTRIBUTE_LIST * ); +static NTSTATUS (WINAPI *pNtSuspendProcess)(HANDLE process); +static NTSTATUS (WINAPI *pNtResumeProcess)(HANDLE process); + static int * (CDECL *p_errno)(void);
static void init_function_pointers(void) @@ -38,6 +41,8 @@ static void init_function_pointers(void) HMODULE hntdll = GetModuleHandleA( "ntdll.dll" ); #define GET_FUNC(name) p##name = (void *)GetProcAddress( hntdll, #name ); GET_FUNC( NtCreateThreadEx ); + GET_FUNC( NtSuspendProcess ); + GET_FUNC( NtResumeProcess ); GET_FUNC( _errno ); #undef GET_FUNC } @@ -242,6 +247,32 @@ static void test_NtCreateUserProcess(void) CloseHandle( thread ); }
+static void CALLBACK test_thread_bypass_process_freeze_proc(void *param) +{ + pNtSuspendProcess(NtCurrentProcess()); + /* The current process will be suspended forever here if THREAD_CREATE_FLAGS_BYPASS_PROCESS_FREEZE is nonfunctional. */ + pNtResumeProcess(NtCurrentProcess()); +} + +static void test_thread_bypass_process_freeze(void) +{ + HANDLE thread; + NTSTATUS status; + + if (!pNtCreateThreadEx || !pNtSuspendProcess || !pNtResumeProcess) + { + win_skip( "NtCreateThreadEx/NtSuspendProcess/NtResumeProcess are not available.\n" ); + return; + } + + status = pNtCreateThreadEx( &thread, THREAD_ALL_ACCESS, NULL, GetCurrentProcess(), test_thread_bypass_process_freeze_proc, + NULL, THREAD_CREATE_FLAGS_BYPASS_PROCESS_FREEZE, 0, 0, 0, NULL ); + todo_wine ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status ); + + WaitForSingleObject( thread, INFINITE ); + CloseHandle( thread ); +} + START_TEST(thread) { init_function_pointers(); @@ -250,4 +281,5 @@ START_TEST(thread) test_unique_teb(); test_errno(); test_NtCreateUserProcess(); + test_thread_bypass_process_freeze(); } diff --git a/include/winternl.h b/include/winternl.h index 0bf166b8996..daa5906fdaa 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -3936,8 +3936,9 @@ typedef struct _RTL_PROCESS_MODULE_INFORMATION_EX #define THREAD_CREATE_FLAGS_CREATE_SUSPENDED 0x00000001 #define THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH 0x00000002 #define THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER 0x00000004 -#define THREAD_CREATE_FLAGS_HAS_SECURITY_DESCRIPTOR 0x00000010 -#define THREAD_CREATE_FLAGS_ACCESS_CHECK_IN_TARGET 0x00000020 +#define THREAD_CREATE_FLAGS_LOADER_WORKER 0x00000010 +#define THREAD_CREATE_FLAGS_SKIP_LOADER_INIT 0x00000020 +#define THREAD_CREATE_FLAGS_BYPASS_PROCESS_FREEZE 0x00000040 #define THREAD_CREATE_FLAGS_INITIAL_THREAD 0x00000080
#ifdef __WINESRC__