/********************************************************/ /* ntapi: Native API core library */ /* Copyright (C) 2013--2017 Z. Gilboa */ /* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ /********************************************************/ #include #include #include #include #include #include "ntapi_impl.h" typedef struct _nt_afd_send_udp_info { nt_afd_send_info afd_send; uint32_t afd_reserved[8]; void * pmeta; uint32_t afd_unknown[4]; uint32_t extlen; uint32_t unknown; uint32_t addrlen; uint32_t reserved; const nt_sockaddr * addr; } nt_afd_send_udp_info; int32_t __cdecl __ntapi_sc_send( __in nt_socket * hssocket, __in const void * buffer, __in size_t len, __out ssize_t * bytes_sent __optional, __in const nt_sockaddr * addr __optional, __in size_t addrlen __optional, __in uintptr_t afdflags __optional, __in uintptr_t tdiflags __optional, __out nt_io_status_block * iosb __optional) { nt_afd_buffer afd_buffer; nt_afd_send_udp_info afd_send; nt_io_status_block siosb; if (addrlen && (addrlen != sizeof(nt_sockaddr_in4)) && (addrlen != sizeof(nt_sockaddr_in6))) return NT_STATUS_INVALID_PARAMETER_6; iosb = iosb ? iosb : &siosb; /* conditional connect */ if (addrlen) { __ntapi->tt_aligned_block_memset( &afd_send, 0,sizeof(afd_send)); afd_send.pmeta = &afd_send.extlen; afd_send.addrlen = (uint32_t)addrlen; afd_send.addr = addr; } /* afd_buffer */ afd_buffer.length = len; afd_buffer.buffer = (char *)buffer; /* afd_send.afd_send */ afd_send.afd_send.afd_buffer_array = &afd_buffer; afd_send.afd_send.buffer_count = 1; afd_send.afd_send.afd_flags = (uint32_t)afdflags; afd_send.afd_send.tdi_flags = (uint32_t)tdiflags; if ((hssocket->iostatus = __ntapi->zw_device_io_control_file( hssocket->hsocket, hssocket->hevent, 0, 0, iosb, addrlen ? NT_AFD_IOCTL_UDP_SEND : NT_AFD_IOCTL_SEND, &afd_send, addrlen ? sizeof(afd_send) : sizeof(afd_send.afd_send), 0, 0))) return hssocket->iostatus; if (bytes_sent) *bytes_sent = iosb->info; return NT_STATUS_SUCCESS; }