Blame src/socket/ntapi_sc_accept.c

dd89bb
/********************************************************/
dd89bb
/*  ntapi: Native API core library                      */
dde53a
/*  Copyright (C) 2013--2017  Z. Gilboa                 */
dd89bb
/*  Released under GPLv2 and GPLv3; see COPYING.NTAPI.  */
dd89bb
/********************************************************/
dd89bb
dd89bb
#include <psxtypes/psxtypes.h>
dd89bb
#include <ntapi/nt_object.h>
dd89bb
#include <ntapi/nt_file.h>
dd89bb
#include <ntapi/nt_socket.h>
dd89bb
#include <ntapi/ntapi.h>
dd89bb
#include "ntapi_impl.h"
dd89bb
dd89bb
typedef struct __addr_memcpy {
dd89bb
	uint64_t	d0;
dd89bb
	uint64_t	d1;
4543c9
	uint64_t	d2;
4543c9
	uint32_t	d3;
dd89bb
} _addr_memcpy;
dd89bb
dd89bb
dd89bb
int32_t __cdecl __ntapi_sc_accept(
dd89bb
	__in	nt_socket *		hssock_listen,
dd89bb
	__out	nt_sockaddr *		addr,
dd89bb
	__out	uint16_t *		addrlen,
dd89bb
	__out	nt_socket *		hssock_dedicated,
dd89bb
	__in	uintptr_t		afdflags	__optional,
dd89bb
	__in	uintptr_t		tdiflags	__optional,
dd89bb
	__out	nt_io_status_block *	iosb		__optional)
dd89bb
{
dd89bb
	int32_t			status;
dd89bb
dd89bb
	nt_afd_accept_info	accept_info;
dd89bb
	nt_io_status_block	siosb;
dd89bb
dd89bb
	_addr_memcpy *		src;
dd89bb
	_addr_memcpy *		dst;
dd89bb
c713d8
	(void)afdflags;
c713d8
	(void)tdiflags;
c713d8
dd89bb
	iosb = iosb ? iosb : &siosb;
dd89bb
dd89bb
	/* establish kernel connection */
dd89bb
	if ((status = __ntapi->sc_server_accept_connection(
dd89bb
			hssock_listen,
dd89bb
			&accept_info,
dd89bb
			iosb)))
dd89bb
		return status;
dd89bb
dd89bb
	/* create connection-dedicated socket handle */
dd89bb
	if ((status = __ntapi->sc_socket(
dd89bb
			hssock_dedicated,
dd89bb
			hssock_listen->domain,
dd89bb
			hssock_listen->type,
dd89bb
			hssock_listen->protocol,
dd89bb
			0,
dd89bb
			0,
dd89bb
			0)))
dd89bb
		return status;
dd89bb
dd89bb
	/* associate the dedicated handle with the connection */
dd89bb
	if ((status = __ntapi->sc_server_duplicate_socket(
dd89bb
			hssock_listen,
dd89bb
			hssock_dedicated,
dd89bb
			&accept_info,
dd89bb
			0)))
dd89bb
		return status;
dd89bb
dd89bb
	/* return address information */
dd89bb
	if (addr) {
dd89bb
		src = (_addr_memcpy *)&(accept_info.addr);
dd89bb
		dst = (_addr_memcpy *)addr;
dd89bb
dd89bb
		dst->d0 = src->d0;
dd89bb
		dst->d1 = src->d1;
4543c9
4543c9
		if ((size_t)iosb->info >= sizeof(accept_info.sequence)
4543c9
					+ sizeof(nt_sockaddr_in6)) {
4543c9
			dst->d2 = src->d2;
4543c9
			dst->d3 = src->d3;
4543c9
		} else {
4543c9
			dst->d2 = 0;
4543c9
			dst->d3 = 0;
4543c9
		}
dd89bb
	}
dd89bb
dd89bb
	/* return address length information */
dd89bb
	if (addrlen)
dd89bb
		*addrlen = sizeof(nt_sockaddr);
dd89bb
dd89bb
	return status;
dd89bb
}