ntdll: Implement RtlCreateUserStack() and RtlFreeUserStack().

Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2019-06-14 10:32:43 -05:00 committed by Alexandre Julliard
parent 410cf7d24c
commit 90c3b78bec
6 changed files with 64 additions and 13 deletions

View file

@ -3787,6 +3787,7 @@ void __wine_process_init(void)
ANSI_STRING func_name;
UNICODE_STRING nt_name;
void * (CDECL *init_func)(void);
INITIAL_TEB stack;
thread_init();
@ -3838,11 +3839,15 @@ void __wine_process_init(void)
RemoveEntryList( &wm->ldr.InMemoryOrderModuleList );
InsertHeadList( &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList, &wm->ldr.InMemoryOrderModuleList );
if ((status = virtual_alloc_thread_stack( NtCurrentTeb(), 0, 0, NULL )) != STATUS_SUCCESS)
if ((status = virtual_alloc_thread_stack( &stack, 0, 0, NULL )) != STATUS_SUCCESS)
{
ERR( "Main exe initialization for %s failed, status %x\n",
debugstr_w(wm->ldr.FullDllName.Buffer), status );
NtTerminateProcess( GetCurrentProcess(), status );
}
NtCurrentTeb()->Tib.StackBase = stack.StackBase;
NtCurrentTeb()->Tib.StackLimit = stack.StackLimit;
NtCurrentTeb()->DeallocationStack = stack.DeallocationStack;
server_init_process_done();
}

View file

@ -526,6 +526,7 @@
@ stdcall RtlCreateUnicodeStringFromAsciiz(ptr str)
@ 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)
@ stub RtlCustomCPToUnicodeN
@ stub RtlCutoverTimeToSystemTime
@ -644,7 +645,7 @@
@ stdcall RtlFreeSid (ptr)
@ stdcall RtlFreeThreadActivationContextStack()
@ stdcall RtlFreeUnicodeString(ptr)
@ stub RtlFreeUserThreadStack
@ stdcall RtlFreeUserStack(ptr)
@ stdcall RtlGUIDFromString(ptr ptr)
@ stub RtlGenerate8dot3Name
@ stdcall RtlGetAce(ptr long ptr)

View file

