summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/thread/ntapi_tt_create_thread.c124
1 files changed, 81 insertions, 43 deletions
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,
&params->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);
}