|
|
dd89bb |
/********************************************************/
|
|
|
dd89bb |
/* ntapi: Native API core library */
|
|
|
64e606 |
/* Copyright (C) 2013--2021 SysDeer Technologies, LLC */
|
|
|
dd89bb |
/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
|
|
|
dd89bb |
/********************************************************/
|
|
|
dd89bb |
|
|
|
dd89bb |
#include <psxtypes/psxtypes.h>
|
|
|
dd89bb |
#include <pemagine/pemagine.h>
|
|
|
dd89bb |
#include <ntapi/nt_status.h>
|
|
|
dd89bb |
#include <ntapi/nt_object.h>
|
|
|
dd89bb |
#include <ntapi/nt_memory.h>
|
|
|
dd89bb |
#include <ntapi/nt_thread.h>
|
|
|
dd89bb |
#include <ntapi/nt_process.h>
|
|
|
dd89bb |
#include <ntapi/nt_string.h>
|
|
|
80236a |
#include <ntapi/nt_atomic.h>
|
|
|
dd89bb |
#include <ntapi/ntapi.h>
|
|
|
dd89bb |
#include "ntapi_impl.h"
|
|
|
dd89bb |
|
|
|
dd89bb |
/* (no planned support of alpha processors, use constant values) */
|
|
|
dd89bb |
#define __PAGE_SIZE 0x001000
|
|
|
dd89bb |
#define __GRANULARITY 0x010000
|
|
|
dd89bb |
#define __RESERVE_ROUND_UP 0x100000
|
|
|
dd89bb |
|
|
|
e870a2 |
static int32_t __create_thread_fail(
|
|
|
dd89bb |
void * hprocess,
|
|
|
dd89bb |
void * stack_bottom,
|
|
|
dd89bb |
size_t stack_size,
|
|
|
dd89bb |
int32_t status)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
__ntapi->zw_free_virtual_memory(
|
|
|
dd89bb |
hprocess,
|
|
|
dd89bb |
&stack_bottom,
|
|
|
dd89bb |
&stack_size,
|
|
|
dd89bb |
NT_MEM_RELEASE);
|
|
|
dd89bb |
return status;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
2db6fe |
static int32_t __tt_create_thread_stack(
|
|
|
2db6fe |
nt_thread_params * params,
|
|
|
2db6fe |
nt_user_stack * stack)
|
|
|
2db6fe |
{
|
|
|
2db6fe |
int32_t status;
|
|
|
2db6fe |
uint32_t protect_type_old;
|
|
|
2db6fe |
void * stack_system_limit;
|
|
|
2db6fe |
char * base;
|
|
|
2db6fe |
size_t size;
|
|
|
2db6fe |
size_t commit;
|
|
|
2db6fe |
|
|
|
2db6fe |
/* caller-provided stack? */
|
|
|
2db6fe |
if (params->stack_info && params->stack_info->expandable_stack_base) {
|
|
|
2db6fe |
stack->fixed_stack_base = params->stack_info->fixed_stack_base;
|
|
|
2db6fe |
stack->fixed_stack_limit = params->stack_info->fixed_stack_limit;
|
|
|
2db6fe |
stack->expandable_stack_base = params->stack_info->expandable_stack_base;
|
|
|
2db6fe |
stack->expandable_stack_limit = params->stack_info->expandable_stack_limit;
|
|
|
2db6fe |
stack->expandable_stack_bottom = params->stack_info->expandable_stack_bottom;
|
|
|
2db6fe |
|
|
|
2db6fe |
return NT_STATUS_SUCCESS;
|
|
|
2db6fe |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
/* init */
|
|
|
dd89bb |
params->stack_size_commit = __NT_ROUND_UP_TO_POWER_OF_2(params->stack_size_commit+params->ext_ctx_size, __PAGE_SIZE);
|
|
|
dd89bb |
params->stack_size_reserve = __NT_ROUND_UP_TO_POWER_OF_2(params->stack_size_reserve,__GRANULARITY);
|
|
|
dd89bb |
|
|
|
dd89bb |
/* compare, round-up as needed */
|
|
|
dd89bb |
if (params->stack_size_commit >= params->stack_size_reserve)
|
|
|
dd89bb |
params->stack_size_reserve = __NT_ROUND_UP_TO_POWER_OF_2(params->stack_size_commit,__RESERVE_ROUND_UP);
|
|
|
dd89bb |
|
|
|
dd89bb |
/**
|
|
|
dd89bb |
*
|
|
|
dd89bb |
* --------- BASE ----------
|
|
|
dd89bb |
*
|
|
|
dd89bb |
* ---- (COMMITED AREA) ----
|
|
|
dd89bb |
*
|
|
|
dd89bb |
* --------- LIMIT ---------
|
|
|
dd89bb |
*
|
|
|
dd89bb |
* ------ GUARD PAGE -------
|
|
|
dd89bb |
*
|
|
|
dd89bb |
* ------ ACTUAL LIMIT -----
|
|
|
dd89bb |
*
|
|
|
dd89bb |
* ---- (RESERVED AREA) ----
|
|
|
dd89bb |
*
|
|
|
dd89bb |
* -------- BOTTOM ---------
|
|
|
dd89bb |
*
|
|
|
dd89bb |
**/
|
|
|
dd89bb |
|
|
|
dd89bb |
/* stack structure: unused fields */
|
|
|
2db6fe |
stack->fixed_stack_base = 0;
|
|
|
2db6fe |
stack->fixed_stack_limit = 0;
|
|
|
dd89bb |
|
|
|
dd89bb |
/* first we reserve */
|
|
|
2db6fe |
stack->expandable_stack_bottom = 0;
|
|
|
dd89bb |
|
|
|
e870a2 |
if ((status = __ntapi->zw_allocate_virtual_memory(
|
|
|
e870a2 |
params->hprocess,
|
|
|
2db6fe |
&stack->expandable_stack_bottom,
|
|
|
e870a2 |
params->stack_zero_bits,
|
|
|
e870a2 |
¶ms->stack_size_reserve,
|
|
|
e870a2 |
NT_MEM_RESERVE,
|
|
|
e870a2 |
NT_PAGE_READWRITE)))
|
|
|
e870a2 |
return status;
|
|
|
dd89bb |
|
|
|
dd89bb |
/* calculate base and limit */
|
|
|
2db6fe |
base = stack->expandable_stack_bottom;
|
|
|
e870a2 |
base += params->stack_size_reserve;
|
|
|
dd89bb |
|
|
|
2db6fe |
stack->expandable_stack_base = base;
|
|
|
2db6fe |
stack->expandable_stack_limit = base - params->stack_size_commit;
|
|
|
dd89bb |
|
|
|
dd89bb |
/* guard page */
|
|
|
e870a2 |
commit = params->stack_size_commit + __PAGE_SIZE;
|
|
|
e870a2 |
stack_system_limit = base - commit;
|
|
|
dd89bb |
|
|
|
dd89bb |
/* then we commit */
|
|
|
e870a2 |
if ((status = __ntapi->zw_allocate_virtual_memory(
|
|
|
e870a2 |
params->hprocess,
|
|
|
e870a2 |
&stack_system_limit,
|
|
|
e870a2 |
0,&commit,
|
|
|
e870a2 |
NT_MEM_COMMIT,
|
|
|
e870a2 |
NT_PAGE_READWRITE)))
|
|
|
e870a2 |
return __create_thread_fail(
|
|
|
e870a2 |
params->hprocess,
|
|
|
2db6fe |
stack->expandable_stack_bottom,
|
|
|
e870a2 |
params->stack_size_reserve,
|
|
|
e870a2 |
status);
|
|
|
dd89bb |
|
|
|
dd89bb |
/* finally we protect the guard page */
|
|
|
656c60 |
size = __PAGE_SIZE;
|
|
|
e870a2 |
|
|
|
e870a2 |
if ((status = __ntapi->zw_protect_virtual_memory(
|
|
|
e870a2 |
params->hprocess,
|
|
|
e870a2 |
&stack_system_limit,
|
|
|
e870a2 |
&size,
|
|
|
e870a2 |
NT_PAGE_READWRITE | NT_MEM_PAGE_GUARD,
|
|
|
e870a2 |
&protect_type_old)))
|
|
|
e870a2 |
return __create_thread_fail(
|
|
|
e870a2 |
params->hprocess,
|
|
|
2db6fe |
stack->expandable_stack_bottom,
|
|
|
e870a2 |
params->stack_size_reserve,
|
|
|
e870a2 |
status);
|
|
|
dd89bb |
|
|
|
2db6fe |
/* all done */
|
|
|
2db6fe |
if (params->stack_info) {
|
|
|
2db6fe |
params->stack_info->fixed_stack_base = stack->fixed_stack_base;
|
|
|
2db6fe |
params->stack_info->fixed_stack_limit = stack->fixed_stack_limit;
|
|
|
2db6fe |
params->stack_info->expandable_stack_base = stack->expandable_stack_base;
|
|
|
2db6fe |
params->stack_info->expandable_stack_limit = stack->expandable_stack_limit;
|
|
|
2db6fe |
params->stack_info->expandable_stack_bottom = stack->expandable_stack_bottom;
|
|
|
2db6fe |
|
|
|
2db6fe |
return NT_STATUS_SUCCESS;
|
|
|
2db6fe |
}
|
|
|
2db6fe |
|
|
|
2db6fe |
return NT_STATUS_SUCCESS;
|
|
|
2db6fe |
}
|
|
|
2db6fe |
|
|
|
2db6fe |
int32_t __stdcall __ntapi_tt_create_thread(nt_thread_params * params)
|
|
|
2db6fe |
{
|
|
|
2db6fe |
int32_t status;
|
|
|
2db6fe |
ntapi_internals * __internals;
|
|
|
2db6fe |
|
|
|
2db6fe |
nt_client_id cid;
|
|
|
2db6fe |
nt_port_message_csrss_process csrss_msg;
|
|
|
2db6fe |
nt_port_message_csrss_process * csrss_msg_1st;
|
|
|
2db6fe |
nt_port_message_csrss_thread * csrss_msg_any;
|
|
|
2db6fe |
|
|
|
2db6fe |
nt_thread_context __attr_aligned__(0x40) context;
|
|
|
2db6fe |
nt_user_stack __attr_aligned__(0x10) stack;
|
|
|
2db6fe |
uintptr_t fsuspended;
|
|
|
2db6fe |
uintptr_t * parg;
|
|
|
2db6fe |
|
|
|
2db6fe |
if (!(params->stack_size_commit))
|
|
|
2db6fe |
return NT_STATUS_INVALID_PARAMETER;
|
|
|
2db6fe |
else if (!(params->stack_size_reserve))
|
|
|
2db6fe |
return NT_STATUS_INVALID_PARAMETER;
|
|
|
2db6fe |
else if (params->ext_ctx_size > __NT_INTERNAL_PAGE_SIZE)
|
|
|
2db6fe |
return NT_STATUS_INVALID_PARAMETER;
|
|
|
2db6fe |
else if (params->ext_ctx_size % sizeof(intptr_t))
|
|
|
2db6fe |
return NT_STATUS_INVALID_PARAMETER;
|
|
|
2db6fe |
else if (params->arg && params->ext_ctx)
|
|
|
2db6fe |
return NT_STATUS_INVALID_PARAMETER_MIX;
|
|
|
2db6fe |
else if (params->ext_ctx && !params->ext_ctx_size)
|
|
|
2db6fe |
return NT_STATUS_INVALID_PARAMETER_MIX;
|
|
|
2db6fe |
|
|
|
2db6fe |
/* init */
|
|
|
2db6fe |
__internals = __ntapi_internals();
|
|
|
2db6fe |
|
|
|
2db6fe |
/* stack */
|
|
|
2db6fe |
if ((status = __tt_create_thread_stack(params,&stack)))
|
|
|
2db6fe |
return status;
|
|
|
2db6fe |
|
|
|
dd89bb |
/* context */
|
|
|
3bc37f |
if (params->reg_context) {
|
|
|
3bc37f |
__ntapi->tt_aligned_block_memcpy(
|
|
|
3bc37f |
(uintptr_t *)&context,
|
|
|
3bc37f |
(uintptr_t *)params->reg_context,
|
|
|
3bc37f |
sizeof(context));
|
|
|
3bc37f |
} else {
|
|
|
3bc37f |
__ntapi->tt_aligned_block_memset(
|
|
|
3bc37f |
&context,0,sizeof(context));
|
|
|
3bc37f |
|
|
|
dd89bb |
__INIT_CONTEXT(context);
|
|
|
dd89bb |
context.INSTRUCTION_POINTER_REGISTER = (uintptr_t)params->start;
|
|
|
360317 |
context.STACK_POINTER_REGISTER = (uintptr_t)(stack.expandable_stack_base);
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
/*****************************************************************************/
|
|
|
dd89bb |
/*-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-*/
|
|
|
dd89bb |
/* */
|
|
|
dd89bb |
/* */
|
|
|
dd89bb |
/* INNOVATION IN THE FIELD OF MULTI-THREADED COMPUTER PROGRAMMING */
|
|
|
dd89bb |
/* */
|
|
|
dd89bb |
/* A "RAPUNZEL" TOP-OF-STACK, VARIABLE-SIZE ENTRY-ROUTINE CONTEXT */
|
|
|
dd89bb |
/* */
|
|
|
64e606 |
/* COPYRIGHT (C) 2013--2021 SysDeer Technologies, LLC */
|
|
|
dd89bb |
/* */
|
|
|
dd89bb |
/* */
|
|
|
dd89bb |
/* */
|
|
|
dd89bb |
/* Laß mir dein Haar herunter.« */
|
|
|
dd89bb |
/**/ if (params->ext_ctx) { /**/
|
|
|
dd89bb |
/**/ context.STACK_POINTER_REGISTER -= params->ext_ctx_size; /**/
|
|
|
dd89bb |
/**/ params->arg = (void *)context.STACK_POINTER_REGISTER; /**/
|
|
|
dd89bb |
/**/ /**/
|
|
|
80236a |
/**/ if (params->creation_flags & NT_CREATE_LOCAL_THREAD) { /**/
|
|
|
dd89bb |
/**/ __ntapi->tt_aligned_block_memcpy( /**/
|
|
|
dd89bb |
/**/ (uintptr_t *)params->arg, /**/
|
|
|
dd89bb |
/**/ (uintptr_t *)params->ext_ctx, /**/
|
|
|
dd89bb |
/**/ params->ext_ctx_size); /**/
|
|
|
80236a |
/**/ /**/
|
|
|
80236a |
/**/ __ntapi->tt_aligned_block_memlock( /**/
|
|
|
80236a |
/**/ (uintptr_t *)params->arg, /**/
|
|
|
80236a |
/**/ params->ext_ctx_size); /**/
|
|
|
80236a |
/**/ /**/
|
|
|
80236a |
/**/ } else { /**/
|
|
|
dd89bb |
/**/ status = __ntapi->zw_write_virtual_memory( /**/
|
|
|
dd89bb |
/**/ params->hprocess, /**/
|
|
|
dd89bb |
/**/ params->arg, /**/
|
|
|
dd89bb |
/**/ (char *)params->ext_ctx, /**/
|
|
|
dd89bb |
/**/ params->ext_ctx_size, /**/
|
|
|
dd89bb |
/**/ 0); /**/
|
|
|
dd89bb |
/**/ /**/
|
|
|
dd89bb |
/**/ if (status) return __create_thread_fail( /**/
|
|
|
dd89bb |
/**/ params->hprocess, /**/
|
|
|
dd89bb |
/**/ stack.expandable_stack_bottom, /**/
|
|
|
dd89bb |
/**/ params->stack_size_reserve, /**/
|
|
|
dd89bb |
/**/ status); /**/
|
|
|
dd89bb |
/**/ } /**/
|
|
|
dd89bb |
/**/ } /**/
|
|
|
dd89bb |
/**/ /**/
|
|
|
dd89bb |
/**/ /**/
|
|
|
dd89bb |
/**/ /**/
|
|
|
dd89bb |
/* entry-routine argument address and stack pointer adjustment */
|
|
|
dd89bb |
/**/ if (sizeof(intptr_t) == 4) { /**/
|
|
|
dd89bb |
/**/ context.STACK_POINTER_REGISTER -= sizeof(intptr_t); /**/
|
|
|
dd89bb |
/**/ parg = (uintptr_t *)context.STACK_POINTER_REGISTER; /**/
|
|
|
c2fe99 |
/**/ } else { /**/
|
|
|
dd89bb |
/**/ parg = &context.FAST_CALL_ARG0; /**/
|
|
|
c2fe99 |
/**/ } /**/
|
|
|
dd89bb |
/**/ /**/
|
|
|
dd89bb |
/**/ /**/
|
|
|
dd89bb |
/* write entry-routine argument */
|
|
|
d7c519 |
/**/ if (sizeof(intptr_t) == 8) { /**/
|
|
|
80236a |
/**/ at_store( /**/
|
|
|
80236a |
/**/ (intptr_t *)parg, /**/
|
|
|
80236a |
/**/ (intptr_t)params->arg); /**/
|
|
|
d7c519 |
/**/ /**/
|
|
|
d7c519 |
/**/ } else if (params->creation_flags & NT_CREATE_LOCAL_THREAD) { /**/
|
|
|
d7c519 |
/**/ at_store( /**/
|
|
|
d7c519 |
/**/ (intptr_t *)parg, /**/
|
|
|
d7c519 |
/**/ (intptr_t)params->arg); /**/
|
|
|
d7c519 |
/**/ /**/
|
|
|
d7c519 |
/**/ } else { /**/
|
|
|
dd89bb |
/**/ status = __ntapi->zw_write_virtual_memory( /**/
|
|
|
dd89bb |
/**/ params->hprocess, /**/
|
|
|
dd89bb |
/**/ parg, /**/
|
|
|
dd89bb |
/**/ (char *)¶ms->arg, /**/
|
|
|
dd89bb |
/**/ sizeof(uintptr_t), /**/
|
|
|
dd89bb |
/**/ 0); /**/
|
|
|
dd89bb |
/**/ /**/
|
|
|
dd89bb |
/**/ if (status) return __create_thread_fail( /**/
|
|
|
dd89bb |
/**/ params->hprocess, /**/
|
|
|
dd89bb |
/**/ stack.expandable_stack_bottom, /**/
|
|
|
dd89bb |
/**/ params->stack_size_reserve, /**/
|
|
|
dd89bb |
/**/ status); /**/
|
|
|
dd89bb |
/**/ } /**/
|
|
|
dd89bb |
/**/ /**/
|
|
|
dd89bb |
/**/ /**/
|
|
|
dd89bb |
/*-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-*/
|
|
|
dd89bb |
/*****************************************************************************/
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
/* create thread */
|
|
|
e870a2 |
fsuspended = (params->creation_flags & NT_CREATE_SUSPENDED)
|
|
|
e870a2 |
? 1 : __ntapi->zw_create_user_process
|
|
|
e870a2 |
? 0 : 1;
|
|
|
e870a2 |
|
|
|
e870a2 |
if ((status = __ntapi->zw_create_thread(
|
|
|
e870a2 |
¶ms->hthread,
|
|
|
e870a2 |
NT_THREAD_ALL_ACCESS,
|
|
|
e870a2 |
params->obj_attr,
|
|
|
e870a2 |
params->hprocess,
|
|
|
e870a2 |
&cid,&context,&stack,
|
|
|
e870a2 |
fsuspended)))
|
|
|
e870a2 |
return __create_thread_fail(
|
|
|
e870a2 |
params->hprocess,
|
|
|
e870a2 |
stack.expandable_stack_bottom,
|
|
|
e870a2 |
params->stack_size_reserve,
|
|
|
e870a2 |
status);
|
|
|
dd89bb |
|
|
|
dd89bb |
/* for os versions prior to hasta la */
|
|
|
dd89bb |
if (!__ntapi->zw_create_user_process) {
|
|
|
dd89bb |
__ntapi->tt_aligned_block_memset(&csrss_msg,0,sizeof(csrss_msg));
|
|
|
dd89bb |
|
|
|
dd89bb |
if (params->creation_flags & NT_CREATE_FIRST_THREAD_OF_PROCESS) {
|
|
|
dd89bb |
/* nt_port_message_csrss_process is the larger structure */
|
|
|
dd89bb |
csrss_msg_1st = &csrss_msg;
|
|
|
dd89bb |
|
|
|
dd89bb |
csrss_msg_1st->header.data_size = sizeof(nt_port_message_csrss_process) - sizeof(nt_port_message);
|
|
|
dd89bb |
csrss_msg_1st->header.msg_size = sizeof(nt_port_message_csrss_process);
|
|
|
dd89bb |
csrss_msg_1st->opcode = 0x10000;
|
|
|
dd89bb |
csrss_msg_1st->hprocess = params->hprocess;
|
|
|
dd89bb |
csrss_msg_1st->hthread = params->hthread;
|
|
|
dd89bb |
csrss_msg_1st->unique_process_id = cid.process_id;
|
|
|
dd89bb |
csrss_msg_1st->unique_thread_id = cid.thread_id;
|
|
|
dd89bb |
} else {
|
|
|
dd89bb |
/* nt_port_message_csrss_thread is the smaller structure */
|
|
|
dd89bb |
csrss_msg_any = (nt_port_message_csrss_thread *)&csrss_msg;
|
|
|
dd89bb |
|
|
|
dd89bb |
csrss_msg_any->header.data_size = sizeof(nt_port_message_csrss_thread) - sizeof(nt_port_message);
|
|
|
dd89bb |
csrss_msg_any->header.msg_size = sizeof(nt_port_message_csrss_thread);
|
|
|
dd89bb |
csrss_msg_any->opcode = 0x10001;
|
|
|
dd89bb |
csrss_msg_any->hthread = params->hthread;
|
|
|
dd89bb |
csrss_msg_any->unique_process_id = cid.process_id;
|
|
|
dd89bb |
csrss_msg_any->unique_thread_id = cid.thread_id;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
/* send csrss a new-thread notification */
|
|
|
dd89bb |
if (__internals->csr_port_handle_addr) {
|
|
|
dd89bb |
status = __ntapi->zw_request_wait_reply_port(
|
|
|
dd89bb |
*__internals->csr_port_handle_addr,
|
|
|
dd89bb |
&csrss_msg,&csrss_msg);
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
/* output csrss_status to caller */
|
|
|
dd89bb |
params->csrss_status = status
|
|
|
dd89bb |
? status
|
|
|
dd89bb |
: csrss_msg.status;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
/* resume thread, close handle as needed */
|
|
|
dd89bb |
if (fsuspended && !(params->creation_flags & NT_CREATE_SUSPENDED))
|
|
|
dd89bb |
status = __ntapi->zw_resume_thread(params->hthread,0);
|
|
|
dd89bb |
|
|
|
dd89bb |
if (params->creation_flags & NT_CLOSE_THREAD_HANDLE)
|
|
|
dd89bb |
__ntapi->zw_close(params->hthread);
|
|
|
dd89bb |
|
|
|
dd89bb |
/* and finally */
|
|
|
c8a126 |
params->cid.process_id = cid.process_id;
|
|
|
c8a126 |
params->cid.thread_id = cid.thread_id;
|
|
|
e870a2 |
|
|
|
dd89bb |
return NT_STATUS_SUCCESS;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
e870a2 |
int32_t __stdcall __ntapi_tt_create_local_thread(nt_thread_params * params)
|
|
|
dd89bb |
{
|
|
|
e870a2 |
nt_status status;
|
|
|
dd89bb |
void * image_base;
|
|
|
dd89bb |
struct pe_stack_heap_info stack_heap_info;
|
|
|
dd89bb |
|
|
|
f36e2d |
/* flags */
|
|
|
f36e2d |
params->creation_flags |= NT_CREATE_LOCAL_THREAD;
|
|
|
f36e2d |
|
|
|
f36e2d |
/* hprocess */
|
|
|
f36e2d |
if (!params->hprocess)
|
|
|
f36e2d |
params->hprocess = __ntapi_internals()->hprocess;
|
|
|
f36e2d |
|
|
|
f36e2d |
/* stack defaults */
|
|
|
e870a2 |
if (params->stack_info)
|
|
|
e870a2 |
(void)0;
|
|
|
dd89bb |
|
|
|
e870a2 |
else if (params->stack_size_commit && params->stack_size_reserve)
|
|
|
e870a2 |
(void)0;
|
|
|
dd89bb |
|
|
|
e870a2 |
else {
|
|
|
e870a2 |
/* image_base*/
|
|
|
e870a2 |
if (!(image_base = pe_get_first_module_handle()))
|
|
|
e870a2 |
return NT_STATUS_INVALID_IMPORT_OF_NON_DLL;
|
|
|
dd89bb |
|
|
|
e870a2 |
if ((status = pe_get_image_stack_heap_info(
|
|
|
e870a2 |
image_base,
|
|
|
e870a2 |
&stack_heap_info)))
|
|
|
dd89bb |
return NT_STATUS_INVALID_IMAGE_FORMAT;
|
|
|
dd89bb |
|
|
|
dd89bb |
/* stack_size_commit */
|
|
|
dd89bb |
if (!params->stack_size_commit)
|
|
|
dd89bb |
params->stack_size_commit = stack_heap_info.size_of_stack_commit;
|
|
|
dd89bb |
|
|
|
dd89bb |
/* stack_size_reserve */
|
|
|
dd89bb |
if (!params->stack_size_reserve)
|
|
|
dd89bb |
params->stack_size_reserve = stack_heap_info.size_of_stack_reserve;
|
|
|
dd89bb |
|
|
|
dd89bb |
if (!(params->stack_size_commit && params->stack_size_reserve))
|
|
|
dd89bb |
return NT_STATUS_INVALID_IMAGE_FORMAT;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
e870a2 |
return __ntapi_tt_create_thread(params);
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
e870a2 |
int32_t __stdcall __ntapi_tt_create_remote_thread(nt_thread_params * params)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
return __ntapi_tt_create_thread(params);
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
void * __cdecl __ntapi_csr_port_handle(nt_status * pstatus)
|
|
|
dd89bb |
{
|
|
|
e870a2 |
nt_status status;
|
|
|
e870a2 |
ntapi_internals * __internals;
|
|
|
dd89bb |
|
|
|
e870a2 |
pstatus = pstatus ? pstatus : &status;
|
|
|
dd89bb |
__internals = __ntapi_internals();
|
|
|
dd89bb |
|
|
|
dd89bb |
if (__internals->csr_port_handle_addr) {
|
|
|
e870a2 |
*pstatus = NT_STATUS_SUCCESS;
|
|
|
dd89bb |
return *__internals->csr_port_handle_addr;
|
|
|
dd89bb |
} else {
|
|
|
e870a2 |
*pstatus = NT_STATUS_UNSUCCESSFUL;
|
|
|
e870a2 |
return 0;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
}
|