ntdll: RtlCreateUserThread() also takes a zero_bits parameter.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-05-07 16:03:27 +02:00
parent 6de7fa1bde
commit 40165dfa58
6 changed files with 66 additions and 15 deletions

View File

@ -84,7 +84,7 @@ HANDLE WINAPI DECLSPEC_HOTPATCH CreateRemoteThreadEx( HANDLE process, SECURITY_A
else stack_commit = stack;
if (!set_ntstatus( RtlCreateUserThread( process, sa ? sa->lpSecurityDescriptor : NULL, TRUE,
NULL, stack_reserve, stack_commit,
0, stack_reserve, stack_commit,
(PRTL_THREAD_START_ROUTINE)start, param, &handle, &client_id )))
return 0;

View File

@ -562,7 +562,7 @@
@ stdcall RtlCreateUserProcess(ptr long ptr ptr ptr long long long long ptr)
@ stub RtlCreateUserSecurityObject
@ stdcall RtlCreateUserStack(long long long long long ptr)
@ stdcall RtlCreateUserThread(long ptr long ptr long long ptr ptr ptr ptr)
@ stdcall RtlCreateUserThread(long ptr long long long long ptr ptr ptr ptr)
@ stdcall RtlCustomCPToUnicodeN(ptr ptr long ptr str long)
@ stub RtlCutoverTimeToSystemTime
@ stdcall RtlDeNormalizeProcessParams(ptr)

View File

@ -31,6 +31,8 @@ static unsigned int page_size;
static DWORD64 (WINAPI *pGetEnabledXStateFeatures)(void);
static NTSTATUS (WINAPI *pRtlCreateUserStack)(SIZE_T, SIZE_T, ULONG, SIZE_T, SIZE_T, INITIAL_TEB *);
static NTSTATUS (WINAPI *pRtlCreateUserThread)(HANDLE, SECURITY_DESCRIPTOR*, BOOLEAN, ULONG, SIZE_T,
SIZE_T, PRTL_THREAD_START_ROUTINE, void*, HANDLE*, CLIENT_ID* );
static ULONG64 (WINAPI *pRtlGetEnabledExtendedFeatures)(ULONG64);
static NTSTATUS (WINAPI *pRtlFreeUserStack)(void *);
static void * (WINAPI *pRtlFindExportedRoutineByName)(HMODULE,const char*);
@ -38,6 +40,7 @@ static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
static NTSTATUS (WINAPI *pNtAllocateVirtualMemoryEx)(HANDLE, PVOID *, SIZE_T *, ULONG, ULONG,
MEM_EXTENDED_PARAMETER *, ULONG);
static const BOOL is_win64 = sizeof(void*) != sizeof(int);
static BOOL is_wow64;
static SYSTEM_BASIC_INFORMATION sbi;
@ -91,9 +94,6 @@ static void test_NtAllocateVirtualMemory(void)
NTSTATUS status;
SIZE_T size;
ULONG_PTR zero_bits;
BOOL is_wow64;
if (!pIsWow64Process || !pIsWow64Process(NtCurrentProcess(), &is_wow64)) is_wow64 = FALSE;
/* simple allocation should success */
size = 0x1000;
@ -485,7 +485,7 @@ static DWORD WINAPI test_stack_size_thread(void *ptr)
todo_wine ok( committed == 0x6000, "unexpected stack committed size %x, expected 6000\n", committed );
#endif
return 0;
ExitThread(0);
}
static void test_RtlCreateUserStack(void)
@ -498,6 +498,7 @@ static void test_RtlCreateUserStack(void)
unsigned int i;
NTSTATUS ret;
HANDLE thread;
CLIENT_ID id;
struct
{
@ -563,6 +564,54 @@ static void test_RtlCreateUserStack(void)
thread = CreateThread(NULL, 0x3ff000, test_stack_size_thread, &args, STACK_SIZE_PARAM_IS_A_RESERVATION, NULL);
WaitForSingleObject(thread, INFINITE);
CloseHandle(thread);
args.expect_committed = default_commit < 0x2000 ? 0x2000 : default_commit;
args.expect_reserved = 0x100000;
for (i = 0; i < 32; i++)
{
ULONG mask = ~0u >> i;
NTSTATUS expect_ret = STATUS_SUCCESS;
if (i == 12) expect_ret = STATUS_CONFLICTING_ADDRESSES;
else if (i >= 13) expect_ret = STATUS_INVALID_PARAMETER;
ret = pRtlCreateUserStack( args.expect_committed, args.expect_reserved, i, 0x1000, 0x1000, &stack );
ok( ret == expect_ret || ret == STATUS_NO_MEMORY ||
(ret == STATUS_INVALID_PARAMETER_3 && expect_ret == STATUS_INVALID_PARAMETER) ||
broken( i == 1 && ret == STATUS_INVALID_PARAMETER_3 ), /* win7 */
"%u: got %x / %x\n", i, ret, expect_ret );
if (!ret) pRtlFreeUserStack( stack.DeallocationStack );
ret = pRtlCreateUserThread( GetCurrentProcess(), NULL, FALSE, i,
args.expect_reserved, args.expect_committed,
(void *)test_stack_size_thread, &args, &thread, &id );
ok( ret == expect_ret || ret == STATUS_NO_MEMORY ||
(ret == STATUS_INVALID_PARAMETER_3 && expect_ret == STATUS_INVALID_PARAMETER) ||
broken( i == 1 && ret == STATUS_INVALID_PARAMETER_3 ), /* win7 */
"%u: got %x / %x\n", i, ret, expect_ret );
if (!ret)
{
WaitForSingleObject( thread, INFINITE );
CloseHandle( thread );
}
if (mask <= 31) continue;
if (!is_win64 && !is_wow64) expect_ret = STATUS_INVALID_PARAMETER_3;
ret = pRtlCreateUserStack( args.expect_committed, args.expect_reserved, mask, 0x1000, 0x1000, &stack );
ok( ret == expect_ret || ret == STATUS_NO_MEMORY ||
(ret == STATUS_INVALID_PARAMETER_3 && expect_ret == STATUS_INVALID_PARAMETER),
"%08x: got %x / %x\n", mask, ret, expect_ret );
if (!ret) pRtlFreeUserStack( stack.DeallocationStack );
ret = pRtlCreateUserThread( GetCurrentProcess(), NULL, FALSE, mask,
args.expect_reserved, args.expect_committed,
(void *)test_stack_size_thread, &args, &thread, &id );
ok( ret == expect_ret || ret == STATUS_NO_MEMORY ||
(ret == STATUS_INVALID_PARAMETER_3 && expect_ret == STATUS_INVALID_PARAMETER),
"%08x: got %x / %x\n", mask, ret, expect_ret );
if (!ret)
{
WaitForSingleObject( thread, INFINITE );
CloseHandle( thread );
}
}
}
static void test_NtMapViewOfSection(void)
@ -572,7 +621,7 @@ static void test_NtMapViewOfSection(void)
char buffer[sizeof(data)];
HANDLE file, mapping, process;
void *ptr, *ptr2;
BOOL is_wow64, ret;
BOOL ret;
DWORD status, written;
SIZE_T size, result;
LARGE_INTEGER offset;
@ -1051,6 +1100,7 @@ START_TEST(virtual)
pGetEnabledXStateFeatures = (void *)GetProcAddress(mod, "GetEnabledXStateFeatures");
mod = GetModuleHandleA("ntdll.dll");
pRtlCreateUserStack = (void *)GetProcAddress(mod, "RtlCreateUserStack");
pRtlCreateUserThread = (void *)GetProcAddress(mod, "RtlCreateUserThread");
pRtlFreeUserStack = (void *)GetProcAddress(mod, "RtlFreeUserStack");
pRtlFindExportedRoutineByName = (void *)GetProcAddress(mod, "RtlFindExportedRoutineByName");
pRtlGetEnabledExtendedFeatures = (void *)GetProcAddress(mod, "RtlGetEnabledExtendedFeatures");
@ -1059,6 +1109,7 @@ START_TEST(virtual)
NtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), NULL);
trace("system page size %#x\n", sbi.PageSize);
page_size = sbi.PageSize;
if (!pIsWow64Process || !pIsWow64Process(NtCurrentProcess(), &is_wow64)) is_wow64 = FALSE;
test_NtAllocateVirtualMemory();
test_RtlCreateUserStack();

