dinput/tests: Add some windows.gaming.input device tests.
[wine.git] / dlls / ntoskrnl.exe / tests / driver_netio.c
blob4ebacc7cf140dac48263f88a687f64b18dab177d
1 /*
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
21 #include <stdarg.h>
22 #include <stdio.h>
24 #include "ntstatus.h"
25 #define WIN32_NO_STATUS
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winternl.h"
29 #include "winioctl.h"
30 #include "ddk/ntddk.h"
31 #include "ddk/ntifs.h"
32 #include "ddk/wdm.h"
33 #include "ddk/wsk.h"
35 #include "driver.h"
37 #include "utils.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;
49 static IRP *wsk_irp;
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
65 NTSTATUS status;
67 client_npi.Dispatch = &client_dispatch;
68 status = WskRegister(&client_npi, &registration);
69 ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status);
71 status = WskCaptureProviderNPI(&registration, 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)
84 IoFreeIrp(wsk_irp);
85 WskReleaseProviderNPI(&registration);
86 WskDeregister(&registration);
89 static void test_wsk_get_address_info(void)
91 UNICODE_STRING node_name, service_name;
92 ADDRINFOEXW *result, *addr_info;
93 unsigned int count;
94 NTSTATUS status;
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);
138 count = 0;
139 addr_info = result;
140 while (addr_info)
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));
150 ++count;
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;
176 MDL *mdl1, *mdl2;
177 NTSTATUS status;
178 KEVENT event;
179 IRP *irp;
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);
191 wsk_buf1.Mdl = mdl1;
192 wsk_buf1.Offset = 0;
193 wsk_buf1.Length = TEST_BUFFER_LENGTH;
194 wsk_buf2 = wsk_buf1;
195 wsk_buf2.Mdl = mdl2;
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);
287 if (0)
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);
376 IoFreeIrp(irp);
378 IoFreeMdl(mdl1);
379 IoFreeMdl(mdl2);
380 ExFreePool(buffer1);
381 ExFreePool(buffer2);
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;
390 WSK_SOCKET *socket;
391 NTSTATUS status;
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;
470 if (!buffer)
471 return STATUS_ACCESS_VIOLATION;
473 netio_init();
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);
491 break;
492 default:
493 break;
496 if (status != STATUS_PENDING)
498 irp->IoStatus.Status = status;
499 IoCompleteRequest(irp, IO_NO_INCREMENT);
501 return status;
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)
513 netio_uninit();
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);
531 winetest_cleanup();
534 NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, PUNICODE_STRING registry)
536 UNICODE_STRING nameW, linkW;
537 NTSTATUS status;
539 if ((status = winetest_init()))
540 return status;
542 DbgPrint("Loading driver.\n");
544 driver_obj = driver;
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;