diff --git a/src/thread/ntapi_tt_create_thread.c b/src/thread/ntapi_tt_create_thread.c index a8dcb11..c356370 100644 --- a/src/thread/ntapi_tt_create_thread.c +++ b/src/thread/ntapi_tt_create_thread.c @@ -34,42 +34,30 @@ static int32_t __create_thread_fail( return status; } -int32_t __stdcall __ntapi_tt_create_thread(nt_thread_params * params) -{ - int32_t status; - ntapi_internals * __internals; - - nt_client_id cid; - nt_port_message_csrss_process csrss_msg; - nt_port_message_csrss_process * csrss_msg_1st; - nt_port_message_csrss_thread * csrss_msg_any; - char * base; - void * stack_system_limit; - uint32_t protect_type_old; - - nt_thread_context __attr_aligned__(0x40) context; - nt_user_stack __attr_aligned__(0x10) stack; - uintptr_t fsuspended; - uintptr_t * parg; - size_t size; - size_t commit; - - if (!(params->stack_size_commit)) - return NT_STATUS_INVALID_PARAMETER; - else if (!(params->stack_size_reserve)) - return NT_STATUS_INVALID_PARAMETER; - else if (params->ext_ctx_size > __NT_INTERNAL_PAGE_SIZE) - return NT_STATUS_INVALID_PARAMETER; - else if (params->ext_ctx_size % sizeof(intptr_t)) - return NT_STATUS_INVALID_PARAMETER; - else if (params->arg && params->ext_ctx) - return NT_STATUS_INVALID_PARAMETER_MIX; - else if (params->ext_ctx && !params->ext_ctx_size) - return NT_STATUS_INVALID_PARAMETER_MIX; +static int32_t __tt_create_thread_stack( + nt_thread_params * params, + nt_user_stack * stack) +{ + int32_t status; + uint32_t protect_type_old; + void * stack_system_limit; + char * base; + size_t size; + size_t commit; + + /* caller-provided stack? */ + if (params->stack_info && params->stack_info->expandable_stack_base) { + stack->fixed_stack_base = params->stack_info->fixed_stack_base; + stack->fixed_stack_limit = params->stack_info->fixed_stack_limit; + stack->expandable_stack_base = params->stack_info->expandable_stack_base; + stack->expandable_stack_limit = params->stack_info->expandable_stack_limit; + stack->expandable_stack_bottom = params->stack_info->expandable_stack_bottom; + + return NT_STATUS_SUCCESS; + } /* init */ - __internals = __ntapi_internals(); params->stack_size_commit = __NT_ROUND_UP_TO_POWER_OF_2(params->stack_size_commit+params->ext_ctx_size, __PAGE_SIZE); params->stack_size_reserve = __NT_ROUND_UP_TO_POWER_OF_2(params->stack_size_reserve,__GRANULARITY); @@ -96,15 +84,15 @@ int32_t __stdcall __ntapi_tt_create_thread(nt_thread_params * params) **/ /* stack structure: unused fields */ - stack.fixed_stack_base = 0; - stack.fixed_stack_limit = 0; + stack->fixed_stack_base = 0; + stack->fixed_stack_limit = 0; /* first we reserve */ - stack.expandable_stack_bottom = 0; + stack->expandable_stack_bottom = 0; if ((status = __ntapi->zw_allocate_virtual_memory( params->hprocess, - &stack.expandable_stack_bottom, + &stack->expandable_stack_bottom, params->stack_zero_bits, ¶ms->stack_size_reserve, NT_MEM_RESERVE, @@ -112,11 +100,11 @@ int32_t __stdcall __ntapi_tt_create_thread(nt_thread_params * params) return status; /* calculate base and limit */ - base = stack.expandable_stack_bottom; + base = stack->expandable_stack_bottom; base += params->stack_size_reserve; - stack.expandable_stack_base = base; - stack.expandable_stack_limit = base - params->stack_size_commit; + stack->expandable_stack_base = base; + stack->expandable_stack_limit = base - params->stack_size_commit; /* guard page */ commit = params->stack_size_commit + __PAGE_SIZE; @@ -131,7 +119,7 @@ int32_t __stdcall __ntapi_tt_create_thread(nt_thread_params * params) NT_PAGE_READWRITE))) return __create_thread_fail( params->hprocess, - stack.expandable_stack_bottom, + stack->expandable_stack_bottom, params->stack_size_reserve, status); @@ -146,10 +134,59 @@ int32_t __stdcall __ntapi_tt_create_thread(nt_thread_params * params) &protect_type_old))) return __create_thread_fail( params->hprocess, - stack.expandable_stack_bottom, + stack->expandable_stack_bottom, params->stack_size_reserve, status); + /* all done */ + if (params->stack_info) { + params->stack_info->fixed_stack_base = stack->fixed_stack_base; + params->stack_info->fixed_stack_limit = stack->fixed_stack_limit; + params->stack_info->expandable_stack_base = stack->expandable_stack_base; + params->stack_info->expandable_stack_limit = stack->expandable_stack_limit; + params->stack_info->expandable_stack_bottom = stack->expandable_stack_bottom; + + return NT_STATUS_SUCCESS; + } + + return NT_STATUS_SUCCESS; +} + +int32_t __stdcall __ntapi_tt_create_thread(nt_thread_params * params) +{ + int32_t status; + ntapi_internals * __internals; + + nt_client_id cid; + nt_port_message_csrss_process csrss_msg; + nt_port_message_csrss_process * csrss_msg_1st; + nt_port_message_csrss_thread * csrss_msg_any; + + nt_thread_context __attr_aligned__(0x40) context; + nt_user_stack __attr_aligned__(0x10) stack; + uintptr_t fsuspended; + uintptr_t * parg; + + if (!(params->stack_size_commit)) + return NT_STATUS_INVALID_PARAMETER; + else if (!(params->stack_size_reserve)) + return NT_STATUS_INVALID_PARAMETER; + else if (params->ext_ctx_size > __NT_INTERNAL_PAGE_SIZE) + return NT_STATUS_INVALID_PARAMETER; + else if (params->ext_ctx_size % sizeof(intptr_t)) + return NT_STATUS_INVALID_PARAMETER; + else if (params->arg && params->ext_ctx) + return NT_STATUS_INVALID_PARAMETER_MIX; + else if (params->ext_ctx && !params->ext_ctx_size) + return NT_STATUS_INVALID_PARAMETER_MIX; + + /* init */ + __internals = __ntapi_internals(); + + /* stack */ + if ((status = __tt_create_thread_stack(params,&stack))) + return status; + /* context */ if (params->reg_context) { __ntapi->tt_aligned_block_memcpy( @@ -162,7 +199,8 @@ int32_t __stdcall __ntapi_tt_create_thread(nt_thread_params * params) __INIT_CONTEXT(context); context.INSTRUCTION_POINTER_REGISTER = (uintptr_t)params->start; - context.STACK_POINTER_REGISTER = (uintptr_t)(base) - sizeof(intptr_t); + context.STACK_POINTER_REGISTER = (uintptr_t)(stack.expandable_stack_base) + - sizeof(intptr_t); }