View File

@ -150,7 +150,7 @@ void WINAPI RtlUserThreadStart( PRTL_THREAD_START_ROUTINE entry, void *arg )
* RtlCreateUserThread (NTDLL.@)
*/
NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, SECURITY_DESCRIPTOR *descr,
BOOLEAN suspended, PVOID stack_addr,
BOOLEAN suspended, ULONG zero_bits,
SIZE_T stack_reserve, SIZE_T stack_commit,
PRTL_THREAD_START_ROUTINE start, void *param,
HANDLE *handle_ptr, CLIENT_ID *id )
@ -181,7 +181,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, SECURITY_DESCRIPTOR *descr,
if (actctx) flags |= THREAD_CREATE_FLAGS_CREATE_SUSPENDED;
status = NtCreateThreadEx( &handle, THREAD_ALL_ACCESS, &attr, process, start, param,
flags, 0, stack_commit, stack_reserve, attr_list );
flags, zero_bits, stack_commit, stack_reserve, attr_list );
if (!status)
{
if (actctx)

View File

@ -783,7 +783,7 @@ NTSTATUS WINAPI RtlCreateTimerQueue(PHANDLE NewTimerQueue)
RtlFreeHeap(GetProcessHeap(), 0, q);
return status;
}
status = RtlCreateUserThread(GetCurrentProcess(), NULL, FALSE, NULL, 0, 0,
status = RtlCreateUserThread(GetCurrentProcess(), NULL, FALSE, 0, 0, 0,
timer_queue_thread_proc, q, &q->thread, NULL);
if (status != STATUS_SUCCESS)
{
@ -1141,7 +1141,7 @@ static NTSTATUS tp_new_worker_thread( struct threadpool *pool )
HANDLE thread;
NTSTATUS status;
status = RtlCreateUserThread( GetCurrentProcess(), NULL, FALSE, NULL, 0, 0,
status = RtlCreateUserThread( GetCurrentProcess(), NULL, FALSE, 0, 0, 0,
threadpool_worker_proc, pool, &thread, NULL );
if (status == STATUS_SUCCESS)
{
@ -1176,7 +1176,7 @@ static NTSTATUS tp_timerqueue_lock( struct threadpool_object *timer )
if (!timerqueue.thread_running)
{
HANDLE thread;
status = RtlCreateUserThread( GetCurrentProcess(), NULL, FALSE, NULL, 0, 0,
status = RtlCreateUserThread( GetCurrentProcess(), NULL, FALSE, 0, 0, 0,
timerqueue_thread_proc, NULL, &thread, NULL );
if (status == STATUS_SUCCESS)
{
@ -1454,7 +1454,7 @@ static NTSTATUS tp_waitqueue_lock( struct threadpool_object *wait )
goto out;
}
status = RtlCreateUserThread( GetCurrentProcess(), NULL, FALSE, NULL, 0, 0,
status = RtlCreateUserThread( GetCurrentProcess(), NULL, FALSE, 0, 0, 0,
waitqueue_thread_proc, bucket, &thread, NULL );
if (status == STATUS_SUCCESS)
{
@ -1592,7 +1592,7 @@ static NTSTATUS tp_ioqueue_lock( struct threadpool_object *io, HANDLE file )
HANDLE thread;
if (!(status = RtlCreateUserThread( GetCurrentProcess(), NULL, FALSE,
NULL, 0, 0, ioqueue_thread_proc, NULL, &thread, NULL )))
0, 0, 0, ioqueue_thread_proc, NULL, &thread, NULL )))
{
ioqueue.thread_running = TRUE;
NtClose( thread );

View File

@ -3958,7 +3958,7 @@ NTSYSAPI NTSTATUS WINAPI RtlCreateTimer(PHANDLE, HANDLE, RTL_WAITORTIMERCALLBAC
NTSYSAPI BOOLEAN WINAPI RtlCreateUnicodeString(PUNICODE_STRING,LPCWSTR);
NTSYSAPI BOOLEAN WINAPI RtlCreateUnicodeStringFromAsciiz(PUNICODE_STRING,LPCSTR);
NTSYSAPI NTSTATUS WINAPI RtlCreateUserProcess(UNICODE_STRING*,ULONG,RTL_USER_PROCESS_PARAMETERS*,SECURITY_DESCRIPTOR*,SECURITY_DESCRIPTOR*,HANDLE,BOOLEAN,HANDLE,HANDLE,RTL_USER_PROCESS_INFORMATION*);
NTSYSAPI NTSTATUS WINAPI RtlCreateUserThread(HANDLE,SECURITY_DESCRIPTOR*,BOOLEAN,PVOID,SIZE_T,SIZE_T,PRTL_THREAD_START_ROUTINE,void*,HANDLE*,CLIENT_ID*);
NTSYSAPI NTSTATUS WINAPI RtlCreateUserThread(HANDLE,SECURITY_DESCRIPTOR*,BOOLEAN,ULONG,SIZE_T,SIZE_T,PRTL_THREAD_START_ROUTINE,void*,HANDLE*,CLIENT_ID*);
NTSYSAPI NTSTATUS WINAPI RtlCreateUserStack(SIZE_T,SIZE_T,ULONG,SIZE_T,SIZE_T,INITIAL_TEB*);
NTSYSAPI NTSTATUS WINAPI RtlCustomCPToUnicodeN(CPTABLEINFO*,WCHAR*,DWORD,DWORD*,const char*,DWORD);
NTSYSAPI void WINAPI RtlDeactivateActivationContext(DWORD,ULONG_PTR);