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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
|
#ifndef WSK_H
#define WSK_H 1
#ifdef BUILD_USERMODE
#error "This file should only be included if building for kernel mode! Include <ksocket/ksocket.hpp> wrapper instead."
#endif
#include <ntddk.h>
#if !defined(__MINGW64__)
#error \
"This was designed to work **only** with Mingw-w64! For MSVC, please check https://github.com/wbenny/KSOCKET out"
#endif
#if (NTDDI_VERSION < NTDDI_WIN10)
#error \
"Your mingw-w64 toolchain is too old. Please use the one provided by https://github.com/utoni/mingw-w64-ddk-template"
#endif
#if !defined(__BYTE_ORDER__) || __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
#error \
"This project requires a little endian system. Does Windows support any other?"
#endif
// ---------------------------------------------------------------
// defines
// ---------------------------------------------------------------
#define WSKAPI NTAPI
#define MAKE_WSK_VERSION(Mj, Mn) ((USHORT)((Mj) << 8) | (USHORT)((Mn)&0xff))
#define WSK_NO_WAIT 0
#define WSK_INFINITE_WAIT 0xffffffff
#define WSK_FLAG_BASIC_SOCKET 0x00000000
#define WSK_FLAG_LISTEN_SOCKET 0x00000001
#define WSK_FLAG_CONNECTION_SOCKET 0x00000002
#define WSK_FLAG_DATAGRAM_SOCKET 0x00000004
#define WSK_FLAG_STREAM_SOCKET 0x00000008
#define INADDR_ANY ((ULONG)0x00000000)
// ---------------------------------------------------------------
// forward decls / opaque structs
// ---------------------------------------------------------------
struct _WSK_CLIENT_CONNECTION_DISPATCH;
typedef struct _WSK_CLIENT_CONNECTION_DISPATCH WSK_CLIENT_CONNECTION_DISPATCH;
typedef WSK_CLIENT_CONNECTION_DISPATCH *PWSK_CLIENT_CONNECTION_DISPATCH;
struct _WSK_CLIENT_NPI;
typedef struct _WSK_CLIENT_NPI WSK_CLIENT_NPI;
typedef struct _WSK_CLIENT_NPI *PWSK_CLIENT_NPI;
struct _WSK_PROVIDER_NPI;
typedef struct _WSK_PROVIDER_NPI WSK_PROVIDER_NPI;
typedef struct _WSK_PROVIDER_NPI *PWSK_PROVIDER_NPI;
typedef PVOID PWSK_CLIENT;
// ---------------------------------------------------------------
// enums
// ---------------------------------------------------------------
typedef enum {
WskSetOption, // set socket option
WskGetOption, // get socket option
WskIoctl, // socket IOCTL
WskControlMax
} WSK_CONTROL_SOCKET_TYPE,
*PWSK_CONTROL_SOCKET_TYPE;
enum {
AI_PASSIVE = 0x01,
AI_CANONNAME = 0x02,
AI_NUMERICHOST = 0x04,
AI_ALL = 0x0100,
AI_ADDRCONFIG = 0x0400,
AI_V4MAPPED = 0x0800,
AI_NON_AUTHORITATIVE = 0x4000,
AI_SECURE = 0x08000,
AI_RETURN_PREFERRED_NAMES = 0x10000,
AI_FQDN = 0x00020000,
AI_FILESERVER = 0x00040000
};
typedef enum ADDRESS_FAMILY {
AF_UNSPEC = 0,
AF_INET = 2,
AF_INET6 = 23
} ADDRESS_FAMILY;
enum {
IPPROTO_ICMP = 1,
IPPROTO_IGMP = 2,
BTHPROTO_RFCOMM = 3,
IPPROTO_TCP = 6,
IPPROTO_UDP = 17,
IPPROTO_ICMPV6 = 58,
IPPROTO_RM = 113
};
enum {
SOCK_STREAM = 1,
SOCK_DGRAM = 2,
SOCK_RAW = 3,
SOCK_RDM = 4,
SOCK_SEQPACKET = 5,
};
typedef enum {
WskInspectReject, // reject the connection request
WskInspectAccept, // proceed with accept
WskInspectPend, // delay the decision (use WskInspectComplete later)
WskInspectMax
} WSK_INSPECT_ACTION,
*PWSK_INSPECT_ACTION;
// ---------------------------------------------------------------
// general structs
// ---------------------------------------------------------------
typedef struct addrinfo {
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
size_t ai_addrlen;
char *ai_canonname;
struct sockaddr *ai_addr;
struct addrinfo *ai_next;
} ADDRINFOA, *PADDRINFOA;
typedef struct addrinfoexA {
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
size_t ai_addrlen;
char *ai_canonname;
struct sockaddr *ai_addr;
void *ai_blob;
size_t ai_bloblen;
LPGUID ai_provider;
struct addrinfoexA *ai_next;
} ADDRINFOEXA, *PADDRINFOEXA, *LPADDRINFOEXA;
typedef struct addrinfoW {
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
size_t ai_addrlen;
PWSTR ai_canonname;
struct sockaddr *ai_addr;
struct addrinfoW *ai_next;
} ADDRINFOW, *PADDRINFOW;
typedef struct addrinfoexW {
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
size_t ai_addrlen;
PWSTR ai_canonname;
struct sockaddr *ai_addr;
void *ai_blob;
size_t ai_bloblen;
LPGUID ai_provider;
struct addrinfoexW *ai_next;
} ADDRINFOEXW, *PADDRINFOEXW, *LPADDRINFOEXW;
typedef struct sockaddr {
ADDRESS_FAMILY sa_family;
CHAR sa_data[14];
} SOCKADDR, *PSOCKADDR, *LPSOCKADDR;
struct in_addr {
union {
struct {
UCHAR s_b1;
UCHAR s_b2;
UCHAR s_b3;
UCHAR s_b4;
} s_un_b;
struct {
USHORT s_w1;
USHORT s_w2;
} s_un_w;
ULONG s_addr;
};
};
typedef struct sockaddr_in {
short sin_family;
USHORT sin_port;
struct in_addr sin_addr;
char sin_zero[8];
} SOCKADDR_IN, *PSOCKADDR_IN, *LPSOCKADDR_IN;
typedef struct _WSK_SOCKET {
const VOID *Dispatch;
} WSK_SOCKET, *PWSK_SOCKET;
typedef struct _WSK_BUF {
PMDL Mdl; // Locked MDL chain
ULONG Offset; // Offset into the "first" Mdl in the chain
SIZE_T Length; // Length of data starting from Offset
} WSK_BUF, *PWSK_BUF;
typedef struct _WSK_BUF_LIST {
struct _WSK_BUF_LIST *Next;
WSK_BUF Buffer;
} WSK_BUF_LIST, *PWSK_BUF_LIST;
typedef struct _WSK_DATA_INDICATION {
struct _WSK_DATA_INDICATION *Next;
WSK_BUF Buffer;
} WSK_DATA_INDICATION, *PWSK_DATA_INDICATION;
typedef struct _WSK_INSPECT_ID {
ULONG_PTR Key;
ULONG SerialNumber;
} WSK_INSPECT_ID, *PWSK_INSPECT_ID;
typedef struct _WSACMSGHDR {
SIZE_T cmsg_len;
INT cmsg_level;
INT cmsg_type;
} WSACMSGHDR, *PWSACMSGHDR, *LPWSACMSGHDR, CMSGHDR, *PCMSGHDR;
typedef struct _WSK_DATAGRAM_INDICATION {
struct _WSK_DATAGRAM_INDICATION *Next;
WSK_BUF Buffer;
_Field_size_bytes_(ControlInfoLength) PCMSGHDR ControlInfo;
ULONG ControlInfoLength;
PSOCKADDR RemoteAddress;
} WSK_DATAGRAM_INDICATION, *PWSK_DATAGRAM_INDICATION;
typedef struct _WSK_REGISTRATION {
ULONGLONG ReservedRegistrationState;
PVOID ReservedRegistrationContext;
KSPIN_LOCK ReservedRegistrationLock;
} WSK_REGISTRATION, *PWSK_REGISTRATION;
// ---------------------------------------------------------------
// callback functions
// ---------------------------------------------------------------
typedef NTSTATUS(WSKAPI *PFN_WSK_CONTROL_SOCKET)(
_In_ PWSK_SOCKET Socket, _In_ WSK_CONTROL_SOCKET_TYPE RequestType,
_In_ ULONG ControlCode, _In_ ULONG Level, _In_ SIZE_T InputSize,
_In_opt_ PVOID InputBuffer, _In_ SIZE_T OutputSize,
_Out_opt_ PVOID OutputBuffer, _Out_opt_ SIZE_T *OutputSizeReturned,
_In_ _Out_ PIRP Irp);
typedef NTSTATUS(WSKAPI *PFN_WSK_CLOSE_SOCKET)(_In_ PWSK_SOCKET Socket,
_Inout_ PIRP Irp);
typedef NTSTATUS(WSKAPI *PFN_WSK_CONNECT)(_In_ PWSK_SOCKET Socket,
_In_ PSOCKADDR RemoteAddress,
ULONG Flags, _In_ _Out_ PIRP Irp);
typedef NTSTATUS(WSKAPI *PFN_WSK_BIND)(_In_ PWSK_SOCKET Socket,
_In_ PSOCKADDR LocalAddress,
_Reserved_ ULONG Flags,
_Inout_ PIRP Irp);
typedef NTSTATUS(WSKAPI *PFN_WSK_GET_LOCAL_ADDRESS)(
_In_ PWSK_SOCKET Socket, _Out_ PSOCKADDR LocalAddress, _Inout_ PIRP Irp);
typedef NTSTATUS(WSKAPI *PFN_WSK_GET_REMOTE_ADDRESS)(
_In_ PWSK_SOCKET Socket, _Out_ PSOCKADDR RemoteAddress, _Inout_ PIRP Irp);
typedef NTSTATUS(WSKAPI *PFN_WSK_SEND)(_In_ PWSK_SOCKET Socket,
_In_ PWSK_BUF Buffer, _In_ ULONG Flags,
_Inout_ PIRP Irp);
typedef NTSTATUS(WSKAPI *PFN_WSK_RECEIVE)(_In_ PWSK_SOCKET Socket,
_In_ PWSK_BUF Buffer,
_In_ ULONG Flags, _Inout_ PIRP Irp);
typedef NTSTATUS(WSKAPI *PFN_WSK_DISCONNECT)(_In_ PWSK_SOCKET Socket,
_In_opt_ PWSK_BUF Buffer,
_In_ ULONG Flags,
_Inout_ PIRP Irp);
typedef NTSTATUS(WSKAPI *PFN_WSK_RELEASE_DATA_INDICATION_LIST)(
_In_ PWSK_SOCKET Socket, _In_ PWSK_DATA_INDICATION DataIndication);
typedef NTSTATUS(WSKAPI *PFN_WSK_CONNECT_EX)(_In_ PWSK_SOCKET Socket,
_In_ PSOCKADDR RemoteAddress,
_In_opt_ PWSK_BUF Buffer,
_Reserved_ ULONG Flags,
_Inout_ PIRP Irp);
typedef NTSTATUS(WSKAPI *PFN_WSK_CONNECT_EX)(_In_ PWSK_SOCKET Socket,
_In_ PSOCKADDR RemoteAddress,
_In_opt_ PWSK_BUF Buffer,
_Reserved_ ULONG Flags,
_Inout_ PIRP Irp);
typedef void *PFN_WSK_SEND_EX; // reserved for system use
typedef void *PFN_WSK_RECEIVE_EX; // reserved for system use
typedef _At_(Irp->IoStatus.Information, __drv_allocatesMem(Mem))
NTSTATUS(WSKAPI *PFN_WSK_ACCEPT)(
_In_ PWSK_SOCKET ListenSocket, _Reserved_ ULONG Flags,
_In_opt_ PVOID AcceptSocketContext,
_In_opt_ CONST WSK_CLIENT_CONNECTION_DISPATCH *AcceptSocketDispatch,
_Out_opt_ PSOCKADDR LocalAddress, _Out_opt_ PSOCKADDR RemoteAddress,
_Inout_ PIRP Irp);
typedef _Must_inspect_result_ NTSTATUS(WSKAPI *PFN_WSK_RECEIVE_EVENT)(
_In_opt_ PVOID SocketContext, _In_ ULONG Flags,
_In_opt_ PWSK_DATA_INDICATION DataIndication, _In_ SIZE_T BytesIndicated,
_Inout_ SIZE_T *BytesAccepted);
typedef NTSTATUS(WSKAPI *PFN_WSK_DISCONNECT_EVENT)(_In_opt_ PVOID SocketContext,
_In_ ULONG Flags);
typedef NTSTATUS(WSKAPI *PFN_WSK_SEND_BACKLOG_EVENT)(
_In_opt_ PVOID SocketContext, _In_ SIZE_T IdealBacklogSize);
typedef NTSTATUS(WSKAPI *PFN_WSK_INSPECT_COMPLETE)(
_In_ PWSK_SOCKET ListenSocket, _In_ PWSK_INSPECT_ID InspectID,
_In_ WSK_INSPECT_ACTION Action, _Inout_ PIRP Irp);
typedef NTSTATUS(WSKAPI *PFN_WSK_SEND_TO)(
_In_ PWSK_SOCKET Socket, _In_ PWSK_BUF Buffer, _Reserved_ ULONG Flags,
_In_opt_ PSOCKADDR RemoteAddress, _In_ ULONG ControlInfoLength,
_In_reads_bytes_opt_(ControlInfoLength) PCMSGHDR ControlInfo,
_Inout_ PIRP Irp);
typedef _Must_inspect_result_ NTSTATUS(WSKAPI *PFN_WSK_RECEIVE_FROM_EVENT)(
_In_opt_ PVOID SocketContext, _In_ ULONG Flags,
_In_opt_ PWSK_DATAGRAM_INDICATION DataIndication);
typedef NTSTATUS(WSKAPI *PFN_WSK_RECEIVE_FROM)(
_In_ PWSK_SOCKET Socket, _In_ PWSK_BUF Buffer, _Reserved_ ULONG Flags,
_Out_opt_ PSOCKADDR RemoteAddress, _Inout_ PULONG ControlLength,
_Out_writes_bytes_opt_(*ControlLength) PCMSGHDR ControlInfo,
_Out_opt_ PULONG ControlFlags, _Inout_ PIRP Irp);
typedef NTSTATUS(WSKAPI *PFN_WSK_RELEASE_DATAGRAM_INDICATION_LIST)(
_In_ PWSK_SOCKET Socket, _In_ PWSK_DATAGRAM_INDICATION DatagramIndication);
typedef NTSTATUS(WSKAPI *PFN_WSK_SEND_MESSAGES)(
_In_ PWSK_SOCKET Socket, _In_ PWSK_BUF_LIST BufferList,
_Reserved_ ULONG Flags, _In_opt_ PSOCKADDR RemoteAddress,
_In_ ULONG ControlInfoLength,
_In_reads_bytes_opt_(ControlInfoLength) PCMSGHDR ControlInfo,
_Inout_ PIRP Irp);
typedef _At_((void *)Irp->IoStatus.Information, __drv_allocatesMem(Mem))
NTSTATUS(WSKAPI *PFN_WSK_SOCKET)(
_In_ PWSK_CLIENT Client, _In_ ADDRESS_FAMILY AddressFamily,
_In_ USHORT SocketType, _In_ ULONG Protocol, _In_ ULONG Flags,
_In_opt_ PVOID SocketContext, _In_opt_ CONST VOID *Dispatch,
_In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread,
_In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor, _Inout_ PIRP Irp);
typedef _At_(Irp->IoStatus.Information, __drv_allocatesMem(Mem))
NTSTATUS(WSKAPI *PFN_WSK_SOCKET_CONNECT)(
_In_ PWSK_CLIENT Client, _In_ USHORT SocketType, _In_ ULONG Protocol,
_In_ PSOCKADDR LocalAddress, _In_ PSOCKADDR RemoteAddress,
_Reserved_ ULONG Flags, _In_opt_ PVOID SocketContext,
_In_opt_ CONST WSK_CLIENT_CONNECTION_DISPATCH *Dispatch,
_In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread,
_In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor, _Inout_ PIRP Irp);
typedef NTSTATUS(WSKAPI *PFN_WSK_CONTROL_CLIENT)(
_In_ PWSK_CLIENT Client, _In_ ULONG ControlCode, _In_ SIZE_T InputSize,
_In_reads_bytes_opt_(InputSize) PVOID InputBuffer, _In_ SIZE_T OutputSize,
_Out_writes_bytes_opt_(OutputSize) PVOID OutputBuffer,
_Out_opt_ SIZE_T *OutputSizeReturned, _Inout_opt_ PIRP Irp);
typedef _At_(*Result, __drv_allocatesMem(Mem))
NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO)(
_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName,
_In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace,
_In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints,
_Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess,
_In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp);
typedef _At_(AddrInfo, __drv_freesMem(Mem))
VOID(WSKAPI *PFN_WSK_FREE_ADDRESS_INFO)(_In_ PWSK_CLIENT Client,
_In_ PADDRINFOEXW AddrInfo);
typedef NTSTATUS(WSKAPI *PFN_WSK_GET_NAME_INFO)(
_In_ PWSK_CLIENT Client, _In_ PSOCKADDR SockAddr, _In_ ULONG SockAddrLength,
_Out_opt_ PUNICODE_STRING NodeName, _Out_opt_ PUNICODE_STRING ServiceName,
_In_ ULONG Flags, _In_opt_ PEPROCESS OwningProcess,
_In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp);
typedef NTSTATUS(WSKAPI *PFN_WSK_CLIENT_EVENT)(
_In_opt_ PVOID ClientContext, _In_ ULONG EventType,
_In_reads_bytes_opt_(InformationLength) PVOID Information,
_In_ SIZE_T InformationLength);
_Must_inspect_result_ NTSTATUS WskRegister(
_In_ PWSK_CLIENT_NPI WskClientNpi, _Out_ PWSK_REGISTRATION WskRegistration);
_Must_inspect_result_ NTSTATUS WskCaptureProviderNPI(
_In_ PWSK_REGISTRATION WskRegistration, _In_ ULONG WaitTimeout,
_Out_ PWSK_PROVIDER_NPI WskProviderNpi);
VOID WskReleaseProviderNPI(_In_ PWSK_REGISTRATION WskRegistration);
VOID WskDeregister(_In_ PWSK_REGISTRATION WskRegistration);
// ---------------------------------------------------------------
// function pointer structs
// ---------------------------------------------------------------
typedef struct _WSK_CLIENT_CONNECTION_DISPATCH {
PFN_WSK_RECEIVE_EVENT WskReceiveEvent;
PFN_WSK_DISCONNECT_EVENT WskDisconnectEvent;
PFN_WSK_SEND_BACKLOG_EVENT WskSendBacklogEvent;
} WSK_CLIENT_CONNECTION_DISPATCH, *PWSK_CLIENT_CONNECTION_DISPATCH;
typedef struct _WSK_PROVIDER_BASIC_DISPATCH {
PFN_WSK_CONTROL_SOCKET WskControlSocket;
PFN_WSK_CLOSE_SOCKET WskCloseSocket;
} WSK_PROVIDER_BASIC_DISPATCH, *PWSK_PROVIDER_BASIC_DISPATCH;
typedef struct _WSK_PROVIDER_CONNECTION_DISPATCH {
#ifdef __cplusplus
WSK_PROVIDER_BASIC_DISPATCH Basic;
#else
WSK_PROVIDER_BASIC_DISPATCH;
#endif
PFN_WSK_BIND WskBind;
PFN_WSK_CONNECT WskConnect;
PFN_WSK_GET_LOCAL_ADDRESS WskGetLocalAddress;
PFN_WSK_GET_REMOTE_ADDRESS WskGetRemoteAddress;
PFN_WSK_SEND WskSend;
PFN_WSK_RECEIVE WskReceive;
PFN_WSK_DISCONNECT WskDisconnect;
PFN_WSK_RELEASE_DATA_INDICATION_LIST WskRelease;
PFN_WSK_CONNECT_EX WskConnectEx;
PFN_WSK_SEND_EX WskSendEx;
PFN_WSK_RECEIVE_EX WskReceiveEx;
} WSK_PROVIDER_CONNECTION_DISPATCH, *PWSK_PROVIDER_CONNECTION_DISPATCH;
typedef struct _WSK_PROVIDER_LISTEN_DISPATCH {
#ifdef __cplusplus
WSK_PROVIDER_BASIC_DISPATCH Basic;
#else
WSK_PROVIDER_BASIC_DISPATCH;
#endif
PFN_WSK_BIND WskBind;
PFN_WSK_ACCEPT WskAccept;
PFN_WSK_INSPECT_COMPLETE WskInspectComplete;
PFN_WSK_GET_LOCAL_ADDRESS WskGetLocalAddress;
} WSK_PROVIDER_LISTEN_DISPATCH, *PWSK_PROVIDER_LISTEN_DISPATCH;
typedef struct _WSK_PROVIDER_DATAGRAM_DISPATCH {
#ifdef __cplusplus
WSK_PROVIDER_BASIC_DISPATCH Basic;
#else
WSK_PROVIDER_BASIC_DISPATCH;
#endif
PFN_WSK_BIND WskBind;
PFN_WSK_SEND_TO WskSendTo;
PFN_WSK_RECEIVE_FROM WskReceiveFrom;
PFN_WSK_RELEASE_DATAGRAM_INDICATION_LIST WskRelease;
PFN_WSK_GET_LOCAL_ADDRESS WskGetLocalAddress;
PFN_WSK_SEND_MESSAGES WskSendMessages;
} WSK_PROVIDER_DATAGRAM_DISPATCH, *PWSK_PROVIDER_DATAGRAM_DISPATCH;
typedef struct _WSK_PROVIDER_DISPATCH {
USHORT Version;
USHORT Reserved;
PFN_WSK_SOCKET WskSocket;
PFN_WSK_SOCKET_CONNECT WskSocketConnect;
PFN_WSK_CONTROL_CLIENT WskControlClient;
PFN_WSK_GET_ADDRESS_INFO WskGetAddressInfo;
PFN_WSK_FREE_ADDRESS_INFO WskFreeAddressInfo;
PFN_WSK_GET_NAME_INFO WskGetNameInfo;
} WSK_PROVIDER_DISPATCH, *PWSK_PROVIDER_DISPATCH;
typedef struct _WSK_CLIENT_DISPATCH {
USHORT Version;
USHORT Reserved;
PFN_WSK_CLIENT_EVENT WskClientEvent;
} WSK_CLIENT_DISPATCH, *PWSK_CLIENT_DISPATCH;
typedef struct _WSK_CLIENT_NPI {
PVOID ClientContext;
CONST WSK_CLIENT_DISPATCH *Dispatch;
} WSK_CLIENT_NPI, *PWSK_CLIENT_NPI;
typedef struct _WSK_PROVIDER_NPI {
PWSK_CLIENT Client;
CONST WSK_PROVIDER_DISPATCH *Dispatch;
} WSK_PROVIDER_NPI, *PWSK_PROVIDER_NPI;
#endif
|