ntdll: Run the entire thread initialization code on the thread stack on remaining platforms.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
32c2cfb861
commit
c3dd077d34
|
@ -57,7 +57,6 @@ extern NTSTATUS context_to_server( context_t *to, const CONTEXT *from ) DECLSPEC
|
||||||
extern NTSTATUS context_from_server( CONTEXT *to, const context_t *from ) DECLSPEC_HIDDEN;
|
extern NTSTATUS context_from_server( CONTEXT *to, const context_t *from ) DECLSPEC_HIDDEN;
|
||||||
extern NTSTATUS set_thread_context( HANDLE handle, const CONTEXT *context, BOOL *self ) DECLSPEC_HIDDEN;
|
extern NTSTATUS set_thread_context( HANDLE handle, const CONTEXT *context, BOOL *self ) DECLSPEC_HIDDEN;
|
||||||
extern NTSTATUS get_thread_context( HANDLE handle, CONTEXT *context, BOOL *self ) DECLSPEC_HIDDEN;
|
extern NTSTATUS get_thread_context( HANDLE handle, CONTEXT *context, BOOL *self ) DECLSPEC_HIDDEN;
|
||||||
extern void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) DECLSPEC_NORETURN DECLSPEC_HIDDEN;
|
|
||||||
|
|
||||||
/* debug helpers */
|
/* debug helpers */
|
||||||
extern LPCSTR debugstr_us( const UNICODE_STRING *str ) DECLSPEC_HIDDEN;
|
extern LPCSTR debugstr_us( const UNICODE_STRING *str ) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -1013,63 +1013,6 @@ void signal_init_process(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct startup_info
|
|
||||||
{
|
|
||||||
LPTHREAD_START_ROUTINE entry;
|
|
||||||
void *arg;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void thread_startup( void *param )
|
|
||||||
{
|
|
||||||
struct startup_info *info = param;
|
|
||||||
call_thread_entry_point( info->entry, info->arg );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* signal_start_thread
|
|
||||||
*/
|
|
||||||
void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend )
|
|
||||||
{
|
|
||||||
CONTEXT context = { 0 };
|
|
||||||
struct startup_info info = { entry, arg };
|
|
||||||
|
|
||||||
/* build the initial context */
|
|
||||||
context.ContextFlags = CONTEXT_FULL;
|
|
||||||
context.R0 = (DWORD)entry;
|
|
||||||
context.R1 = (DWORD)arg;
|
|
||||||
context.Sp = (DWORD)NtCurrentTeb()->Tib.StackBase;
|
|
||||||
context.Pc = (DWORD)call_thread_entry_point;
|
|
||||||
|
|
||||||
if (suspend) wait_suspend( &context );
|
|
||||||
|
|
||||||
wine_call_on_stack( attach_dlls, (void *)1, NtCurrentTeb()->Tib.StackBase );
|
|
||||||
TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg );
|
|
||||||
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
|
||||||
* signal_start_process
|
|
||||||
*/
|
|
||||||
void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
|
|
||||||
{
|
|
||||||
CONTEXT context = { 0 };
|
|
||||||
|
|
||||||
/* build the initial context */
|
|
||||||
context.ContextFlags = CONTEXT_FULL;
|
|
||||||
context.R0 = (DWORD)kernel32_start_process;
|
|
||||||
context.R1 = (DWORD)entry;
|
|
||||||
context.Sp = (DWORD)NtCurrentTeb()->Tib.StackBase;
|
|
||||||
context.Pc = (DWORD)call_thread_entry_point;
|
|
||||||
|
|
||||||
if (suspend) wait_suspend( &context );
|
|
||||||
|
|
||||||
wine_call_on_stack( attach_dlls, (void *)1, (char *)NtCurrentTeb()->Tib.StackBase );
|
|
||||||
set_cpu_context( &context );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* __wine_enter_vm86 (NTDLL.@)
|
* __wine_enter_vm86 (NTDLL.@)
|
||||||
*/
|
*/
|
||||||
|
@ -1250,10 +1193,11 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer,
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* call_thread_entry_point
|
* call_thread_entry_point
|
||||||
*/
|
*/
|
||||||
void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg )
|
static void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg )
|
||||||
{
|
{
|
||||||
__TRY
|
__TRY
|
||||||
{
|
{
|
||||||
|
TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg );
|
||||||
exit_thread( entry( arg ));
|
exit_thread( entry( arg ));
|
||||||
}
|
}
|
||||||
__EXCEPT(unhandled_exception_filter)
|
__EXCEPT(unhandled_exception_filter)
|
||||||
|
@ -1264,6 +1208,63 @@ void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg )
|
||||||
abort(); /* should not be reached */
|
abort(); /* should not be reached */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct startup_info
|
||||||
|
{
|
||||||
|
LPTHREAD_START_ROUTINE entry;
|
||||||
|
void *arg;
|
||||||
|
BOOL suspend;
|
||||||
|
};
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* thread_startup
|
||||||
|
*/
|
||||||
|
static void thread_startup( void *param )
|
||||||
|
{
|
||||||
|
CONTEXT context = { 0 };
|
||||||
|
struct startup_info *info = param;
|
||||||
|
|
||||||
|
/* build the initial context */
|
||||||
|
context.ContextFlags = CONTEXT_FULL;
|
||||||
|
context.R0 = (DWORD)info->entry;
|
||||||
|
context.R1 = (DWORD)info->arg;
|
||||||
|
context.Sp = (DWORD)NtCurrentTeb()->Tib.StackBase;
|
||||||
|
context.Pc = (DWORD)call_thread_entry_point;
|
||||||
|
|
||||||
|
if (info->suspend) wait_suspend( &context );
|
||||||
|
attach_dlls( &context );
|
||||||
|
|
||||||
|
set_cpu_context( &context );
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* signal_start_thread
|
||||||
|
*
|
||||||
|
* Thread startup sequence:
|
||||||
|
* signal_start_thread()
|
||||||
|
* -> thread_startup()
|
||||||
|
* -> call_thread_entry_point()
|
||||||
|
*/
|
||||||
|
void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend )
|
||||||
|
{
|
||||||
|
struct startup_info info = { entry, arg, suspend };
|
||||||
|
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* signal_start_process
|
||||||
|
*
|
||||||
|
* Process startup sequence:
|
||||||
|
* signal_start_process()
|
||||||
|
* -> thread_startup()
|
||||||
|
* -> call_thread_entry_point()
|
||||||
|
* -> kernel32_start_process()
|
||||||
|
*/
|
||||||
|
void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
|
||||||
|
{
|
||||||
|
struct startup_info info = { kernel32_start_process, entry, suspend };
|
||||||
|
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* RtlExitUserThread (NTDLL.@)
|
* RtlExitUserThread (NTDLL.@)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -884,72 +884,6 @@ void signal_init_process(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct startup_info
|
|
||||||
{
|
|
||||||
LPTHREAD_START_ROUTINE entry;
|
|
||||||
void *arg;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void thread_startup( void *param )
|
|
||||||
{
|
|
||||||
struct startup_info *info = param;
|
|
||||||
call_thread_entry_point( info->entry, info->arg );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* signal_start_thread
|
|
||||||
*/
|
|
||||||
void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend )
|
|
||||||
{
|
|
||||||
CONTEXT context = { 0 };
|
|
||||||
struct startup_info info = { entry, arg };
|
|
||||||
|
|
||||||
/* build the initial context */
|
|
||||||
context.ContextFlags = CONTEXT_FULL;
|
|
||||||
context.X0 = (DWORD_PTR)entry;
|
|
||||||
context.X1 = (DWORD_PTR)arg;
|
|
||||||
context.Sp = (DWORD_PTR)NtCurrentTeb()->Tib.StackBase;
|
|
||||||
context.Pc = (DWORD_PTR)call_thread_entry_point;
|
|
||||||
|
|
||||||
if (suspend) wait_suspend( &context );
|
|
||||||
|
|
||||||
wine_call_on_stack( attach_dlls, (void *)1, NtCurrentTeb()->Tib.StackBase );
|
|
||||||
TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg );
|
|
||||||
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* start_process
|
|
||||||
*/
|
|
||||||
static void start_process( void *arg )
|
|
||||||
{
|
|
||||||
CONTEXT *context = arg;
|
|
||||||
call_thread_entry_point( (LPTHREAD_START_ROUTINE)context->X0, (void *)context->X1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************
|
|
||||||
* signal_start_process
|
|
||||||
*/
|
|
||||||
void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
|
|
||||||
{
|
|
||||||
CONTEXT context = { 0 };
|
|
||||||
|
|
||||||
/* build the initial context */
|
|
||||||
context.ContextFlags = CONTEXT_FULL;
|
|
||||||
context.X0 = (DWORD_PTR)kernel32_start_process;
|
|
||||||
context.X1 = (DWORD_PTR)entry;
|
|
||||||
context.Sp = (DWORD_PTR)NtCurrentTeb()->Tib.StackBase;
|
|
||||||
context.Pc = (DWORD_PTR)call_thread_entry_point;
|
|
||||||
|
|
||||||
if (suspend) wait_suspend( &context );
|
|
||||||
|
|
||||||
wine_call_on_stack( attach_dlls, (void *)1, (void *)context.Sp );
|
|
||||||
wine_switch_to_stack( start_process, &context, (void *)context.Sp );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* __wine_enter_vm86 (NTDLL.@)
|
* __wine_enter_vm86 (NTDLL.@)
|
||||||
*/
|
*/
|
||||||
|
@ -1002,10 +936,11 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer,
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* call_thread_entry_point
|
* call_thread_entry_point
|
||||||
*/
|
*/
|
||||||
void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg )
|
static void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg )
|
||||||
{
|
{
|
||||||
__TRY
|
__TRY
|
||||||
{
|
{
|
||||||
|
TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg );
|
||||||
exit_thread( entry( arg ));
|
exit_thread( entry( arg ));
|
||||||
}
|
}
|
||||||
__EXCEPT(unhandled_exception_filter)
|
__EXCEPT(unhandled_exception_filter)
|
||||||
|
@ -1016,6 +951,63 @@ void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg )
|
||||||
abort(); /* should not be reached */
|
abort(); /* should not be reached */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct startup_info
|
||||||
|
{
|
||||||
|
LPTHREAD_START_ROUTINE entry;
|
||||||
|
void *arg;
|
||||||
|
BOOL suspend;
|
||||||
|
};
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* thread_startup
|
||||||
|
*/
|
||||||
|
static void thread_startup( void *param )
|
||||||
|
{
|
||||||
|
CONTEXT context = { 0 };
|
||||||
|
struct startup_info *info = param;
|
||||||
|
|
||||||
|
/* build the initial context */
|
||||||
|
context.ContextFlags = CONTEXT_FULL;
|
||||||
|
context.X0 = (DWORD_PTR)info->entry;
|
||||||
|
context.X1 = (DWORD_PTR)info->arg;
|
||||||
|
context.Sp = (DWORD_PTR)NtCurrentTeb()->Tib.StackBase;
|
||||||
|
context.Pc = (DWORD_PTR)call_thread_entry_point;
|
||||||
|
|
||||||
|
if (info->suspend) wait_suspend( &context );
|
||||||
|
attach_dlls( &context );
|
||||||
|
|
||||||
|
call_thread_entry_point( (LPTHREAD_START_ROUTINE)context.X0, (void *)context.X1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* signal_start_thread
|
||||||
|
*
|
||||||
|
* Thread startup sequence:
|
||||||
|
* signal_start_thread()
|
||||||
|
* -> thread_startup()
|
||||||
|
* -> call_thread_entry_point()
|
||||||
|
*/
|
||||||
|
void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend )
|
||||||
|
{
|
||||||
|
struct startup_info info = { entry, arg, suspend };
|
||||||
|
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* signal_start_process
|
||||||
|
*
|
||||||
|
* Process startup sequence:
|
||||||
|
* signal_start_process()
|
||||||
|
* -> thread_startup()
|
||||||
|
* -> call_thread_entry_point()
|
||||||
|
* -> kernel32_start_process()
|
||||||
|
*/
|
||||||
|
void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
|
||||||
|
{
|
||||||
|
struct startup_info info = { kernel32_start_process, entry, suspend };
|
||||||
|
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* RtlExitUserThread (NTDLL.@)
|
* RtlExitUserThread (NTDLL.@)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1086,72 +1086,6 @@ void signal_init_process(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct startup_info
|
|
||||||
{
|
|
||||||
LPTHREAD_START_ROUTINE entry;
|
|
||||||
void *arg;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void thread_startup( void *param )
|
|
||||||
{
|
|
||||||
struct startup_info *info = param;
|
|
||||||
call_thread_entry_point( info->entry, info->arg );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* signal_start_thread
|
|
||||||
*/
|
|
||||||
void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend )
|
|
||||||
{
|
|
||||||
CONTEXT context = { 0 };
|
|
||||||
struct startup_info info = { entry, arg };
|
|
||||||
|
|
||||||
/* build the initial context */
|
|
||||||
context.ContextFlags = CONTEXT_FULL;
|
|
||||||
context.Gpr1 = (DWORD)NtCurrentTeb()->Tib.StackBase;
|
|
||||||
context.Gpr3 = (DWORD)entry;
|
|
||||||
context.Gpr4 = (DWORD)arg;
|
|
||||||
context.Iar = (DWORD)call_thread_entry_point;
|
|
||||||
|
|
||||||
if (suspend) wait_suspend( &context );
|
|
||||||
|
|
||||||
wine_call_on_stack( attach_dlls, (void *)1, NtCurrentTeb()->Tib.StackBase );
|
|
||||||
TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg );
|
|
||||||
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* start_process
|
|
||||||
*/
|
|
||||||
static void start_process( void *arg )
|
|
||||||
{
|
|
||||||
CONTEXT *context = arg;
|
|
||||||
call_thread_entry_point( (LPTHREAD_START_ROUTINE)context->Gpr3, (void *)context->Gpr4 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************
|
|
||||||
* signal_start_process
|
|
||||||
*/
|
|
||||||
void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
|
|
||||||
{
|
|
||||||
CONTEXT context = { 0 };
|
|
||||||
|
|
||||||
/* build the initial context */
|
|
||||||
context.ContextFlags = CONTEXT_FULL;
|
|
||||||
context.Gpr1 = (DWORD)NtCurrentTeb()->Tib.StackBase;
|
|
||||||
context.Gpr3 = (DWORD)kernel32_start_process;
|
|
||||||
context.Gpr4 = (DWORD)entry;
|
|
||||||
context.Iar = (DWORD)call_thread_entry_point;
|
|
||||||
|
|
||||||
if (suspend) wait_suspend( &context );
|
|
||||||
|
|
||||||
wine_call_on_stack( attach_dlls, (void *)1, (void *)context.Gpr1 );
|
|
||||||
wine_switch_to_stack( start_process, &context, (void *)context.Gpr1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* __wine_enter_vm86 (NTDLL.@)
|
* __wine_enter_vm86 (NTDLL.@)
|
||||||
*/
|
*/
|
||||||
|
@ -1204,10 +1138,11 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer,
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* call_thread_entry_point
|
* call_thread_entry_point
|
||||||
*/
|
*/
|
||||||
void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg )
|
static void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg )
|
||||||
{
|
{
|
||||||
__TRY
|
__TRY
|
||||||
{
|
{
|
||||||
|
TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg );
|
||||||
exit_thread( entry( arg ));
|
exit_thread( entry( arg ));
|
||||||
}
|
}
|
||||||
__EXCEPT(unhandled_exception_filter)
|
__EXCEPT(unhandled_exception_filter)
|
||||||
|
@ -1218,6 +1153,63 @@ void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg )
|
||||||
abort(); /* should not be reached */
|
abort(); /* should not be reached */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct startup_info
|
||||||
|
{
|
||||||
|
LPTHREAD_START_ROUTINE entry;
|
||||||
|
void *arg;
|
||||||
|
BOOL suspend;
|
||||||
|
};
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* thread_startup
|
||||||
|
*/
|
||||||
|
static void thread_startup( void *param )
|
||||||
|
{
|
||||||
|
CONTEXT context = { 0 };
|
||||||
|
struct startup_info *info = param;
|
||||||
|
|
||||||
|
/* build the initial context */
|
||||||
|
context.ContextFlags = CONTEXT_FULL;
|
||||||
|
context.Gpr1 = (DWORD)NtCurrentTeb()->Tib.StackBase;
|
||||||
|
context.Gpr3 = (DWORD)info->entry;
|
||||||
|
context.Gpr4 = (DWORD)info->arg;
|
||||||
|
context.Iar = (DWORD)call_thread_entry_point;
|
||||||
|
|
||||||
|
if (info->suspend) wait_suspend( &context );
|
||||||
|
attach_dlls( &context );
|
||||||
|
|
||||||
|
call_thread_entry_point( (LPTHREAD_START_ROUTINE)context.Gpr3, (void *)context.Gpr4 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* signal_start_thread
|
||||||
|
*
|
||||||
|
* Thread startup sequence:
|
||||||
|
* signal_start_thread()
|
||||||
|
* -> thread_startup()
|
||||||
|
* -> call_thread_entry_point()
|
||||||
|
*/
|
||||||
|
void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend )
|
||||||
|
{
|
||||||
|
struct startup_info info = { entry, arg, suspend };
|
||||||
|
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* signal_start_process
|
||||||
|
*
|
||||||
|
* Process startup sequence:
|
||||||
|
* signal_start_process()
|
||||||
|
* -> thread_startup()
|
||||||
|
* -> call_thread_entry_point()
|
||||||
|
* -> kernel32_start_process()
|
||||||
|
*/
|
||||||
|
void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
|
||||||
|
{
|
||||||
|
struct startup_info info = { kernel32_start_process, entry, suspend };
|
||||||
|
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* RtlExitUserThread (NTDLL.@)
|
* RtlExitUserThread (NTDLL.@)
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue