/********************************************************/ /* ntapi: Native API core library */ /* Copyright (C) 2013--2021 Z. Gilboa */ /* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ /********************************************************/ #include #include #include #include #include #include "ntapi_impl.h" typedef struct __attr_ptr_size_aligned__ _nt_tty_pipe_name { wchar16_t pipe_dir[8]; wchar16_t back_slash; wchar16_t key_1st[8]; wchar16_t uscore_1st; wchar16_t key_2nd[8]; wchar16_t uscore_2nd; wchar16_t key_3rd[8]; wchar16_t uscore_3rd; wchar16_t key_4th[8]; wchar16_t uscore_4th; wchar16_t key_5th[8]; wchar16_t uscore_5th; wchar16_t key_6th[8]; wchar16_t null_termination; void * pad; } nt_tty_pipe_name; int32_t __stdcall __ntapi_ipc_create_pipe_v1( __out void ** hpipe_read, __out void ** hpipe_write, __in uint32_t advisory_buffer_size) { int32_t status; void * hread; void * hwrite; nt_object_attributes oa; nt_io_status_block iosb; nt_unicode_string nt_name; nt_security_quality_of_service sqos; nt_large_integer timeout; intptr_t * counter; nt_tty_pipe_name pipe_name = { {'\\','?','?','\\','p','i','p','e'}, '\\', {0},'_', {0},'_', {0},'_', {0},'_', {0},'_', {0}, 0,0 }; (void)advisory_buffer_size; /* pipe_count */ counter = (intptr_t *)&__ntapi_internals()->v1_pipe_counter; at_locked_inc(counter); /* get system time */ status = __ntapi->zw_query_system_time(&timeout); if (status != NT_STATUS_SUCCESS) return status; /* pipe name (no anonymous pipe prior to vista) */ __ntapi->tt_uint32_to_hex_utf16( pe_get_current_process_id(),pipe_name.key_1st); __ntapi->tt_uint32_to_hex_utf16( pe_get_current_thread_id(),pipe_name.key_2nd); __ntapi->tt_uint32_to_hex_utf16( timeout.ihigh + (uint32_t)*counter,pipe_name.key_3rd); __ntapi->tt_uint32_to_hex_utf16(timeout.ulow + (uint32_t)*counter,pipe_name.key_4th); __ntapi->tt_uint32_to_hex_utf16( __ntapi->tt_buffer_crc32(0,(char *)&pipe_name,sizeof(pipe_name)), pipe_name.key_5th); __ntapi->tt_uint32_to_hex_utf16( __ntapi->tt_buffer_crc32(0,(char *)&pipe_name,sizeof(pipe_name)), pipe_name.key_6th); __ntapi->tt_uint32_to_hex_utf16( __ntapi->tt_buffer_crc32(0,(char *)&pipe_name,sizeof(pipe_name)), pipe_name.key_1st); __ntapi->tt_uint32_to_hex_utf16( __ntapi->tt_buffer_crc32(0,(char *)&pipe_name,sizeof(pipe_name)), pipe_name.key_2nd); __ntapi->tt_uint32_to_hex_utf16( __ntapi->tt_buffer_crc32(0,(char *)&pipe_name,sizeof(pipe_name)), pipe_name.key_3rd); __ntapi->tt_uint32_to_hex_utf16( __ntapi->tt_buffer_crc32(0,(char *)&pipe_name,sizeof(pipe_name)), pipe_name.key_4th); /* nt_name */ nt_name.strlen = (uint16_t)(sizeof(pipe_name) - sizeof(wchar16_t)); nt_name.maxlen = (uint16_t)(sizeof(pipe_name)); nt_name.buffer = (uint16_t *)&pipe_name; /* init security structure */ sqos.length = sizeof(sqos); sqos.impersonation_level = NT_SECURITY_ANONYMOUS; sqos.context_tracking_mode = NT_SECURITY_TRACKING_STATIC; sqos.effective_only = 1; /* oa */ oa.len = sizeof(oa); oa.root_dir = (void *)0; oa.obj_name = &nt_name; oa.obj_attr = 0x0; oa.sec_desc = (nt_security_descriptor *)0; oa.sec_qos = &sqos; timeout.ihigh = 0xffffffff; timeout.ulow = 0x0; /* the reading end */ status = __ntapi->zw_create_named_pipe_file( &hread, NT_GENERIC_READ | NT_SEC_SYNCHRONIZE | NT_FILE_WRITE_ATTRIBUTES, &oa, &iosb, NT_FILE_SHARE_READ | NT_FILE_SHARE_WRITE, NT_FILE_CREATE, NT_FILE_ASYNCHRONOUS_IO, NT_FILE_PIPE_BYTE_STREAM_TYPE, NT_FILE_PIPE_BYTE_STREAM_MODE, NT_FILE_PIPE_QUEUE_OPERATION, 1, advisory_buffer_size, advisory_buffer_size, &timeout); if (status != NT_STATUS_SUCCESS) { return status; } /* the writing end(s) */ status = __ntapi->zw_open_file( &hwrite, NT_GENERIC_WRITE | NT_SEC_SYNCHRONIZE | NT_FILE_READ_ATTRIBUTES, &oa, &iosb, NT_FILE_SHARE_READ | NT_FILE_SHARE_WRITE, NT_FILE_WRITE_THROUGH | NT_FILE_SYNCHRONOUS_IO_ALERT | NT_FILE_NON_DIRECTORY_FILE); if (status != NT_STATUS_SUCCESS) { __ntapi->zw_close(hread); return status; } *hpipe_read = hread; *hpipe_write = hwrite; return status; }