/********************************************************/
/* ntapi: Native API core library */
/* Copyright (C) 2013--2017 Z. Gilboa */
/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
/********************************************************/
#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_bind_msg {
uint32_t domain;
uint32_t type;
uint32_t service_flags;
char sa_data[14];
} nt_afd_bind_msg;
typedef struct __addr_memcpy {
uint16_t d0;
uint16_t d1;
uint16_t d2;
uint16_t d3;
uint16_t d4;
uint16_t d5;
uint16_t d6;
uint16_t d7;
} _addr_memcpy;
int32_t __cdecl __ntapi_sc_bind_v1(
__in nt_socket * hssocket,
__in const nt_sockaddr * addr,
__in uintptr_t addrlen,
__in uint32_t afdflags __optional,
__in uint32_t srvflags __optional,
__out nt_sockaddr * sockaddr __optional,
__out nt_iosb volatile * iosb __optional)
{
nt_iosb volatile siosb;
nt_afd_bind_msg afd_bind_req;
nt_afd_bind_msg afd_bind_rep;
_addr_memcpy * src;
_addr_memcpy * dst;
(void)afdflags;
(void)addrlen;
iosb = iosb ? iosb : &siosb;
/* service_flags */
if (!srvflags)
srvflags = 0x2000E;
/* afd_bind_req */
afd_bind_req.domain = hssocket->domain;
afd_bind_req.type = hssocket->type;
afd_bind_req.service_flags = srvflags;
src = (_addr_memcpy *)addr;
dst = (_addr_memcpy *)&(afd_bind_req.sa_data);
dst->d0 = src->d1;
dst->d1 = src->d2;
dst->d2 = src->d3;
dst->d3 = src->d4;
dst->d4 = src->d5;
dst->d5 = src->d6;
dst->d6 = src->d7;
hssocket->iostatus = __ntapi->zw_device_io_control_file(
hssocket->hsocket,
hssocket->hevent,
0,
0,
iosb,
NT_AFD_IOCTL_BIND,
&afd_bind_req,
sizeof(afd_bind_req),
&afd_bind_rep,
sizeof(afd_bind_rep));
__ntapi->sc_wait(hssocket,iosb,0);
if (!hssocket->iostatus && sockaddr) {
src = (_addr_memcpy *)&(afd_bind_rep.sa_data);
dst = (_addr_memcpy *)sockaddr;
dst->d1 = src->d0;
dst->d2 = src->d1;
dst->d3 = src->d2;
dst->d4 = src->d3;
dst->d5 = src->d4;
dst->d6 = src->d5;
dst->d7 = src->d6;
sockaddr->sa_addr_in4.sa_family = hssocket->domain;
}
return hssocket->iostatus;
}