| |
| |
| |
| |
| |
| |
| #include <psxtypes/psxtypes.h> |
| #include <ntapi/nt_object.h> |
| #include <ntapi/nt_file.h> |
| #include <ntapi/nt_socket.h> |
| #include <ntapi/ntapi.h> |
| #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; |
| |
| |
| if (addrlen) { |
| __ntapi->tt_aligned_block_memset( |
| &afd_send, |
| 0,sizeof(afd_send)); |
| |
| afd_send.pmeta = &afd_send.extlen; |
| afd_send.addrlen = addrlen; |
| afd_send.addr = addr; |
| } |
| |
| |
| afd_buffer.length = len; |
| afd_buffer.buffer = (char *)buffer; |
| |
| |
| 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; |
| |
| 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); |
| |
| if (hssocket->iostatus && (hssocket->ntflags & __NT_FILE_SYNC_IO)) |
| __ntapi->sc_wait(hssocket,iosb,&hssocket->timeout); |
| |
| if (!hssocket->iostatus && bytes_sent) |
| *bytes_sent = iosb->info; |
| |
| return hssocket->iostatus; |
| } |