@ -175,7 +175,7 @@ extern NTSTATUS virtual_map_section( HANDLE handle, PVOID *addr_ptr, ULONG zero_
pe_image_info_t *image_info ) DECLSPEC_HIDDEN;
extern void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info ) DECLSPEC_HIDDEN;
extern NTSTATUS virtual_create_builtin_view( void *base ) DECLSPEC_HIDDEN;
extern NTSTATUS virtual_alloc_thread_stack( TEB *teb, SIZE_T reserve_size,
extern NTSTATUS virtual_alloc_thread_stack( INITIAL_TEB *stack, SIZE_T reserve_size,
SIZE_T commit_size, SIZE_T *pthread_size ) DECLSPEC_HIDDEN;
extern void virtual_clear_thread_stack( void *stack_end ) DECLSPEC_HIDDEN;
extern BOOL virtual_handle_stack_fault( void *addr ) DECLSPEC_HIDDEN;

View file

@ -415,6 +415,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, SECURITY_DESCRIPTOR *descr,
SIZE_T extra_stack = PTHREAD_STACK_MIN;
data_size_t len = 0;
struct object_attributes *objattr = NULL;
INITIAL_TEB stack;
if (process != NtCurrentProcess())
{
@ -506,9 +507,13 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, SECURITY_DESCRIPTOR *descr,
info->entry_point = start;
info->entry_arg = param;
if ((status = virtual_alloc_thread_stack( teb, stack_reserve, stack_commit, &extra_stack )))
if ((status = virtual_alloc_thread_stack( &stack, stack_reserve, stack_commit, &extra_stack )))
goto error;
teb->Tib.StackBase = stack.StackBase;
teb->Tib.StackLimit = stack.StackLimit;
teb->DeallocationStack = stack.DeallocationStack;
thread_data = (struct ntdll_thread_data *)&teb->GdiTebBatch;
thread_data->request_fd = request_pipe[1];
thread_data->reply_fd = -1;

View file

@ -1927,7 +1927,7 @@ NTSTATUS virtual_create_builtin_view( void *module )
/***********************************************************************
* virtual_alloc_thread_stack
*/
NTSTATUS virtual_alloc_thread_stack( TEB *teb, SIZE_T reserve_size, SIZE_T commit_size, SIZE_T *pthread_size )
NTSTATUS virtual_alloc_thread_stack( INITIAL_TEB *stack, SIZE_T reserve_size, SIZE_T commit_size, SIZE_T *pthread_size )
{
struct file_view *view;
NTSTATUS status;
@ -1981,9 +1981,11 @@ NTSTATUS virtual_alloc_thread_stack( TEB *teb, SIZE_T reserve_size, SIZE_T commi
}
/* note: limit is lower than base since the stack grows down */
teb->DeallocationStack = view->base;
teb->Tib.StackBase = (char *)view->base + view->size;
teb->Tib.StackLimit = (char *)view->base + 2 * page_size;
stack->OldStackBase = 0;
stack->OldStackLimit = 0;
stack->DeallocationStack = view->base;
stack->StackBase = (char *)view->base + view->size;
stack->StackLimit = (char *)view->base + 2 * page_size;
done:
server_leave_uninterrupted_section( &csVirtual, &sigset );
return status;
@ -2004,6 +2006,42 @@ void virtual_clear_thread_stack( void *stack_end )
if (force_exec_prot) mprotect( stack, size, PROT_READ | PROT_WRITE | PROT_EXEC );
}
/**********************************************************************
* RtlCreateUserStack (NTDLL.@)
*/
NTSTATUS WINAPI RtlCreateUserStack( SIZE_T commit, SIZE_T reserve, ULONG zero_bits,
SIZE_T commit_align, SIZE_T reserve_align, INITIAL_TEB *stack )
{
TRACE("commit %#lx, reserve %#lx, zero_bits %u, commit_align %#lx, reserve_align %#lx, stack %p\n",
commit, reserve, zero_bits, commit_align, reserve_align, stack);
if (!commit_align || !reserve_align)
return STATUS_INVALID_PARAMETER;
if (!commit || !reserve)
{
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( NtCurrentTeb()->Peb->ImageBaseAddress );
if (!reserve) reserve = nt->OptionalHeader.SizeOfStackReserve;
if (!commit) commit = nt->OptionalHeader.SizeOfStackCommit;
}
reserve = (reserve + reserve_align - 1) & ~(reserve_align - 1);
commit = (commit + commit_align - 1) & ~(commit_align - 1);
return virtual_alloc_thread_stack( stack, reserve, commit, NULL );
}
/**********************************************************************
* RtlFreeUserStack (NTDLL.@)
*/
void WINAPI RtlFreeUserStack( void *stack )
{
SIZE_T size = 0;
TRACE("stack %p\n", stack);
NtFreeVirtualMemory( NtCurrentProcess(), &stack, &size, MEM_RELEASE );
}
/***********************************************************************
* virtual_handle_fault

View file

@ -2104,11 +2104,11 @@ typedef struct _DIRECTORY_BASIC_INFORMATION {
} DIRECTORY_BASIC_INFORMATION, *PDIRECTORY_BASIC_INFORMATION;
typedef struct _INITIAL_TEB {
PVOID StackBase;
PVOID StackLimit;
PVOID StackCommit;
PVOID StackCommitMax;
PVOID StackReserved;
void *OldStackBase;
void *OldStackLimit;
void *StackBase;
void *StackLimit;
void *DeallocationStack;
} INITIAL_TEB, *PINITIAL_TEB;
typedef enum _PORT_INFORMATION_CLASS {
@ -2618,6 +2618,7 @@ 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 RtlCreateUserStack(SIZE_T,SIZE_T,ULONG,SIZE_T,SIZE_T,INITIAL_TEB*);
NTSYSAPI void WINAPI RtlDeactivateActivationContext(DWORD,ULONG_PTR);
NTSYSAPI PVOID WINAPI RtlDecodePointer(PVOID);
NTSYSAPI NTSTATUS WINAPI RtlDecompressBuffer(USHORT,PUCHAR,ULONG,PUCHAR,ULONG,PULONG);
@ -2691,6 +2692,7 @@ NTSYSAPI void WINAPI RtlFreeOemString(POEM_STRING);
NTSYSAPI DWORD WINAPI RtlFreeSid(PSID);
NTSYSAPI void WINAPI RtlFreeThreadActivationContextStack(void);
NTSYSAPI void WINAPI RtlFreeUnicodeString(PUNICODE_STRING);
NTSYSAPI void WINAPI RtlFreeUserStack(void*);
NTSYSAPI NTSTATUS WINAPI RtlGetAce(PACL,DWORD,LPVOID *);
NTSYSAPI NTSTATUS WINAPI RtlGetActiveActivationContext(HANDLE*);
NTSYSAPI NTSTATUS WINAPI RtlGetCompressionWorkSpaceSize(USHORT,PULONG,PULONG);