2 * Unit tests for netio.sys (kernel sockets)
4 * Copyright 2020 Paul Gofman for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #define WIN32_NO_STATUS
30 #include "ddk/ntddk.h"
31 #include "ddk/ntifs.h"
39 static DRIVER_OBJECT
*driver_obj
;
40 static DEVICE_OBJECT
*device_obj
;
42 static const WCHAR driver_link
[] = L
"\\DosDevices\\winetest_netio";
43 static const WCHAR device_name
[] = L
"\\Device\\winetest_netio";
45 static WSK_CLIENT_NPI client_npi
;
46 static WSK_REGISTRATION registration
;
47 static WSK_PROVIDER_NPI provider_npi
;
48 static KEVENT irp_complete_event
;
51 static NTSTATUS WINAPI
irp_completion_routine(DEVICE_OBJECT
*reserved
, IRP
*irp
, void *context
)
53 KEVENT
*event
= context
;
55 KeSetEvent(event
, 1, FALSE
);
56 return STATUS_MORE_PROCESSING_REQUIRED
;
59 static void netio_init(void)
61 static const WSK_CLIENT_DISPATCH client_dispatch
=
63 MAKE_WSK_VERSION(1, 0), 0, NULL
67 client_npi
.Dispatch
= &client_dispatch
;
68 status
= WskRegister(&client_npi
, ®istration
);
69 ok(status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", status
);
71 status
= WskCaptureProviderNPI(®istration
, WSK_INFINITE_WAIT
, &provider_npi
);
72 ok(status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", status
);
74 ok(provider_npi
.Dispatch
->Version
>= MAKE_WSK_VERSION(1, 0), "Got unexpected version %#x.\n",
75 provider_npi
.Dispatch
->Version
);
76 ok(!!provider_npi
.Client
, "Got null WSK_CLIENT.\n");
78 KeInitializeEvent(&irp_complete_event
, SynchronizationEvent
, FALSE
);
79 wsk_irp
= IoAllocateIrp(1, FALSE
);
82 static void netio_uninit(void)
85 WskReleaseProviderNPI(®istration
);
86 WskDeregister(®istration
);
89 static void test_wsk_get_address_info(void)
91 UNICODE_STRING node_name
, service_name
;
92 ADDRINFOEXW
*result
, *addr_info
;
96 RtlInitUnicodeString(&service_name
, L
"12345");
98 wsk_irp
->IoStatus
.Status
= 0xdeadbeef;
99 wsk_irp
->IoStatus
.Information
= 0xdeadbeef;
100 status
= provider_npi
.Dispatch
->WskGetAddressInfo(provider_npi
.Client
, &node_name
, &service_name
,
101 NS_ALL
, NULL
, NULL
, &result
, NULL
, NULL
, NULL
);
102 ok(status
== STATUS_INVALID_PARAMETER
, "Got unexpected status %#x.\n", status
);
103 ok(wsk_irp
->IoStatus
.Status
== 0xdeadbeef, "Got unexpected status %#x.\n", wsk_irp
->IoStatus
.Status
);
104 ok(wsk_irp
->IoStatus
.Information
== 0xdeadbeef, "Got unexpected Information %#lx.\n",
105 wsk_irp
->IoStatus
.Information
);
107 RtlInitUnicodeString(&node_name
, L
"dead.beef");
109 IoReuseIrp(wsk_irp
, STATUS_UNSUCCESSFUL
);
110 IoSetCompletionRoutine(wsk_irp
, irp_completion_routine
, &irp_complete_event
, TRUE
, TRUE
, TRUE
);
111 wsk_irp
->IoStatus
.Status
= 0xdeadbeef;
112 wsk_irp
->IoStatus
.Information
= 0xdeadbeef;
113 status
= provider_npi
.Dispatch
->WskGetAddressInfo(provider_npi
.Client
, &node_name
, &service_name
,
114 NS_ALL
, NULL
, NULL
, &result
, NULL
, NULL
, wsk_irp
);
115 ok(status
== STATUS_PENDING
, "Got unexpected status %#x.\n", status
);
116 status
= KeWaitForSingleObject(&irp_complete_event
, Executive
, KernelMode
, FALSE
, NULL
);
117 ok(status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", status
);
118 ok(wsk_irp
->IoStatus
.Status
== STATUS_NOT_FOUND
119 || broken(wsk_irp
->IoStatus
.Status
== STATUS_NO_MATCH
) /* Win7 */,
120 "Got unexpected status %#x.\n", wsk_irp
->IoStatus
.Status
);
121 ok(wsk_irp
->IoStatus
.Information
== 0, "Got unexpected Information %#lx.\n",
122 wsk_irp
->IoStatus
.Information
);
124 RtlInitUnicodeString(&node_name
, L
"127.0.0.1");
125 IoReuseIrp(wsk_irp
, STATUS_UNSUCCESSFUL
);
126 IoSetCompletionRoutine(wsk_irp
, irp_completion_routine
, &irp_complete_event
, TRUE
, TRUE
, TRUE
);
127 wsk_irp
->IoStatus
.Status
= 0xdeadbeef;
128 wsk_irp
->IoStatus
.Information
= 0xdeadbeef;
129 status
= provider_npi
.Dispatch
->WskGetAddressInfo(provider_npi
.Client
, &node_name
, &service_name
,
130 NS_ALL
, NULL
, NULL
, &result
, NULL
, NULL
, wsk_irp
);
131 ok(status
== STATUS_PENDING
, "Got unexpected status %#x.\n", status
);
132 status
= KeWaitForSingleObject(&irp_complete_event
, Executive
, KernelMode
, FALSE
, NULL
);
133 ok(status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", status
);
134 ok(wsk_irp
->IoStatus
.Status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", wsk_irp
->IoStatus
.Status
);
135 ok(wsk_irp
->IoStatus
.Information
== 0, "Got unexpected Information %#lx.\n",
136 wsk_irp
->IoStatus
.Information
);
142 struct sockaddr_in
*addr
= (struct sockaddr_in
*)addr_info
->ai_addr
;
144 ok(addr_info
->ai_addrlen
== sizeof(*addr
), "Got unexpected ai_addrlen %I64u.\n", (UINT64
)addr_info
->ai_addrlen
);
145 ok(addr
->sin_family
== AF_INET
, "Got unexpected sin_family %u.\n", addr
->sin_family
);
146 ok(ntohs(addr
->sin_port
) == 12345, "Got unexpected sin_port %u.\n", ntohs(addr
->sin_port
));
147 ok(ntohl(addr
->sin_addr
.s_addr
) == 0x7f000001, "Got unexpected sin_addr %#x.\n",
148 ntohl(addr
->sin_addr
.s_addr
));
151 addr_info
= addr_info
->ai_next
;
153 ok(count
, "Got zero addr_info count.\n");
154 provider_npi
.Dispatch
->WskFreeAddressInfo(provider_npi
.Client
, result
);
157 struct socket_context
161 #define TEST_BUFFER_LENGTH 256
163 static void test_wsk_listen_socket(void)
165 static const char test_receive_string
[] = "Client test string 1.";
166 const WSK_PROVIDER_LISTEN_DISPATCH
*tcp_dispatch
, *udp_dispatch
;
167 static const char test_send_string
[] = "Server test string 1.";
168 static const WSK_CLIENT_LISTEN_DISPATCH client_listen_dispatch
;
169 const WSK_PROVIDER_CONNECTION_DISPATCH
*accept_dispatch
;
170 WSK_SOCKET
*tcp_socket
, *udp_socket
, *accept_socket
;
171 struct sockaddr_in addr
, local_addr
, remote_addr
;
172 struct socket_context context
;
173 WSK_BUF wsk_buf1
, wsk_buf2
;
174 void *buffer1
, *buffer2
;
175 LARGE_INTEGER timeout
;
181 irp
= IoAllocateIrp(1, FALSE
);
182 KeInitializeEvent(&event
, SynchronizationEvent
, FALSE
);
184 buffer1
= ExAllocatePool(NonPagedPool
, TEST_BUFFER_LENGTH
);
185 mdl1
= IoAllocateMdl(buffer1
, TEST_BUFFER_LENGTH
, FALSE
, FALSE
, NULL
);
186 MmBuildMdlForNonPagedPool(mdl1
);
187 buffer2
= ExAllocatePool(NonPagedPool
, TEST_BUFFER_LENGTH
);
188 mdl2
= IoAllocateMdl(buffer2
, TEST_BUFFER_LENGTH
, FALSE
, FALSE
, NULL
);
189 MmBuildMdlForNonPagedPool(mdl2
);
193 wsk_buf1
.Length
= TEST_BUFFER_LENGTH
;
197 status
= provider_npi
.Dispatch
->WskSocket(NULL
, AF_INET
, SOCK_STREAM
, IPPROTO_TCP
,
198 WSK_FLAG_LISTEN_SOCKET
, &context
, &client_listen_dispatch
, NULL
, NULL
, NULL
, NULL
);
199 ok(status
== STATUS_INVALID_PARAMETER
, "Got unexpected status %#x.\n", status
);
201 IoReuseIrp(wsk_irp
, STATUS_UNSUCCESSFUL
);
202 IoSetCompletionRoutine(wsk_irp
, irp_completion_routine
, &irp_complete_event
, TRUE
, TRUE
, TRUE
);
203 status
= provider_npi
.Dispatch
->WskSocket(NULL
, AF_INET
, SOCK_STREAM
, IPPROTO_TCP
,
204 WSK_FLAG_LISTEN_SOCKET
, &context
, &client_listen_dispatch
, NULL
, NULL
, NULL
, wsk_irp
);
205 ok(status
== STATUS_INVALID_HANDLE
, "Got unexpected status %#x.\n", status
);
207 IoReuseIrp(wsk_irp
, STATUS_UNSUCCESSFUL
);
208 IoSetCompletionRoutine(wsk_irp
, irp_completion_routine
, &irp_complete_event
, TRUE
, TRUE
, TRUE
);
209 wsk_irp
->IoStatus
.Status
= 0xdeadbeef;
210 wsk_irp
->IoStatus
.Information
= 0xdeadbeef;
211 status
= provider_npi
.Dispatch
->WskSocket(provider_npi
.Client
, AF_INET
, SOCK_STREAM
, IPPROTO_TCP
,
212 WSK_FLAG_LISTEN_SOCKET
, &context
, &client_listen_dispatch
, NULL
, NULL
, NULL
, wsk_irp
);
213 ok(status
== STATUS_PENDING
, "Got unexpected status %#x.\n", status
);
214 status
= KeWaitForSingleObject(&irp_complete_event
, Executive
, KernelMode
, FALSE
, NULL
);
215 ok(status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", status
);
216 ok(wsk_irp
->IoStatus
.Status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", wsk_irp
->IoStatus
.Status
);
217 ok(wsk_irp
->IoStatus
.Information
, "Got zero Information.\n");
219 tcp_socket
= (WSK_SOCKET
*)wsk_irp
->IoStatus
.Information
;
220 tcp_dispatch
= tcp_socket
->Dispatch
;
222 IoReuseIrp(wsk_irp
, STATUS_UNSUCCESSFUL
);
223 IoSetCompletionRoutine(wsk_irp
, irp_completion_routine
, &irp_complete_event
, TRUE
, TRUE
, TRUE
);
224 status
= provider_npi
.Dispatch
->WskSocket(provider_npi
.Client
, AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
,
225 WSK_FLAG_LISTEN_SOCKET
, &context
, &client_listen_dispatch
, NULL
, NULL
, NULL
, wsk_irp
);
226 ok(status
== STATUS_PENDING
, "Got unexpected status %#x.\n", status
);
227 status
= KeWaitForSingleObject(&irp_complete_event
, Executive
, KernelMode
, FALSE
, NULL
);
228 ok(status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", status
);
229 ok(wsk_irp
->IoStatus
.Status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", wsk_irp
->IoStatus
.Status
);
230 ok(wsk_irp
->IoStatus
.Information
, "Got zero Information.\n");
232 udp_socket
= (WSK_SOCKET
*)wsk_irp
->IoStatus
.Information
;
233 udp_dispatch
= udp_socket
->Dispatch
;
235 memset(&addr
, 0, sizeof(addr
));
236 addr
.sin_family
= AF_INET
;
237 addr
.sin_port
= htons(SERVER_LISTEN_PORT
);
239 IoReuseIrp(wsk_irp
, STATUS_UNSUCCESSFUL
);
240 IoSetCompletionRoutine(wsk_irp
, irp_completion_routine
, &irp_complete_event
, TRUE
, TRUE
, TRUE
);
241 wsk_irp
->IoStatus
.Status
= 0xdeadbeef;
242 wsk_irp
->IoStatus
.Information
= 0xdeadbeef;
243 status
= udp_dispatch
->WskBind(udp_socket
, (SOCKADDR
*)&addr
, 0, wsk_irp
);
244 ok(status
== STATUS_PENDING
, "Got unexpected status %#x.\n", status
);
245 status
= KeWaitForSingleObject(&irp_complete_event
, Executive
, KernelMode
, FALSE
, NULL
);
246 ok(status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", status
);
247 ok(wsk_irp
->IoStatus
.Status
== STATUS_NOT_IMPLEMENTED
, "Got unexpected status %#x.\n", wsk_irp
->IoStatus
.Status
);
248 ok(!wsk_irp
->IoStatus
.Information
, "Got unexpected Information %#lx.\n",
249 wsk_irp
->IoStatus
.Information
);
251 IoReuseIrp(wsk_irp
, STATUS_UNSUCCESSFUL
);
252 IoSetCompletionRoutine(wsk_irp
, irp_completion_routine
, &irp_complete_event
, TRUE
, TRUE
, TRUE
);
253 status
= udp_dispatch
->Basic
.WskCloseSocket(udp_socket
, wsk_irp
);
254 ok(status
== STATUS_PENDING
, "Got unexpected status %#x.\n", status
);
255 status
= KeWaitForSingleObject(&irp_complete_event
, Executive
, KernelMode
, FALSE
, NULL
);
256 ok(status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", status
);
257 ok(wsk_irp
->IoStatus
.Status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", wsk_irp
->IoStatus
.Status
);
261 IoReuseIrp(wsk_irp
, STATUS_UNSUCCESSFUL
);
262 IoSetCompletionRoutine(wsk_irp
, irp_completion_routine
, &irp_complete_event
, TRUE
, TRUE
, TRUE
);
263 wsk_irp
->IoStatus
.Status
= 0xdeadbeef;
264 wsk_irp
->IoStatus
.Information
= 0xdeadbeef;
265 status
= tcp_dispatch
->WskBind(tcp_socket
, (SOCKADDR
*)&addr
, 0, wsk_irp
);
266 ok(status
== STATUS_PENDING
, "Got unexpected status %#x.\n", status
);
267 status
= KeWaitForSingleObject(&irp_complete_event
, Executive
, KernelMode
, FALSE
, NULL
);
268 ok(status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", status
);
269 ok(wsk_irp
->IoStatus
.Status
== STATUS_SUCCESS
270 || wsk_irp
->IoStatus
.Status
== STATUS_ADDRESS_ALREADY_ASSOCIATED
,
271 "Got unexpected status %#x.\n", wsk_irp
->IoStatus
.Status
);
272 ok(!wsk_irp
->IoStatus
.Information
, "Got unexpected Information %#lx.\n",
273 wsk_irp
->IoStatus
.Information
);
275 while (wsk_irp
->IoStatus
.Status
== STATUS_ADDRESS_ALREADY_ASSOCIATED
);
277 timeout
.QuadPart
= -2000 * 10000;
279 IoReuseIrp(wsk_irp
, STATUS_UNSUCCESSFUL
);
280 IoSetCompletionRoutine(wsk_irp
, irp_completion_routine
, &irp_complete_event
, TRUE
, TRUE
, TRUE
);
281 memset(&local_addr
, 0, sizeof(local_addr
));
282 memset(&remote_addr
, 0, sizeof(remote_addr
));
283 status
= tcp_dispatch
->WskAccept(tcp_socket
, 0, NULL
, NULL
,
284 (SOCKADDR
*)&local_addr
, (SOCKADDR
*)&remote_addr
, wsk_irp
);
285 ok(status
== STATUS_PENDING
, "Got unexpected status %#x.\n", status
);
289 /* Queuing another WskAccept in parallel with different irp results in Windows hang. */
290 IoReuseIrp(irp
, STATUS_UNSUCCESSFUL
);
291 IoSetCompletionRoutine(irp
, irp_completion_routine
, &event
, TRUE
, TRUE
, TRUE
);
292 status
= tcp_dispatch
->WskAccept(tcp_socket
, 0, NULL
, NULL
, NULL
, NULL
, irp
);
293 ok(status
== STATUS_PENDING
, "Got unexpected status %#x.\n", status
);
296 status
= KeWaitForSingleObject(&irp_complete_event
, Executive
, KernelMode
, FALSE
, &timeout
);
297 ok(status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", status
);
298 ok(wsk_irp
->IoStatus
.Status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", wsk_irp
->IoStatus
.Status
);
299 ok(wsk_irp
->IoStatus
.Information
, "Got zero Information.\n");
301 if (status
== STATUS_SUCCESS
&& wsk_irp
->IoStatus
.Status
== STATUS_SUCCESS
)
303 ok(local_addr
.sin_family
== AF_INET
, "Got unexpected sin_family %u.\n", local_addr
.sin_family
);
304 ok(local_addr
.sin_port
== htons(SERVER_LISTEN_PORT
), "Got unexpected sin_port %u.\n",
305 ntohs(local_addr
.sin_port
));
306 ok(local_addr
.sin_addr
.s_addr
== htonl(0x7f000001), "Got unexpected sin_addr %#x.\n",
307 ntohl(local_addr
.sin_addr
.s_addr
));
309 ok(remote_addr
.sin_family
== AF_INET
, "Got unexpected sin_family %u.\n", remote_addr
.sin_family
);
310 ok(remote_addr
.sin_port
, "Got zero sin_port.\n");
311 ok(remote_addr
.sin_addr
.s_addr
== htonl(0x7f000001), "Got unexpected sin_addr %#x.\n",
312 ntohl(remote_addr
.sin_addr
.s_addr
));
314 accept_socket
= (WSK_SOCKET
*)wsk_irp
->IoStatus
.Information
;
315 accept_dispatch
= accept_socket
->Dispatch
;
317 IoReuseIrp(irp
, STATUS_UNSUCCESSFUL
);
318 IoSetCompletionRoutine(irp
, irp_completion_routine
, &event
, TRUE
, TRUE
, TRUE
);
319 status
= accept_dispatch
->WskReceive(accept_socket
, &wsk_buf2
, 0, irp
);
320 ok(status
== STATUS_PENDING
, "Got unexpected status %#x.\n", status
);
322 IoReuseIrp(wsk_irp
, STATUS_UNSUCCESSFUL
);
323 IoSetCompletionRoutine(wsk_irp
, irp_completion_routine
, &irp_complete_event
, TRUE
, TRUE
, TRUE
);
324 strcpy(buffer1
, test_send_string
);
325 /* Setting Length in WSK_BUF greater than MDL allocation size BSODs Windows.
326 * wsk_buf1.Length = TEST_BUFFER_LENGTH * 2; */
327 status
= accept_dispatch
->WskSend(accept_socket
, &wsk_buf1
, 0, wsk_irp
);
328 ok(status
== STATUS_PENDING
, "Got unexpected status %#x.\n", status
);
330 status
= KeWaitForSingleObject(&irp_complete_event
, Executive
, KernelMode
, FALSE
, &timeout
);
331 ok(status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", status
);
332 ok(wsk_irp
->IoStatus
.Status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", wsk_irp
->IoStatus
.Status
);
333 ok(wsk_irp
->IoStatus
.Information
== TEST_BUFFER_LENGTH
, "Got unexpected status %#x.\n",
334 wsk_irp
->IoStatus
.Status
);
336 status
= KeWaitForSingleObject(&event
, Executive
, KernelMode
, FALSE
, &timeout
);
337 ok(status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", status
);
338 ok(irp
->IoStatus
.Status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", irp
->IoStatus
.Status
);
339 ok(irp
->IoStatus
.Information
== sizeof(test_receive_string
), "Got unexpected Information %#lx.\n",
340 irp
->IoStatus
.Information
);
341 ok(!strcmp(buffer2
, test_receive_string
), "Received unexpected data.\n");
343 IoReuseIrp(wsk_irp
, STATUS_UNSUCCESSFUL
);
344 IoSetCompletionRoutine(wsk_irp
, irp_completion_routine
, &irp_complete_event
, TRUE
, TRUE
, TRUE
);
345 status
= accept_dispatch
->Basic
.WskCloseSocket(accept_socket
, wsk_irp
);
346 ok(status
== STATUS_PENDING
, "Got unexpected status %#x.\n", status
);
347 status
= KeWaitForSingleObject(&irp_complete_event
, Executive
, KernelMode
, FALSE
, NULL
);
348 ok(status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", status
);
349 ok(wsk_irp
->IoStatus
.Status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", wsk_irp
->IoStatus
.Status
);
350 ok(!wsk_irp
->IoStatus
.Information
, "Got unexpected Information %#lx.\n",
351 wsk_irp
->IoStatus
.Information
);
354 /* WskAccept to be aborted by WskCloseSocket(). */
355 IoReuseIrp(irp
, STATUS_UNSUCCESSFUL
);
356 IoSetCompletionRoutine(irp
, irp_completion_routine
, &event
, TRUE
, TRUE
, TRUE
);
357 status
= tcp_dispatch
->WskAccept(tcp_socket
, 0, NULL
, NULL
, NULL
, NULL
, irp
);
358 ok(status
== STATUS_PENDING
, "Got unexpected status %#x.\n", status
);
360 IoReuseIrp(wsk_irp
, STATUS_UNSUCCESSFUL
);
361 IoSetCompletionRoutine(wsk_irp
, irp_completion_routine
, &irp_complete_event
, TRUE
, TRUE
, TRUE
);
362 wsk_irp
->IoStatus
.Status
= 0xdeadbeef;
363 wsk_irp
->IoStatus
.Information
= 0xdeadbeef;
364 status
= tcp_dispatch
->Basic
.WskCloseSocket(tcp_socket
, wsk_irp
);
365 ok(status
== STATUS_PENDING
, "Got unexpected status %#x.\n", status
);
366 status
= KeWaitForSingleObject(&irp_complete_event
, Executive
, KernelMode
, FALSE
, NULL
);
367 ok(status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", status
);
368 ok(wsk_irp
->IoStatus
.Status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", wsk_irp
->IoStatus
.Status
);
369 ok(!wsk_irp
->IoStatus
.Information
, "Got unexpected Information %#lx.\n",
370 wsk_irp
->IoStatus
.Information
);
372 status
= KeWaitForSingleObject(&event
, Executive
, KernelMode
, FALSE
, &timeout
);
373 ok(status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", status
);
374 ok(irp
->IoStatus
.Status
== STATUS_CANCELLED
, "Got unexpected status %#x.\n", irp
->IoStatus
.Status
);
375 ok(!irp
->IoStatus
.Information
, "Got unexpected Information %#lx.\n", irp
->IoStatus
.Information
);
384 static void test_wsk_connect_socket(void)
386 const WSK_PROVIDER_CONNECTION_DISPATCH
*connect_dispatch
;
387 struct socket_context context
;
388 struct sockaddr_in addr
;
389 LARGE_INTEGER timeout
;
393 timeout
.QuadPart
= -1000 * 10000;
395 IoReuseIrp(wsk_irp
, STATUS_UNSUCCESSFUL
);
396 IoSetCompletionRoutine(wsk_irp
, irp_completion_routine
, &irp_complete_event
, TRUE
, TRUE
, TRUE
);
397 wsk_irp
->IoStatus
.Status
= 0xdeadbeef;
398 wsk_irp
->IoStatus
.Information
= 0xdeadbeef;
399 status
= provider_npi
.Dispatch
->WskSocket(provider_npi
.Client
, AF_INET
, SOCK_STREAM
, IPPROTO_TCP
,
400 WSK_FLAG_CONNECTION_SOCKET
, &context
, &connect_dispatch
, NULL
, NULL
, NULL
, wsk_irp
);
401 ok(status
== STATUS_PENDING
, "Got unexpected status %#x.\n", status
);
402 status
= KeWaitForSingleObject(&irp_complete_event
, Executive
, KernelMode
, FALSE
, NULL
);
403 ok(status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", status
);
404 ok(wsk_irp
->IoStatus
.Status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", wsk_irp
->IoStatus
.Status
);
405 ok(wsk_irp
->IoStatus
.Information
, "Got zero Information.\n");
407 socket
= (WSK_SOCKET
*)wsk_irp
->IoStatus
.Information
;
408 connect_dispatch
= socket
->Dispatch
;
410 memset(&addr
, 0, sizeof(addr
));
411 addr
.sin_family
= AF_INET
;
412 addr
.sin_port
= htons(CLIENT_LISTEN_PORT
);
413 addr
.sin_addr
.s_addr
= htonl(0x7f000001);
415 IoReuseIrp(wsk_irp
, STATUS_UNSUCCESSFUL
);
416 IoSetCompletionRoutine(wsk_irp
, irp_completion_routine
, &irp_complete_event
, TRUE
, TRUE
, TRUE
);
417 status
= connect_dispatch
->WskConnect(socket
, (SOCKADDR
*)&addr
, 0, wsk_irp
);
418 ok(status
== STATUS_INVALID_DEVICE_STATE
, "Got unexpected status %#x.\n", status
);
419 status
= KeWaitForSingleObject(&irp_complete_event
, Executive
, KernelMode
, FALSE
, &timeout
);
420 ok(status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", status
);
421 ok(wsk_irp
->IoStatus
.Status
== STATUS_INVALID_DEVICE_STATE
, "Got unexpected status %#x.\n", wsk_irp
->IoStatus
.Status
);
422 ok(!wsk_irp
->IoStatus
.Information
, "Got unexpected Information %#lx.\n",
423 wsk_irp
->IoStatus
.Information
);
425 memset(&addr
, 0, sizeof(addr
));
426 addr
.sin_family
= AF_INET
;
428 IoReuseIrp(wsk_irp
, STATUS_UNSUCCESSFUL
);
429 IoSetCompletionRoutine(wsk_irp
, irp_completion_routine
, &irp_complete_event
, TRUE
, TRUE
, TRUE
);
430 wsk_irp
->IoStatus
.Status
= 0xdeadbeef;
431 wsk_irp
->IoStatus
.Information
= 0xdeadbeef;
432 status
= connect_dispatch
->WskBind(socket
, (SOCKADDR
*)&addr
, 0, wsk_irp
);
433 ok(status
== STATUS_PENDING
, "Got unexpected status %#x.\n", status
);
434 status
= KeWaitForSingleObject(&irp_complete_event
, Executive
, KernelMode
, FALSE
, NULL
);
435 ok(status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", status
);
436 ok(wsk_irp
->IoStatus
.Status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", wsk_irp
->IoStatus
.Status
);
437 ok(!wsk_irp
->IoStatus
.Information
, "Got unexpected Information %#lx.\n",
438 wsk_irp
->IoStatus
.Information
);
440 addr
.sin_port
= htons(CLIENT_LISTEN_PORT
);
441 addr
.sin_addr
.s_addr
= htonl(0x7f000001);
443 IoReuseIrp(wsk_irp
, STATUS_UNSUCCESSFUL
);
444 IoSetCompletionRoutine(wsk_irp
, irp_completion_routine
, &irp_complete_event
, TRUE
, TRUE
, TRUE
);
445 status
= connect_dispatch
->WskConnect(socket
, (SOCKADDR
*)&addr
, 0, wsk_irp
);
446 ok(status
== STATUS_PENDING
, "Got unexpected status %#x.\n", status
);
447 status
= KeWaitForSingleObject(&irp_complete_event
, Executive
, KernelMode
, FALSE
, &timeout
);
448 ok(status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", status
);
449 ok(wsk_irp
->IoStatus
.Status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", wsk_irp
->IoStatus
.Status
);
450 ok(!wsk_irp
->IoStatus
.Information
, "Got unexpected Information %#lx.\n",
451 wsk_irp
->IoStatus
.Information
);
453 IoReuseIrp(wsk_irp
, STATUS_UNSUCCESSFUL
);
454 IoSetCompletionRoutine(wsk_irp
, irp_completion_routine
, &irp_complete_event
, TRUE
, TRUE
, TRUE
);
455 wsk_irp
->IoStatus
.Status
= 0xdeadbeef;
456 wsk_irp
->IoStatus
.Information
= 0xdeadbeef;
457 status
= connect_dispatch
->Basic
.WskCloseSocket(socket
, wsk_irp
);
458 ok(status
== STATUS_PENDING
, "Got unexpected status %#x.\n", status
);
459 status
= KeWaitForSingleObject(&irp_complete_event
, Executive
, KernelMode
, FALSE
, NULL
);
460 ok(status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", status
);
461 ok(wsk_irp
->IoStatus
.Status
== STATUS_SUCCESS
, "Got unexpected status %#x.\n", wsk_irp
->IoStatus
.Status
);
462 ok(!wsk_irp
->IoStatus
.Information
, "Got unexpected Information %#lx.\n",
463 wsk_irp
->IoStatus
.Information
);
466 static NTSTATUS
main_test(DEVICE_OBJECT
*device
, IRP
*irp
, IO_STACK_LOCATION
*stack
)
468 void *buffer
= irp
->AssociatedIrp
.SystemBuffer
;
471 return STATUS_ACCESS_VIOLATION
;
474 test_wsk_get_address_info();
475 test_wsk_listen_socket();
476 test_wsk_connect_socket();
478 irp
->IoStatus
.Information
= 0;
479 return STATUS_SUCCESS
;
482 static NTSTATUS WINAPI
driver_iocontrol(DEVICE_OBJECT
*device
, IRP
*irp
)
484 IO_STACK_LOCATION
*stack
= IoGetCurrentIrpStackLocation(irp
);
485 NTSTATUS status
= STATUS_NOT_SUPPORTED
;
487 switch (stack
->Parameters
.DeviceIoControl
.IoControlCode
)
489 case IOCTL_WINETEST_MAIN_TEST
:
490 status
= main_test(device
, irp
, stack
);
496 if (status
!= STATUS_PENDING
)
498 irp
->IoStatus
.Status
= status
;
499 IoCompleteRequest(irp
, IO_NO_INCREMENT
);
504 static NTSTATUS WINAPI
driver_create(DEVICE_OBJECT
*device
, IRP
*irp
)
506 irp
->IoStatus
.Status
= STATUS_SUCCESS
;
507 IoCompleteRequest(irp
, IO_NO_INCREMENT
);
508 return STATUS_SUCCESS
;
511 static NTSTATUS WINAPI
driver_close(DEVICE_OBJECT
*device
, IRP
*irp
)
515 irp
->IoStatus
.Status
= STATUS_SUCCESS
;
516 IoCompleteRequest(irp
, IO_NO_INCREMENT
);
517 return STATUS_SUCCESS
;
520 static VOID WINAPI
driver_unload(DRIVER_OBJECT
*driver
)
522 UNICODE_STRING linkW
;
524 DbgPrint("Unloading driver.\n");
526 RtlInitUnicodeString(&linkW
, driver_link
);
527 IoDeleteSymbolicLink(&linkW
);
529 IoDeleteDevice(device_obj
);
534 NTSTATUS WINAPI
DriverEntry(DRIVER_OBJECT
*driver
, PUNICODE_STRING registry
)
536 UNICODE_STRING nameW
, linkW
;
539 if ((status
= winetest_init()))
542 DbgPrint("Loading driver.\n");
546 driver
->DriverUnload
= driver_unload
;
547 driver
->MajorFunction
[IRP_MJ_CREATE
] = driver_create
;
548 driver
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = driver_iocontrol
;
549 driver
->MajorFunction
[IRP_MJ_CLOSE
] = driver_close
;
551 RtlInitUnicodeString(&nameW
, device_name
);
552 RtlInitUnicodeString(&linkW
, driver_link
);
554 status
= IoCreateDevice(driver
, 0, &nameW
, FILE_DEVICE_UNKNOWN
, FILE_DEVICE_SECURE_OPEN
, FALSE
, &device_obj
);
555 ok(!status
, "failed to create device, status %#x\n", status
);
556 status
= IoCreateSymbolicLink(&linkW
, &nameW
);
557 ok(!status
, "failed to create link, status %#x\n", status
);
558 device_obj
->Flags
&= ~DO_DEVICE_INITIALIZING
;
560 return STATUS_SUCCESS
;