Zebediah Figura : ntdll: Implement RtlCreateUserStack() and RtlFreeUserStack().

Alexandre Julliard julliard at winehq.org
Mon Jun 17 15:54:21 CDT 2019


Module: wine
Branch: master
Commit: 90c3b78becee20c944f27be2f0d6f1bc598a7d24
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=90c3b78becee20c944f27be2f0d6f1bc598a7d24

Author: Zebediah Figura <zfigura at codeweavers.com>
Date:   Fri Jun 14 10:32:43 2019 -0500

ntdll: Implement RtlCreateUserStack() and RtlFreeUserStack().

Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/loader.c     |  7 ++++++-
 dlls/ntdll/ntdll.spec   |  3 ++-
 dlls/ntdll/ntdll_misc.h |  2 +-
 dlls/ntdll/thread.c     |  7 ++++++-
 dlls/ntdll/virtual.c    | 46 ++++++++++++++++++++++++++++++++++++++++++----
 include/winternl.h      | 12 +++++++-----
 6 files changed, 64 insertions(+), 13 deletions(-)

diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 3f422a9..3d747ed 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -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();
 }
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index aeb9735..e0def22 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -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)
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index f8c377e..f847503 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -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;
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index 96aa6be..f837062 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -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;
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 86377af..5c12d87 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -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
diff --git a/include/winternl.h b/include/winternl.h
index e7f89b0..b87aa22 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -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);




More information about the wine-cvs mailing list