summaryrefslogtreecommitdiffhomepage
path: root/src/socket/ntapi_sc_socket_v2.c
blob: 76169a92f346b4e6c0ed56786ba4138fd67d9fd7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/********************************************************/
/*  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_socket_attr {
	uint32_t	datagram;
	uint32_t	unknown;
	uint32_t	domain;
	uint32_t	type;
	uint32_t	protocol;
} nt_socket_attr;

typedef struct _nt_afd_socket_ea {
	uint32_t	next_entry_offset;
	unsigned char	ea_flags;
	unsigned char	ea_name_length;
	uint16_t	ea_value_length;
	char		afd_open_packet[16];
	nt_socket_attr	sattr;
	uint32_t	ea_ext[4];
} nt_afd_socket_ea;

int32_t __cdecl __ntapi_sc_socket_v2(
	__out	nt_socket *		hssocket,
	__in	int32_t			domain,
	__in	int32_t			type,
	__in	uint32_t		protocol,
	__in	uint32_t		desired_access	__optional,
	__in	nt_sqos *		sqos		__optional,
	__out	nt_io_status_block *	iosb		__optional)
{
	int32_t			status;
	nt_object_attributes	oa;
	nt_io_status_block	siosb;
	nt_sqos			ssqos;
	nt_unicode_string	nt_afdep;
	uint32_t		ea_length;
	uint16_t		sdomain;
	uint16_t		stype;
	void *			_hsocket;

	wchar16_t afd_end_point[] = {
		'\\','D','e','v','i','c','e',
		'\\','A','f','d',
		'\\','E','n','d','P','o','i','n','t',
		0};

	nt_afd_socket_ea afd_ea = {
		0,
		0,
		0x0f,
		0x20,
		{'A','f','d','O','p','e','n','P','a','c','k','e','t','X','X',0},
		{0,0,0,0,0},
		{0}};

	if (domain >= 0x10000)
		return NT_STATUS_INVALID_PARAMETER_2;
	else if (type > 0x10000)
		return NT_STATUS_INVALID_PARAMETER_3;

	ea_length = sizeof(afd_ea);

	afd_ea.sattr.domain	= domain;
	afd_ea.sattr.type	= type;
	afd_ea.sattr.protocol	= protocol;

	afd_ea.sattr.datagram	= (type == NT_SOCK_DGRAM) ? protocol : 0;

	__ntapi->rtl_init_unicode_string(&nt_afdep,afd_end_point);

	if (!desired_access)
		desired_access = NT_GENERIC_READ \
				| NT_GENERIC_WRITE \
				| NT_SEC_SYNCHRONIZE \
				| NT_SEC_WRITE_DAC;

	if (!sqos) {
		ssqos.length 			= sizeof(ssqos);
		ssqos.impersonation_level	= NT_SECURITY_IMPERSONATION;
		ssqos.context_tracking_mode	= NT_SECURITY_TRACKING_DYNAMIC;
		ssqos.effective_only		= 1;
		sqos 				= &ssqos;
	}

	oa.len		= sizeof(oa);
	oa.root_dir	= (void *)0;
	oa.obj_name	= &nt_afdep;
	oa.obj_attr	= NT_OBJ_CASE_INSENSITIVE | NT_OBJ_INHERIT;
	oa.sec_desc	= (nt_security_descriptor *)0;
	oa.sec_qos	= sqos;

	iosb = iosb ? iosb : &siosb;

	if ((status = __ntapi->zw_create_file(
			&_hsocket,
			desired_access,
			&oa,
			iosb,
			0,
			0,
			NT_FILE_SHARE_READ | NT_FILE_SHARE_WRITE,
			NT_FILE_OPEN_IF,
			0,
			&afd_ea,
			ea_length)))
		return status;

	oa.obj_name = 0;
	oa.obj_attr = 0;

	sdomain = (uint16_t)domain;
	stype   = (uint16_t)type;

	hssocket->hsocket	= _hsocket;
	hssocket->ntflags	= 0;
	hssocket->domain 	= sdomain;
	hssocket->type		= stype;
	hssocket->protocol	= protocol;
	hssocket->timeout.quad	= 0;
	hssocket->iostatus	= NT_STATUS_SUCCESS;
	hssocket->waitstatus	= NT_STATUS_SUCCESS;

	return status;
}