| |
| |
| |
| |
| |
| |
| #include <psxtypes/psxtypes.h> |
| #include <pemagine/pemagine.h> |
| #include <ntapi/nt_status.h> |
| #include <ntapi/nt_object.h> |
| #include <ntapi/nt_thread.h> |
| #include <ntapi/nt_process.h> |
| #include <ntapi/nt_string.h> |
| #include <ntapi/ntapi.h> |
| #include "ntapi_impl.h" |
| |
| struct __ext_params { |
| size_t size_in_bytes; |
| nt_create_process_ext_param file_info; |
| }; |
| |
| struct __integral_cmdline { |
| struct pe_guid_str_utf16 guid; |
| wchar16_t space1; |
| wchar16_t rarg[2]; |
| wchar16_t space2; |
| wchar16_t addr[2*__SIZEOF_POINTER__]; |
| wchar16_t null; |
| }; |
| |
| static int32_t __tt_create_process_cancel(nt_create_process_params * params, int32_t status) |
| { |
| if (params->hprocess) { |
| __ntapi->zw_terminate_process(params->hprocess,NT_STATUS_INTERNAL_ERROR); |
| __ntapi->zw_close(params->hprocess); |
| } |
| |
| if (params->hthread) |
| __ntapi->zw_close(params->hthread); |
| |
| return status; |
| } |
| |
| |
| int32_t __stdcall __ntapi_tt_create_native_process_v2( |
| __in_out nt_create_process_params * params) |
| { |
| int32_t status; |
| |
| nt_object_attributes oa_process; |
| nt_object_attributes oa_thread; |
| |
| nt_unicode_string nt_image; |
| nt_unicode_string nt_cmd_line; |
| |
| nt_create_process_info nt_process_info; |
| int fresume_thread; |
| |
| struct __ext_params ext_params; |
| struct __integral_cmdline fcmdline = { |
| { |
| '{',{'3','e','4','3','e','c','8','4'}, |
| '-',{'1','a','f','1'}, |
| '-',{'4','e','d','e'}, |
| '-',{'a','c','d','8'}, |
| '-',{'c','3','d','9','2','0','a','f','c','8','6','8'}, |
| '}' |
| }, |
| |
| #if (__SIZEOF_POINTER__ == 4) |
| ' ',{'-','r'},' ', |
| {'i','n','t','e','g','r','a','l'},0}; |
| #elif (__SIZEOF_POINTER__ == 8) |
| ' ',{'-','r'},' ', |
| {'i','n','t','e','g','r','a','l', |
| '-','r','u','n','t','i','m','e'},0}; |
| #endif |
| |
| |
| if (params->cmd_line && params->process_params) |
| return NT_STATUS_INVALID_PARAMETER_MIX; |
| else if (params->cmd_line && params->rtblock) |
| return NT_STATUS_INVALID_PARAMETER_MIX; |
| else if (params->environment && params->process_params) |
| return NT_STATUS_INVALID_PARAMETER_MIX; |
| |
| |
| __ntapi->rtl_init_unicode_string( |
| &nt_image, |
| params->image_name); |
| |
| |
| if (!params->obj_attr_process) { |
| __ntapi->tt_aligned_block_memset( |
| &oa_process,0,sizeof(oa_process)); |
| |
| oa_process.len = sizeof(oa_process); |
| params->obj_attr_process = &oa_process; |
| } |
| |
| |
| if (!params->obj_attr_thread) { |
| __ntapi->tt_aligned_block_memset( |
| &oa_thread,0,sizeof(oa_thread)); |
| |
| oa_thread.len = sizeof(oa_thread); |
| params->obj_attr_thread = &oa_thread; |
| } |
| |
| |
| if (!params->process_params) { |
| |
| if (!params->environment) |
| params->environment = __ntapi->tt_get_peb_env_block_utf16(); |
| |
| |
| if (params->rtblock) { |
| nt_cmd_line.strlen = sizeof(fcmdline) - sizeof(fcmdline.null); |
| nt_cmd_line.maxlen = sizeof(fcmdline); |
| nt_cmd_line.buffer = &fcmdline.guid.lbrace; |
| params->cmd_line = &fcmdline.guid.lbrace; |
| } else { |
| if (!params->cmd_line) |
| params->cmd_line = params->image_name; |
| |
| __ntapi->rtl_init_unicode_string( |
| &nt_cmd_line, |
| params->cmd_line); |
| } |
| |
| if ((status = __ntapi->rtl_create_process_parameters( |
| ¶ms->process_params, |
| &nt_image, |
| (nt_unicode_string *)0, |
| (nt_unicode_string *)0, |
| &nt_cmd_line, |
| params->environment, |
| (nt_unicode_string *)0, |
| (nt_unicode_string *)0, |
| (nt_unicode_string *)0, |
| (nt_unicode_string *)0))) |
| return status; |
| |
| __ntapi->rtl_normalize_process_params(params->process_params); |
| } |
| |
| |
| if (!params->create_process_info) { |
| __ntapi->tt_aligned_block_memset( |
| &nt_process_info,0,sizeof(nt_process_info)); |
| |
| nt_process_info.size = sizeof(nt_create_process_info); |
| nt_process_info.state = NT_PROCESS_CREATE_INITIAL_STATE; |
| nt_process_info.init_state.init_flags = NT_PROCESS_CREATE_INFO_OBTAIN_OUTPUT; |
| nt_process_info.init_state.file_access_ext = NT_FILE_READ_ATTRIBUTES|NT_FILE_READ_ACCESS; |
| |
| params->create_process_info = &nt_process_info; |
| } |
| |
| |
| if (!params->create_process_ext_params) { |
| __ntapi->tt_aligned_block_memset( |
| &ext_params,0,sizeof(ext_params)); |
| |
| ext_params.size_in_bytes = sizeof(ext_params); |
| |
| |
| ext_params.file_info.ext_param_type = NT_CREATE_PROCESS_EXT_PARAM_SET_FILE_NAME; |
| ext_params.file_info.ext_param_size = nt_image.strlen; |
| ext_params.file_info.ext_param_addr = nt_image.buffer; |
| |
| params->create_process_ext_params = (nt_create_process_ext_params *)&ext_params; |
| } |
| |
| params->hprocess = 0; |
| params->hthread = 0; |
| fresume_thread = 0; |
| |
| if (params->rtblock) { |
| fresume_thread = (params->creation_flags_thread ^ 0x01) & 0x01; |
| params->creation_flags_thread |= 0x01; |
| } |
| |
| if (!params->desired_access_process) |
| params->desired_access_process = NT_PROCESS_ALL_ACCESS; |
| |
| if (!params->desired_access_thread) |
| params->desired_access_thread = NT_THREAD_ALL_ACCESS; |
| |
| if ((status = __ntapi->zw_create_user_process( |
| ¶ms->hprocess, |
| ¶ms->hthread, |
| params->desired_access_process, |
| params->desired_access_thread, |
| params->obj_attr_process, |
| params->obj_attr_thread, |
| params->creation_flags_process, |
| params->creation_flags_thread, |
| params->process_params, |
| params->create_process_info, |
| params->create_process_ext_params))) |
| return status; |
| |
| |
| if (params->hsession && (params->hsession != NT_INVALID_HANDLE_VALUE)) |
| if ((status = __ntapi->tty_client_process_register( |
| params->hsession, |
| params->pbi.unique_process_id, |
| 0,0,0))) |
| return __tt_create_process_cancel(params,status); |
| |
| |
| __ntapi->zw_close(params->create_process_info->success_state.hfile); |
| __ntapi->zw_close(params->create_process_info->success_state.hsection); |
| |
| if ((status = __ntapi->zw_query_information_process( |
| params->hprocess, |
| NT_PROCESS_BASIC_INFORMATION, |
| ¶ms->pbi,sizeof(params->pbi), |
| 0))) |
| return __tt_create_process_cancel(params,status); |
| |
| if (!params->rtblock) |
| return NT_STATUS_SUCCESS; |
| |
| |
| if ((status = __ntapi_tt_create_remote_runtime_data(params->hprocess,params->rtblock))) |
| return __tt_create_process_cancel(params,status); |
| |
| |
| if (fresume_thread && (status = __ntapi->zw_resume_thread(params->hthread,0))) |
| return __tt_create_process_cancel(params,status); |
| |
| return NT_STATUS_SUCCESS; |
| } |