ntdll: Move TEB allocation to the common code.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
9650f1d3a1
commit
bd9a1e23f2
|
@ -79,9 +79,8 @@ extern LPCSTR debugstr_ObjectAttributes(const OBJECT_ATTRIBUTES *oa) DECLSPEC_HI
|
||||||
/* init routines */
|
/* init routines */
|
||||||
extern SIZE_T signal_stack_size DECLSPEC_HIDDEN;
|
extern SIZE_T signal_stack_size DECLSPEC_HIDDEN;
|
||||||
extern SIZE_T signal_stack_mask DECLSPEC_HIDDEN;
|
extern SIZE_T signal_stack_mask DECLSPEC_HIDDEN;
|
||||||
extern SIZE_T signal_stack_align DECLSPEC_HIDDEN;
|
|
||||||
extern void signal_init_threading(void) DECLSPEC_HIDDEN;
|
extern void signal_init_threading(void) DECLSPEC_HIDDEN;
|
||||||
extern NTSTATUS signal_alloc_thread( TEB **teb ) DECLSPEC_HIDDEN;
|
extern NTSTATUS signal_alloc_thread( TEB *teb ) DECLSPEC_HIDDEN;
|
||||||
extern void signal_free_thread( TEB *teb ) DECLSPEC_HIDDEN;
|
extern void signal_free_thread( TEB *teb ) DECLSPEC_HIDDEN;
|
||||||
extern void signal_init_thread( TEB *teb ) DECLSPEC_HIDDEN;
|
extern void signal_init_thread( TEB *teb ) DECLSPEC_HIDDEN;
|
||||||
extern void signal_init_process(void) DECLSPEC_HIDDEN;
|
extern void signal_init_process(void) DECLSPEC_HIDDEN;
|
||||||
|
@ -201,6 +200,8 @@ extern NTSTATUS virtual_map_section( HANDLE handle, PVOID *addr_ptr, unsigned sh
|
||||||
ULONG protect, pe_image_info_t *image_info ) DECLSPEC_HIDDEN;
|
ULONG protect, pe_image_info_t *image_info ) DECLSPEC_HIDDEN;
|
||||||
extern void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *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_create_builtin_view( void *base ) DECLSPEC_HIDDEN;
|
||||||
|
extern NTSTATUS virtual_alloc_teb( TEB **teb ) DECLSPEC_HIDDEN;
|
||||||
|
extern void virtual_free_teb( TEB *teb ) DECLSPEC_HIDDEN;
|
||||||
extern NTSTATUS virtual_alloc_thread_stack( INITIAL_TEB *stack, 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;
|
SIZE_T commit_size, SIZE_T *pthread_size ) DECLSPEC_HIDDEN;
|
||||||
extern void virtual_clear_thread_stack( void *stack_end ) DECLSPEC_HIDDEN;
|
extern void virtual_clear_thread_stack( void *stack_end ) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -964,19 +964,9 @@ void signal_init_threading(void)
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* signal_alloc_thread
|
* signal_alloc_thread
|
||||||
*/
|
*/
|
||||||
NTSTATUS signal_alloc_thread( TEB **teb )
|
NTSTATUS signal_alloc_thread( TEB *teb )
|
||||||
{
|
{
|
||||||
SIZE_T size = signal_stack_mask + 1;
|
return STATUS_SUCCESS;
|
||||||
NTSTATUS status;
|
|
||||||
|
|
||||||
*teb = NULL;
|
|
||||||
if (!(status = virtual_alloc_aligned( (void **)teb, 0, &size, MEM_COMMIT | MEM_TOP_DOWN,
|
|
||||||
PAGE_READWRITE, signal_stack_align )))
|
|
||||||
{
|
|
||||||
(*teb)->Tib.Self = &(*teb)->Tib;
|
|
||||||
(*teb)->Tib.ExceptionList = (void *)~0UL;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -985,9 +975,6 @@ NTSTATUS signal_alloc_thread( TEB **teb )
|
||||||
*/
|
*/
|
||||||
void signal_free_thread( TEB *teb )
|
void signal_free_thread( TEB *teb )
|
||||||
{
|
{
|
||||||
SIZE_T size = 0;
|
|
||||||
|
|
||||||
NtFreeVirtualMemory( NtCurrentProcess(), (void **)&teb, &size, MEM_RELEASE );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1261,20 +1261,9 @@ void signal_init_threading(void)
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* signal_alloc_thread
|
* signal_alloc_thread
|
||||||
*/
|
*/
|
||||||
NTSTATUS signal_alloc_thread( TEB **teb )
|
NTSTATUS signal_alloc_thread( TEB *teb )
|
||||||
{
|
{
|
||||||
SIZE_T size;
|
return STATUS_SUCCESS;
|
||||||
NTSTATUS status;
|
|
||||||
|
|
||||||
size = teb_size + max( MINSIGSTKSZ, 8192 );
|
|
||||||
*teb = NULL;
|
|
||||||
if (!(status = virtual_alloc_aligned( (void **)teb, 0, &size, MEM_COMMIT | MEM_TOP_DOWN,
|
|
||||||
PAGE_READWRITE, 13 )))
|
|
||||||
{
|
|
||||||
(*teb)->Tib.Self = &(*teb)->Tib;
|
|
||||||
(*teb)->Tib.ExceptionList = (void *)~0UL;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1283,9 +1272,6 @@ NTSTATUS signal_alloc_thread( TEB **teb )
|
||||||
*/
|
*/
|
||||||
void signal_free_thread( TEB *teb )
|
void signal_free_thread( TEB *teb )
|
||||||
{
|
{
|
||||||
SIZE_T size = 0;
|
|
||||||
|
|
||||||
NtFreeVirtualMemory( NtCurrentProcess(), (void **)&teb, &size, MEM_RELEASE );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2436,46 +2436,6 @@ static void ldt_set_entry( WORD sel, LDT_ENTRY entry )
|
||||||
LDT_FLAGS_ALLOCATED);
|
LDT_FLAGS_ALLOCATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
WORD ldt_alloc_fs( TEB *teb, int first_thread )
|
|
||||||
{
|
|
||||||
LDT_ENTRY entry;
|
|
||||||
int idx;
|
|
||||||
|
|
||||||
if (gdt_fs_sel) return gdt_fs_sel;
|
|
||||||
|
|
||||||
entry = ldt_make_entry( teb, teb_size - 1, LDT_FLAGS_DATA | LDT_FLAGS_32BIT );
|
|
||||||
|
|
||||||
if (first_thread) /* no locking for first thread */
|
|
||||||
{
|
|
||||||
/* leave some space if libc is using the LDT for %gs */
|
|
||||||
if (!is_gdt_sel( get_gs() )) first_ldt_entry = 512;
|
|
||||||
idx = first_ldt_entry;
|
|
||||||
ldt_set_entry( (idx << 3) | 7, entry );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ldt_lock();
|
|
||||||
for (idx = first_ldt_entry; idx < LDT_SIZE; idx++)
|
|
||||||
{
|
|
||||||
if (__wine_ldt_copy.flags[idx]) continue;
|
|
||||||
ldt_set_entry( (idx << 3) | 7, entry );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ldt_unlock();
|
|
||||||
if (idx == LDT_SIZE) return 0;
|
|
||||||
}
|
|
||||||
return (idx << 3) | 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ldt_free_fs( WORD sel )
|
|
||||||
{
|
|
||||||
if (sel == gdt_fs_sel) return;
|
|
||||||
|
|
||||||
ldt_lock();
|
|
||||||
__wine_ldt_copy.flags[sel >> 3] = 0;
|
|
||||||
ldt_unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ldt_set_fs( WORD sel, TEB *teb )
|
static void ldt_set_fs( WORD sel, TEB *teb )
|
||||||
{
|
{
|
||||||
if (sel == gdt_fs_sel)
|
if (sel == gdt_fs_sel)
|
||||||
|
@ -2588,30 +2548,41 @@ void signal_init_threading(void)
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* signal_alloc_thread
|
* signal_alloc_thread
|
||||||
*/
|
*/
|
||||||
NTSTATUS signal_alloc_thread( TEB **teb )
|
NTSTATUS signal_alloc_thread( TEB *teb )
|
||||||
{
|
{
|
||||||
struct x86_thread_data *thread_data;
|
struct x86_thread_data *thread_data = (struct x86_thread_data *)teb->SystemReserved2;
|
||||||
SIZE_T size = signal_stack_mask + 1;
|
|
||||||
void *addr = NULL;
|
|
||||||
NTSTATUS status;
|
|
||||||
static int first_thread = 1;
|
|
||||||
|
|
||||||
if (!(status = virtual_alloc_aligned( &addr, 0, &size, MEM_COMMIT | MEM_TOP_DOWN,
|
if (!gdt_fs_sel)
|
||||||
PAGE_READWRITE, signal_stack_align )))
|
|
||||||
{
|
{
|
||||||
*teb = addr;
|
static int first_thread = 1;
|
||||||
(*teb)->Tib.Self = &(*teb)->Tib;
|
int idx;
|
||||||
(*teb)->Tib.ExceptionList = (void *)~0UL;
|
LDT_ENTRY entry = ldt_make_entry( teb, teb_size - 1, LDT_FLAGS_DATA | LDT_FLAGS_32BIT );
|
||||||
thread_data = (struct x86_thread_data *)(*teb)->SystemReserved2;
|
|
||||||
if (!(thread_data->fs = ldt_alloc_fs( *teb, first_thread )))
|
if (first_thread) /* no locking for first thread */
|
||||||
{
|
{
|
||||||
size = 0;
|
/* leave some space if libc is using the LDT for %gs */
|
||||||
NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE );
|
if (!is_gdt_sel( get_gs() )) first_ldt_entry = 512;
|
||||||
status = STATUS_TOO_MANY_THREADS;
|
idx = first_ldt_entry;
|
||||||
|
ldt_set_entry( (idx << 3) | 7, entry );
|
||||||
|
first_thread = 0;
|
||||||
}
|
}
|
||||||
first_thread = 0;
|
else
|
||||||
|
{
|
||||||
|
ldt_lock();
|
||||||
|
for (idx = first_ldt_entry; idx < LDT_SIZE; idx++)
|
||||||
|
{
|
||||||
|
if (__wine_ldt_copy.flags[idx]) continue;
|
||||||
|
ldt_set_entry( (idx << 3) | 7, entry );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ldt_unlock();
|
||||||
|
if (idx == LDT_SIZE) return STATUS_TOO_MANY_THREADS;
|
||||||
|
}
|
||||||
|
thread_data->fs = (idx << 3) | 7;
|
||||||
}
|
}
|
||||||
return status;
|
else thread_data->fs = gdt_fs_sel;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2620,11 +2591,13 @@ NTSTATUS signal_alloc_thread( TEB **teb )
|
||||||
*/
|
*/
|
||||||
void signal_free_thread( TEB *teb )
|
void signal_free_thread( TEB *teb )
|
||||||
{
|
{
|
||||||
SIZE_T size = 0;
|
|
||||||
struct x86_thread_data *thread_data = (struct x86_thread_data *)teb->SystemReserved2;
|
struct x86_thread_data *thread_data = (struct x86_thread_data *)teb->SystemReserved2;
|
||||||
|
|
||||||
ldt_free_fs( thread_data->fs );
|
if (gdt_fs_sel) return;
|
||||||
NtFreeVirtualMemory( NtCurrentProcess(), (void **)&teb, &size, MEM_RELEASE );
|
|
||||||
|
ldt_lock();
|
||||||
|
__wine_ldt_copy.flags[thread_data->fs >> 3] = 0;
|
||||||
|
ldt_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1025,19 +1025,9 @@ void signal_init_threading(void)
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* signal_alloc_thread
|
* signal_alloc_thread
|
||||||
*/
|
*/
|
||||||
NTSTATUS signal_alloc_thread( TEB **teb )
|
NTSTATUS signal_alloc_thread( TEB *teb )
|
||||||
{
|
{
|
||||||
SIZE_T size = signal_stack_mask + 1;
|
return STATUS_SUCCESS;
|
||||||
NTSTATUS status;
|
|
||||||
|
|
||||||
*teb = NULL;
|
|
||||||
if (!(status = virtual_alloc_aligned( (void **)teb, 0, &size, MEM_COMMIT | MEM_TOP_DOWN,
|
|
||||||
PAGE_READWRITE, signal_stack_align )))
|
|
||||||
{
|
|
||||||
(*teb)->Tib.Self = &(*teb)->Tib;
|
|
||||||
(*teb)->Tib.ExceptionList = (void *)~0UL;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1046,9 +1036,6 @@ NTSTATUS signal_alloc_thread( TEB **teb )
|
||||||
*/
|
*/
|
||||||
void signal_free_thread( TEB *teb )
|
void signal_free_thread( TEB *teb )
|
||||||
{
|
{
|
||||||
SIZE_T size = 0;
|
|
||||||
|
|
||||||
NtFreeVirtualMemory( NtCurrentProcess(), (void **)&teb, &size, MEM_RELEASE );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3117,19 +3117,9 @@ void signal_init_threading(void)
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* signal_alloc_thread
|
* signal_alloc_thread
|
||||||
*/
|
*/
|
||||||
NTSTATUS signal_alloc_thread( TEB **teb )
|
NTSTATUS signal_alloc_thread( TEB *teb )
|
||||||
{
|
{
|
||||||
SIZE_T size = signal_stack_mask + 1;
|
return STATUS_SUCCESS;
|
||||||
NTSTATUS status;
|
|
||||||
|
|
||||||
*teb = NULL;
|
|
||||||
if (!(status = virtual_alloc_aligned( (void **)teb, 0, &size, MEM_COMMIT | MEM_TOP_DOWN,
|
|
||||||
PAGE_READWRITE, signal_stack_align )))
|
|
||||||
{
|
|
||||||
(*teb)->Tib.Self = &(*teb)->Tib;
|
|
||||||
(*teb)->Tib.ExceptionList = (void *)~0UL;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3138,9 +3128,6 @@ NTSTATUS signal_alloc_thread( TEB **teb )
|
||||||
*/
|
*/
|
||||||
void signal_free_thread( TEB *teb )
|
void signal_free_thread( TEB *teb )
|
||||||
{
|
{
|
||||||
SIZE_T size = 0;
|
|
||||||
|
|
||||||
NtFreeVirtualMemory( NtCurrentProcess(), (void **)&teb, &size, MEM_RELEASE );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
|
|
@ -285,11 +285,9 @@ TEB *thread_init(void)
|
||||||
/* allocate and initialize the initial TEB */
|
/* allocate and initialize the initial TEB */
|
||||||
|
|
||||||
signal_init_threading();
|
signal_init_threading();
|
||||||
signal_alloc_thread( &teb );
|
virtual_alloc_teb( &teb );
|
||||||
teb->Peb = peb;
|
teb->Peb = peb;
|
||||||
teb->Tib.StackBase = (void *)~0UL;
|
teb->Tib.StackBase = (void *)~0UL;
|
||||||
teb->StaticUnicodeString.Buffer = teb->StaticUnicodeBuffer;
|
|
||||||
teb->StaticUnicodeString.MaximumLength = sizeof(teb->StaticUnicodeBuffer);
|
|
||||||
|
|
||||||
thread_data = (struct ntdll_thread_data *)&teb->GdiTebBatch;
|
thread_data = (struct ntdll_thread_data *)&teb->GdiTebBatch;
|
||||||
thread_data->request_fd = -1;
|
thread_data->request_fd = -1;
|
||||||
|
@ -320,28 +318,6 @@ TEB *thread_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* free_thread_data
|
|
||||||
*/
|
|
||||||
static void free_thread_data( TEB *teb )
|
|
||||||
{
|
|
||||||
struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)&teb->GdiTebBatch;
|
|
||||||
SIZE_T size;
|
|
||||||
|
|
||||||
if (teb->DeallocationStack)
|
|
||||||
{
|
|
||||||
size = 0;
|
|
||||||
NtFreeVirtualMemory( GetCurrentProcess(), &teb->DeallocationStack, &size, MEM_RELEASE );
|
|
||||||
}
|
|
||||||
if (thread_data->start_stack)
|
|
||||||
{
|
|
||||||
size = 0;
|
|
||||||
NtFreeVirtualMemory( GetCurrentProcess(), &thread_data->start_stack, &size, MEM_RELEASE );
|
|
||||||
}
|
|
||||||
signal_free_thread( teb );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* abort_thread
|
* abort_thread
|
||||||
*/
|
*/
|
||||||
|
@ -404,7 +380,7 @@ void WINAPI RtlExitUserThread( ULONG status )
|
||||||
if (thread_data->pthread_id)
|
if (thread_data->pthread_id)
|
||||||
{
|
{
|
||||||
pthread_join( thread_data->pthread_id, NULL );
|
pthread_join( thread_data->pthread_id, NULL );
|
||||||
free_thread_data( teb );
|
virtual_free_teb( teb );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,13 +515,11 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, SECURITY_DESCRIPTOR *descr,
|
||||||
|
|
||||||
pthread_sigmask( SIG_BLOCK, &server_block_set, &sigset );
|
pthread_sigmask( SIG_BLOCK, &server_block_set, &sigset );
|
||||||
|
|
||||||
if ((status = signal_alloc_thread( &teb ))) goto error;
|
if ((status = virtual_alloc_teb( &teb ))) goto error;
|
||||||
|
|
||||||
teb->Peb = NtCurrentTeb()->Peb;
|
teb->Peb = NtCurrentTeb()->Peb;
|
||||||
teb->ClientId.UniqueProcess = ULongToHandle(GetCurrentProcessId());
|
teb->ClientId.UniqueProcess = ULongToHandle(GetCurrentProcessId());
|
||||||
teb->ClientId.UniqueThread = ULongToHandle(tid);
|
teb->ClientId.UniqueThread = ULongToHandle(tid);
|
||||||
teb->StaticUnicodeString.Buffer = teb->StaticUnicodeBuffer;
|
|
||||||
teb->StaticUnicodeString.MaximumLength = sizeof(teb->StaticUnicodeBuffer);
|
|
||||||
|
|
||||||
/* create default activation context frame for new thread */
|
/* create default activation context frame for new thread */
|
||||||
RtlGetActiveActivationContext(&actctx);
|
RtlGetActiveActivationContext(&actctx);
|
||||||
|
@ -602,7 +576,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, SECURITY_DESCRIPTOR *descr,
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (teb) free_thread_data( teb );
|
if (teb) virtual_free_teb( teb );
|
||||||
if (handle) NtClose( handle );
|
if (handle) NtClose( handle );
|
||||||
pthread_sigmask( SIG_SETMASK, &sigset, NULL );
|
pthread_sigmask( SIG_SETMASK, &sigset, NULL );
|
||||||
close( request_pipe[1] );
|
close( request_pipe[1] );
|
||||||
|
|
|
@ -162,7 +162,7 @@ static const BOOL is_win64 = (sizeof(void *) > sizeof(int));
|
||||||
|
|
||||||
SIZE_T signal_stack_size = 0;
|
SIZE_T signal_stack_size = 0;
|
||||||
SIZE_T signal_stack_mask = 0;
|
SIZE_T signal_stack_mask = 0;
|
||||||
SIZE_T signal_stack_align = 0;
|
static SIZE_T signal_stack_align;
|
||||||
|
|
||||||
#define ROUND_ADDR(addr,mask) \
|
#define ROUND_ADDR(addr,mask) \
|
||||||
((void *)((UINT_PTR)(addr) & ~(UINT_PTR)(mask)))
|
((void *)((UINT_PTR)(addr) & ~(UINT_PTR)(mask)))
|
||||||
|
@ -2093,6 +2093,58 @@ NTSTATUS virtual_create_builtin_view( void *module )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* virtual_alloc_teb
|
||||||
|
*/
|
||||||
|
NTSTATUS virtual_alloc_teb( TEB **ret_teb )
|
||||||
|
{
|
||||||
|
SIZE_T size = signal_stack_mask + 1;
|
||||||
|
void *addr = NULL;
|
||||||
|
TEB *teb;
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
if ((status = virtual_alloc_aligned( &addr, 0, &size, MEM_COMMIT | MEM_TOP_DOWN,
|
||||||
|
PAGE_READWRITE, signal_stack_align )))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
*ret_teb = teb = addr;
|
||||||
|
teb->Tib.Self = &teb->Tib;
|
||||||
|
teb->Tib.ExceptionList = (void *)~0UL;
|
||||||
|
teb->StaticUnicodeString.Buffer = teb->StaticUnicodeBuffer;
|
||||||
|
teb->StaticUnicodeString.MaximumLength = sizeof(teb->StaticUnicodeBuffer);
|
||||||
|
if ((status = signal_alloc_thread( teb )))
|
||||||
|
{
|
||||||
|
size = 0;
|
||||||
|
NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE );
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* virtual_free_teb
|
||||||
|
*/
|
||||||
|
void virtual_free_teb( TEB *teb )
|
||||||
|
{
|
||||||
|
struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)&teb->GdiTebBatch;
|
||||||
|
SIZE_T size;
|
||||||
|
|
||||||
|
signal_free_thread( teb );
|
||||||
|
if (teb->DeallocationStack)
|
||||||
|
{
|
||||||
|
size = 0;
|
||||||
|
NtFreeVirtualMemory( GetCurrentProcess(), &teb->DeallocationStack, &size, MEM_RELEASE );
|
||||||
|
}
|
||||||
|
if (thread_data->start_stack)
|
||||||
|
{
|
||||||
|
size = 0;
|
||||||
|
NtFreeVirtualMemory( GetCurrentProcess(), &thread_data->start_stack, &size, MEM_RELEASE );
|
||||||
|
}
|
||||||
|
size = 0;
|
||||||
|
NtFreeVirtualMemory( NtCurrentProcess(), (void **)&teb, &size, MEM_RELEASE );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* virtual_alloc_thread_stack
|
* virtual_alloc_thread_stack
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue