ws2_32/tests: Fix some more test failures on Vista and older.
[wine.git] / dlls / ws2_32 / tests / afd.c
blob87e4779b9801121e50e919727ddbcea466a978b9
1 /*
2 * Unit tests for AFD device ioctls
4 * Copyright 2021 Zebediah Figura 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 <limits.h>
22 #include <stdarg.h>
23 #include "ntstatus.h"
24 #define WIN32_NO_STATUS
25 #include "windef.h"
26 #include "winternl.h"
27 #include "winioctl.h"
28 #include "winsock2.h"
29 #include "ws2tcpip.h"
30 #include "mswsock.h"
31 #include "wine/afd.h"
32 #include "wine/test.h"
34 static void tcp_socketpair(SOCKET *src, SOCKET *dst)
36 SOCKET server = INVALID_SOCKET;
37 struct sockaddr_in addr;
38 int len, ret;
40 *src = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
41 ok(*src != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
43 server = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
44 ok(server != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
46 memset(&addr, 0, sizeof(addr));
47 addr.sin_family = AF_INET;
48 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
49 ret = bind(server, (struct sockaddr *)&addr, sizeof(addr));
50 ok(!ret, "failed to bind socket, error %u\n", WSAGetLastError());
52 len = sizeof(addr);
53 ret = getsockname(server, (struct sockaddr *)&addr, &len);
54 ok(!ret, "failed to get address, error %u\n", WSAGetLastError());
56 ret = listen(server, 1);
57 ok(!ret, "failed to listen, error %u\n", WSAGetLastError());
59 ret = connect(*src, (struct sockaddr *)&addr, sizeof(addr));
60 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
62 len = sizeof(addr);
63 *dst = accept(server, (struct sockaddr *)&addr, &len);
64 ok(*dst != INVALID_SOCKET, "failed to accept socket, error %u\n", WSAGetLastError());
66 closesocket(server);
69 static void set_blocking(SOCKET s, ULONG blocking)
71 int ret;
72 blocking = !blocking;
73 ret = ioctlsocket(s, FIONBIO, &blocking);
74 ok(!ret, "got error %u\n", WSAGetLastError());
77 static void test_open_device(void)
79 OBJECT_BASIC_INFORMATION info;
80 OBJECT_ATTRIBUTES attr;
81 UNICODE_STRING string;
82 IO_STATUS_BLOCK io;
83 HANDLE handle;
84 SOCKET s;
85 int ret;
87 RtlInitUnicodeString(&string, L"\\Device\\Afd");
88 InitializeObjectAttributes(&attr, &string, 0, NULL, NULL);
89 ret = NtOpenFile(&handle, SYNCHRONIZE, &attr, &io, 0, 0);
90 ok(!ret, "got %#x\n", ret);
91 CloseHandle(handle);
93 RtlInitUnicodeString(&string, L"\\Device\\Afd\\");
94 InitializeObjectAttributes(&attr, &string, 0, NULL, NULL);
95 ret = NtOpenFile(&handle, SYNCHRONIZE, &attr, &io, 0, 0);
96 ok(!ret, "got %#x\n", ret);
97 CloseHandle(handle);
99 RtlInitUnicodeString(&string, L"\\Device\\Afd\\foobar");
100 InitializeObjectAttributes(&attr, &string, 0, NULL, NULL);
101 ret = NtOpenFile(&handle, SYNCHRONIZE, &attr, &io, 0, 0);
102 ok(!ret, "got %#x\n", ret);
103 CloseHandle(handle);
105 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
106 ret = NtQueryObject((HANDLE)s, ObjectBasicInformation, &info, sizeof(info), NULL);
107 ok(!ret, "got %#x\n", ret);
108 todo_wine ok(info.Attributes == OBJ_INHERIT, "got attributes %#x\n", info.Attributes);
109 todo_wine ok(info.GrantedAccess == (FILE_GENERIC_READ | FILE_GENERIC_WRITE | WRITE_DAC), "got access %#x\n", info.GrantedAccess);
111 closesocket(s);
114 #define check_poll(a, b, c) check_poll_(__LINE__, a, b, ~0, c, FALSE)
115 #define check_poll_mask(a, b, c, d) check_poll_(__LINE__, a, b, c, d, FALSE)
116 #define check_poll_todo(a, b, c) check_poll_(__LINE__, a, b, ~0, c, TRUE)
117 static void check_poll_(int line, SOCKET s, HANDLE event, int mask, int expect, BOOL todo)
119 struct afd_poll_params in_params = {0}, out_params = {0};
120 IO_STATUS_BLOCK io;
121 NTSTATUS ret;
123 in_params.timeout = -1000 * 10000;
124 in_params.count = 1;
125 in_params.sockets[0].socket = s;
126 in_params.sockets[0].flags = mask;
127 in_params.sockets[0].status = 0xdeadbeef;
129 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io,
130 IOCTL_AFD_POLL, &in_params, sizeof(in_params), &out_params, sizeof(out_params));
131 ok_(__FILE__, line)(!ret || ret == STATUS_PENDING, "got %#x\n", ret);
132 if (ret == STATUS_PENDING)
134 ret = WaitForSingleObject(event, 1000);
135 ok_(__FILE__, line)(!ret, "wait timed out\n");
137 ok_(__FILE__, line)(!io.Status, "got %#x\n", io.Status);
138 ok_(__FILE__, line)(io.Information == sizeof(out_params), "got %#Ix\n", io.Information);
139 ok_(__FILE__, line)(out_params.timeout == in_params.timeout, "got timeout %I64d\n", out_params.timeout);
140 ok_(__FILE__, line)(out_params.count == 1, "got count %u\n", out_params.count);
141 ok_(__FILE__, line)(out_params.sockets[0].socket == s, "got socket %#Ix\n", out_params.sockets[0].socket);
142 todo_wine_if (todo) ok_(__FILE__, line)(out_params.sockets[0].flags == expect, "got flags %#x\n", out_params.sockets[0].flags);
143 ok_(__FILE__, line)(!out_params.sockets[0].status, "got status %#x\n", out_params.sockets[0].status);
146 static void test_poll(void)
148 const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
149 char in_buffer[offsetof(struct afd_poll_params, sockets[3])];
150 char out_buffer[offsetof(struct afd_poll_params, sockets[3])];
151 struct afd_poll_params *in_params = (struct afd_poll_params *)in_buffer;
152 struct afd_poll_params *out_params = (struct afd_poll_params *)out_buffer;
153 int large_buffer_size = 1024 * 1024;
154 SOCKET client, server, listener;
155 struct sockaddr_in addr;
156 char *large_buffer;
157 IO_STATUS_BLOCK io;
158 LARGE_INTEGER now;
159 ULONG params_size;
160 HANDLE event;
161 int ret, len;
163 large_buffer = malloc(large_buffer_size);
164 memset(in_buffer, 0, sizeof(in_buffer));
165 memset(out_buffer, 0, sizeof(out_buffer));
166 event = CreateEventW(NULL, TRUE, FALSE, NULL);
168 listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
169 ret = bind(listener, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
170 ok(!ret, "got error %u\n", WSAGetLastError());
171 ret = listen(listener, 1);
172 ok(!ret, "got error %u\n", WSAGetLastError());
173 len = sizeof(addr);
174 ret = getsockname(listener, (struct sockaddr *)&addr, &len);
175 ok(!ret, "got error %u\n", WSAGetLastError());
177 params_size = offsetof(struct afd_poll_params, sockets[1]);
178 in_params->count = 1;
180 /* out_size must be at least as large as in_size. */
182 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io,
183 IOCTL_AFD_POLL, in_params, params_size, NULL, 0);
184 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
186 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io,
187 IOCTL_AFD_POLL, NULL, 0, out_params, params_size);
188 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
190 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io,
191 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size + 1);
192 ok(ret == STATUS_INVALID_HANDLE, "got %#x\n", ret);
194 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io,
195 IOCTL_AFD_POLL, in_params, params_size + 1, out_params, params_size);
196 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
198 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io,
199 IOCTL_AFD_POLL, in_params, params_size - 1, out_params, params_size - 1);
200 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
202 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io,
203 IOCTL_AFD_POLL, in_params, params_size + 1, out_params, params_size + 1);
204 ok(ret == STATUS_INVALID_HANDLE, "got %#x\n", ret);
206 in_params->count = 0;
207 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io,
208 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
209 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
211 /* Basic semantics of the ioctl. */
213 in_params->timeout = 0;
214 in_params->count = 1;
215 in_params->sockets[0].socket = listener;
216 in_params->sockets[0].flags = ~0;
217 in_params->sockets[0].status = 0xdeadbeef;
219 memset(out_params, 0, params_size);
220 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io,
221 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
222 ok(!ret, "got %#x\n", ret);
223 ok(!io.Status, "got %#x\n", io.Status);
224 ok(io.Information == offsetof(struct afd_poll_params, sockets[0]), "got %#Ix\n", io.Information);
225 ok(!out_params->timeout, "got timeout %#I64x\n", out_params->timeout);
226 ok(!out_params->count, "got count %u\n", out_params->count);
227 ok(!out_params->sockets[0].socket, "got socket %#Ix\n", out_params->sockets[0].socket);
228 ok(!out_params->sockets[0].flags, "got flags %#x\n", out_params->sockets[0].flags);
229 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
231 NtQuerySystemTime(&now);
232 in_params->timeout = now.QuadPart;
234 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io,
235 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
236 ok(ret == STATUS_PENDING, "got %#x\n", ret);
237 ret = WaitForSingleObject(event, 100);
238 ok(!ret, "got %#x\n", ret);
239 ok(io.Status == STATUS_TIMEOUT, "got %#x\n", io.Status);
240 ok(io.Information == offsetof(struct afd_poll_params, sockets[0]), "got %#Ix\n", io.Information);
241 ok(out_params->timeout == now.QuadPart, "got timeout %#I64x\n", out_params->timeout);
242 ok(!out_params->count, "got count %u\n", out_params->count);
244 in_params->timeout = -1000 * 10000;
246 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io,
247 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
248 ok(ret == STATUS_PENDING, "got %#x\n", ret);
250 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
251 set_blocking(client, FALSE);
252 ret = connect(client, (struct sockaddr *)&addr, sizeof(addr));
253 ok(!ret || WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
255 ret = WaitForSingleObject(event, 100);
256 ok(!ret, "got %#x\n", ret);
257 ok(!io.Status, "got %#x\n", io.Status);
258 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
259 ok(out_params->timeout == -1000 * 10000, "got timeout %#I64x\n", out_params->timeout);
260 ok(out_params->count == 1, "got count %u\n", out_params->count);
261 ok(out_params->sockets[0].socket == listener, "got socket %#Ix\n", out_params->sockets[0].socket);
262 ok(out_params->sockets[0].flags == AFD_POLL_ACCEPT, "got flags %#x\n", out_params->sockets[0].flags);
263 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
265 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io,
266 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
267 ok(!ret, "got %#x\n", ret);
268 ok(!io.Status, "got %#x\n", io.Status);
269 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
270 ok(out_params->timeout == -1000 * 10000, "got timeout %#I64x\n", out_params->timeout);
271 ok(out_params->count == 1, "got count %u\n", out_params->count);
272 ok(out_params->sockets[0].socket == listener, "got socket %#Ix\n", out_params->sockets[0].socket);
273 ok(out_params->sockets[0].flags == AFD_POLL_ACCEPT, "got flags %#x\n", out_params->sockets[0].flags);
274 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
276 in_params->timeout = now.QuadPart;
277 in_params->sockets[0].flags = (~0) & ~AFD_POLL_ACCEPT;
279 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io,
280 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
281 ok(ret == STATUS_PENDING, "got %#x\n", ret);
282 ret = WaitForSingleObject(event, 100);
283 ok(!ret, "got %#x\n", ret);
284 ok(io.Status == STATUS_TIMEOUT, "got %#x\n", io.Status);
285 ok(io.Information == offsetof(struct afd_poll_params, sockets[0]), "got %#Ix\n", io.Information);
286 ok(!out_params->count, "got count %u\n", out_params->count);
288 server = accept(listener, NULL, NULL);
289 ok(server != -1, "got error %u\n", WSAGetLastError());
290 set_blocking(server, FALSE);
292 /* Test flags exposed by connected sockets. */
294 check_poll(client, event, AFD_POLL_WRITE | AFD_POLL_CONNECT);
295 check_poll(server, event, AFD_POLL_WRITE | AFD_POLL_CONNECT);
297 /* It is valid to poll on a socket other than the one passed to
298 * NtDeviceIoControlFile(). */
300 in_params->count = 1;
301 in_params->sockets[0].socket = server;
302 in_params->sockets[0].flags = ~0;
304 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io,
305 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
306 ok(!ret, "got %#x\n", ret);
307 ok(!io.Status, "got %#x\n", io.Status);
308 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
309 ok(out_params->count == 1, "got count %u\n", out_params->count);
310 ok(out_params->sockets[0].socket == server, "got socket %#Ix\n", out_params->sockets[0].socket);
311 ok(out_params->sockets[0].flags == (AFD_POLL_WRITE | AFD_POLL_CONNECT),
312 "got flags %#x\n", out_params->sockets[0].flags);
313 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
315 /* Test sending data. */
317 ret = send(server, "data", 5, 0);
318 ok(ret == 5, "got %d\n", ret);
320 check_poll_mask(client, event, AFD_POLL_READ, AFD_POLL_READ);
321 check_poll(client, event, AFD_POLL_WRITE | AFD_POLL_CONNECT | AFD_POLL_READ);
322 check_poll(server, event, AFD_POLL_WRITE | AFD_POLL_CONNECT);
324 while (send(server, large_buffer, large_buffer_size, 0) == large_buffer_size);
326 check_poll(client, event, AFD_POLL_WRITE | AFD_POLL_CONNECT | AFD_POLL_READ);
327 check_poll(server, event, AFD_POLL_CONNECT);
329 /* Test sending out-of-band data. */
331 ret = send(client, "a", 1, MSG_OOB);
332 ok(ret == 1, "got %d\n", ret);
334 check_poll(client, event, AFD_POLL_WRITE | AFD_POLL_CONNECT | AFD_POLL_READ);
335 check_poll_mask(server, event, AFD_POLL_OOB, AFD_POLL_OOB);
336 check_poll(server, event, AFD_POLL_CONNECT | AFD_POLL_OOB);
338 ret = recv(server, large_buffer, 1, MSG_OOB);
339 ok(ret == 1, "got %d\n", ret);
341 check_poll(client, event, AFD_POLL_WRITE | AFD_POLL_CONNECT | AFD_POLL_READ);
342 check_poll(server, event, AFD_POLL_CONNECT);
344 ret = 1;
345 ret = setsockopt(server, SOL_SOCKET, SO_OOBINLINE, (char *)&ret, sizeof(ret));
346 ok(!ret, "got error %u\n", WSAGetLastError());
348 ret = send(client, "a", 1, MSG_OOB);
349 ok(ret == 1, "got %d\n", ret);
351 check_poll(client, event, AFD_POLL_WRITE | AFD_POLL_CONNECT | AFD_POLL_READ);
352 check_poll_mask(server, event, AFD_POLL_READ, AFD_POLL_READ);
353 check_poll(server, event, AFD_POLL_CONNECT | AFD_POLL_READ);
355 closesocket(client);
356 closesocket(server);
358 /* Test shutdown. */
360 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
361 ret = connect(client, (struct sockaddr *)&addr, sizeof(addr));
362 ok(!ret, "got error %u\n", WSAGetLastError());
363 server = accept(listener, NULL, NULL);
364 ok(server != -1, "got error %u\n", WSAGetLastError());
366 ret = shutdown(client, SD_RECEIVE);
367 ok(!ret, "got error %u\n", WSAGetLastError());
369 check_poll(client, event, AFD_POLL_WRITE | AFD_POLL_CONNECT);
370 check_poll(server, event, AFD_POLL_WRITE | AFD_POLL_CONNECT);
372 ret = shutdown(client, SD_SEND);
373 ok(!ret, "got error %u\n", WSAGetLastError());
375 check_poll(client, event, AFD_POLL_WRITE | AFD_POLL_CONNECT);
376 check_poll_mask(server, event, AFD_POLL_HUP, AFD_POLL_HUP);
377 check_poll(server, event, AFD_POLL_WRITE | AFD_POLL_CONNECT | AFD_POLL_HUP);
379 closesocket(client);
380 closesocket(server);
382 /* Test shutdown with data in the pipe. */
384 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
385 ret = connect(client, (struct sockaddr *)&addr, sizeof(addr));
386 ok(!ret, "got error %u\n", WSAGetLastError());
387 server = accept(listener, NULL, NULL);
388 ok(server != -1, "got error %u\n", WSAGetLastError());
390 ret = send(client, "data", 5, 0);
391 ok(ret == 5, "got %d\n", ret);
393 check_poll(client, event, AFD_POLL_WRITE | AFD_POLL_CONNECT);
394 check_poll_mask(server, event, AFD_POLL_READ, AFD_POLL_READ);
395 check_poll(server, event, AFD_POLL_WRITE | AFD_POLL_CONNECT | AFD_POLL_READ);
397 ret = shutdown(client, SD_SEND);
398 ok(!ret, "got error %u\n", WSAGetLastError());
400 check_poll(client, event, AFD_POLL_WRITE | AFD_POLL_CONNECT);
401 check_poll_mask(server, event, AFD_POLL_READ, AFD_POLL_READ);
402 check_poll_todo(server, event, AFD_POLL_WRITE | AFD_POLL_CONNECT | AFD_POLL_READ | AFD_POLL_HUP);
404 /* Test closing a socket while polling on it. Note that AFD_POLL_CLOSE
405 * is always returned, regardless of whether it's polled for. */
407 in_params->timeout = -1000 * 10000;
408 in_params->count = 1;
409 in_params->sockets[0].socket = client;
410 in_params->sockets[0].flags = 0;
412 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
413 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
414 ok(ret == STATUS_PENDING, "got %#x\n", ret);
416 closesocket(client);
418 ret = WaitForSingleObject(event, 100);
419 ok(!ret, "got %#x\n", ret);
420 ok(!io.Status, "got %#x\n", io.Status);
421 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
422 ok(out_params->count == 1, "got count %u\n", out_params->count);
423 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
424 ok(out_params->sockets[0].flags == AFD_POLL_CLOSE,
425 "got flags %#x\n", out_params->sockets[0].flags);
426 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
428 closesocket(server);
430 /* Test a failed connection.
432 * The following poll works even where the equivalent WSAPoll() call fails.
433 * However, it can take over 2 seconds to complete on the testbot. */
435 if (winetest_interactive)
437 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
438 set_blocking(client, FALSE);
440 in_params->timeout = -10000 * 10000;
441 in_params->count = 1;
442 in_params->sockets[0].socket = client;
443 in_params->sockets[0].flags = ~0;
445 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
446 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
447 ok(ret == STATUS_PENDING, "got %#x\n", ret);
449 addr.sin_port = 255;
450 ret = connect(client, (struct sockaddr *)&addr, sizeof(addr));
451 ok(!ret || WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
453 ret = WaitForSingleObject(event, 10000);
454 ok(!ret, "got %#x\n", ret);
455 ok(!io.Status, "got %#x\n", io.Status);
456 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
457 ok(out_params->count == 1, "got count %u\n", out_params->count);
458 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
459 ok(out_params->sockets[0].flags == AFD_POLL_CONNECT_ERR, "got flags %#x\n", out_params->sockets[0].flags);
460 ok(out_params->sockets[0].status == STATUS_CONNECTION_REFUSED, "got status %#x\n", out_params->sockets[0].status);
462 closesocket(client);
465 /* Test supplying multiple handles to the ioctl. */
467 len = sizeof(addr);
468 ret = getsockname(listener, (struct sockaddr *)&addr, &len);
469 ok(!ret, "got error %u\n", WSAGetLastError());
471 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
472 ret = connect(client, (struct sockaddr *)&addr, sizeof(addr));
473 ok(!ret, "got error %u\n", WSAGetLastError());
474 server = accept(listener, NULL, NULL);
475 ok(server != -1, "got error %u\n", WSAGetLastError());
477 in_params->count = 2;
478 in_params->sockets[0].socket = client;
479 in_params->sockets[0].flags = AFD_POLL_READ;
480 in_params->sockets[1].socket = server;
481 in_params->sockets[1].flags = AFD_POLL_READ;
483 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
484 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
485 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
487 params_size = offsetof(struct afd_poll_params, sockets[2]);
489 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
490 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
491 ok(ret == STATUS_PENDING, "got %#x\n", ret);
493 ret = send(client, "data", 5, 0);
494 ok(ret == 5, "got %d\n", ret);
496 ret = WaitForSingleObject(event, 100);
497 ok(!ret, "got %#x\n", ret);
498 ok(!io.Status, "got %#x\n", io.Status);
499 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
500 ok(out_params->count == 1, "got count %u\n", out_params->count);
501 ok(out_params->sockets[0].socket == server, "got socket %#Ix\n", out_params->sockets[0].socket);
502 ok(out_params->sockets[0].flags == AFD_POLL_READ, "got flags %#x\n", out_params->sockets[0].flags);
503 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
505 in_params->count = 2;
506 in_params->sockets[0].socket = client;
507 in_params->sockets[0].flags = AFD_POLL_READ | AFD_POLL_WRITE;
508 in_params->sockets[1].socket = server;
509 in_params->sockets[1].flags = AFD_POLL_READ | AFD_POLL_WRITE;
511 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
512 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
513 ok(!ret, "got %#x\n", ret);
514 ok(!io.Status, "got %#x\n", io.Status);
515 ok(io.Information == offsetof(struct afd_poll_params, sockets[2]), "got %#Ix\n", io.Information);
516 ok(out_params->count == 2, "got count %u\n", out_params->count);
517 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
518 ok(out_params->sockets[0].flags == AFD_POLL_WRITE, "got flags %#x\n", out_params->sockets[0].flags);
519 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
520 ok(out_params->sockets[1].socket == server, "got socket %#Ix\n", out_params->sockets[1].socket);
521 ok(out_params->sockets[1].flags == (AFD_POLL_READ | AFD_POLL_WRITE),
522 "got flags %#x\n", out_params->sockets[1].flags);
523 ok(!out_params->sockets[1].status, "got status %#x\n", out_params->sockets[1].status);
525 in_params->count = 2;
526 in_params->sockets[0].socket = client;
527 in_params->sockets[0].flags = AFD_POLL_READ | AFD_POLL_WRITE;
528 in_params->sockets[1].socket = server;
529 in_params->sockets[1].flags = AFD_POLL_READ | AFD_POLL_WRITE;
531 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
532 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
533 ok(!ret, "got %#x\n", ret);
534 ok(!io.Status, "got %#x\n", io.Status);
535 ok(io.Information == offsetof(struct afd_poll_params, sockets[2]), "got %#Ix\n", io.Information);
536 ok(out_params->count == 2, "got count %u\n", out_params->count);
537 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
538 ok(out_params->sockets[0].flags == AFD_POLL_WRITE, "got flags %#x\n", out_params->sockets[0].flags);
539 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
540 ok(out_params->sockets[1].socket == server, "got socket %#Ix\n", out_params->sockets[1].socket);
541 ok(out_params->sockets[1].flags == (AFD_POLL_READ | AFD_POLL_WRITE),
542 "got flags %#x\n", out_params->sockets[1].flags);
543 ok(!out_params->sockets[1].status, "got status %#x\n", out_params->sockets[1].status);
545 /* Close a socket while polling on another. */
547 in_params->timeout = -100 * 10000;
548 in_params->count = 1;
549 in_params->sockets[0].socket = client;
550 in_params->sockets[0].flags = AFD_POLL_READ;
551 params_size = offsetof(struct afd_poll_params, sockets[1]);
553 ret = NtDeviceIoControlFile((HANDLE)server, event, NULL, NULL, &io,
554 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
555 ok(ret == STATUS_PENDING, "got %#x\n", ret);
557 closesocket(server);
559 ret = WaitForSingleObject(event, 1000);
560 ok(!ret, "got %#x\n", ret);
561 todo_wine ok(io.Status == STATUS_TIMEOUT, "got %#x\n", io.Status);
562 todo_wine ok(io.Information == offsetof(struct afd_poll_params, sockets[0]), "got %#Ix\n", io.Information);
563 todo_wine ok(!out_params->count, "got count %u\n", out_params->count);
565 closesocket(client);
567 closesocket(listener);
569 /* Test UDP sockets. */
571 client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
572 server = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
574 check_poll(client, event, AFD_POLL_WRITE);
575 check_poll(server, event, AFD_POLL_WRITE);
577 ret = bind(client, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
578 ok(!ret, "got error %u\n", WSAGetLastError());
579 len = sizeof(addr);
580 ret = getsockname(client, (struct sockaddr *)&addr, &len);
581 ok(!ret, "got error %u\n", WSAGetLastError());
583 check_poll(client, event, AFD_POLL_WRITE);
584 check_poll(server, event, AFD_POLL_WRITE);
586 in_params->timeout = -1000 * 10000;
587 in_params->count = 1;
588 in_params->sockets[0].socket = client;
589 in_params->sockets[0].flags = (~0) & ~AFD_POLL_WRITE;
590 params_size = offsetof(struct afd_poll_params, sockets[1]);
592 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
593 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
594 ok(ret == STATUS_PENDING, "got %#x\n", ret);
596 ret = sendto(server, "data", 5, 0, (struct sockaddr *)&addr, sizeof(addr));
597 ok(ret == 5, "got %d\n", ret);
599 ret = WaitForSingleObject(event, 100);
600 ok(!ret, "got %#x\n", ret);
601 ok(!io.Status, "got %#x\n", io.Status);
602 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
603 ok(out_params->count == 1, "got count %u\n", out_params->count);
604 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
605 ok(out_params->sockets[0].flags == AFD_POLL_READ, "got flags %#x\n", out_params->sockets[0].flags);
606 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
608 closesocket(client);
609 closesocket(server);
611 /* Passing any invalid sockets yields STATUS_INVALID_HANDLE.
613 * Note however that WSAPoll() happily accepts invalid sockets. It seems
614 * user-side cached data is used: closing a handle with CloseHandle() before
615 * passing it to WSAPoll() yields ENOTSOCK. */
617 tcp_socketpair(&client, &server);
619 in_params->count = 2;
620 in_params->sockets[0].socket = 0xabacab;
621 in_params->sockets[0].flags = AFD_POLL_READ | AFD_POLL_WRITE;
622 in_params->sockets[1].socket = client;
623 in_params->sockets[1].flags = AFD_POLL_READ | AFD_POLL_WRITE;
624 params_size = offsetof(struct afd_poll_params, sockets[2]);
626 memset(&io, 0, sizeof(io));
627 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
628 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
629 ok(ret == STATUS_INVALID_HANDLE, "got %#x\n", ret);
630 todo_wine ok(!io.Status, "got %#x\n", io.Status);
631 ok(!io.Information, "got %#Ix\n", io.Information);
633 /* Test passing the same handle twice. */
635 in_params->count = 3;
636 in_params->sockets[0].socket = client;
637 in_params->sockets[0].flags = AFD_POLL_READ | AFD_POLL_WRITE;
638 in_params->sockets[1].socket = client;
639 in_params->sockets[1].flags = AFD_POLL_READ | AFD_POLL_WRITE;
640 in_params->sockets[2].socket = client;
641 in_params->sockets[2].flags = AFD_POLL_READ | AFD_POLL_WRITE | AFD_POLL_CONNECT;
642 params_size = offsetof(struct afd_poll_params, sockets[3]);
644 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
645 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
646 ok(!ret, "got %#x\n", ret);
647 ok(!io.Status, "got %#x\n", io.Status);
648 ok(io.Information == offsetof(struct afd_poll_params, sockets[3]), "got %#Ix\n", io.Information);
649 ok(out_params->count == 3, "got count %u\n", out_params->count);
650 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
651 ok(out_params->sockets[0].flags == AFD_POLL_WRITE, "got flags %#x\n", out_params->sockets[0].flags);
652 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
653 ok(out_params->sockets[1].socket == client, "got socket %#Ix\n", out_params->sockets[1].socket);
654 ok(out_params->sockets[1].flags == AFD_POLL_WRITE, "got flags %#x\n", out_params->sockets[1].flags);
655 ok(!out_params->sockets[1].status, "got status %#x\n", out_params->sockets[1].status);
656 ok(out_params->sockets[2].socket == client, "got socket %#Ix\n", out_params->sockets[2].socket);
657 ok(out_params->sockets[2].flags == (AFD_POLL_WRITE | AFD_POLL_CONNECT),
658 "got flags %#x\n", out_params->sockets[2].flags);
659 ok(!out_params->sockets[2].status, "got status %#x\n", out_params->sockets[2].status);
661 in_params->count = 2;
662 in_params->sockets[0].socket = client;
663 in_params->sockets[0].flags = AFD_POLL_READ;
664 in_params->sockets[1].socket = client;
665 in_params->sockets[1].flags = AFD_POLL_READ;
666 params_size = offsetof(struct afd_poll_params, sockets[2]);
668 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
669 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
670 ok(ret == STATUS_PENDING, "got %#x\n", ret);
672 ret = send(server, "data", 5, 0);
673 ok(ret == 5, "got %d\n", ret);
675 ret = WaitForSingleObject(event, 100);
676 ok(!ret, "got %#x\n", ret);
677 ok(!io.Status, "got %#x\n", io.Status);
678 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
679 ok(out_params->count == 1, "got count %u\n", out_params->count);
680 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
681 ok(out_params->sockets[0].flags == AFD_POLL_READ, "got flags %#x\n", out_params->sockets[0].flags);
682 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
684 closesocket(client);
685 closesocket(server);
687 CloseHandle(event);
688 free(large_buffer);
691 static void test_poll_completion_port(void)
693 struct afd_poll_params params = {0};
694 LARGE_INTEGER zero = {{0}};
695 SOCKET client, server;
696 ULONG_PTR key, value;
697 IO_STATUS_BLOCK io;
698 HANDLE event, port;
699 int ret;
701 event = CreateEventW(NULL, TRUE, FALSE, NULL);
702 tcp_socketpair(&client, &server);
703 port = CreateIoCompletionPort((HANDLE)client, NULL, 0, 0);
705 params.timeout = -100 * 10000;
706 params.count = 1;
707 params.sockets[0].socket = client;
708 params.sockets[0].flags = AFD_POLL_WRITE;
709 params.sockets[0].status = 0xdeadbeef;
711 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
712 IOCTL_AFD_POLL, &params, sizeof(params), &params, sizeof(params));
713 ok(!ret, "got %#x\n", ret);
715 ret = NtRemoveIoCompletion(port, &key, &value, &io, &zero);
716 ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
718 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, (void *)0xdeadbeef, &io,
719 IOCTL_AFD_POLL, &params, sizeof(params), &params, sizeof(params));
720 ok(!ret, "got %#x\n", ret);
722 ret = NtRemoveIoCompletion(port, &key, &value, &io, &zero);
723 ok(!ret, "got %#x\n", ret);
724 ok(!key, "got key %#Ix\n", key);
725 ok(value == 0xdeadbeef, "got value %#Ix\n", value);
727 params.timeout = 0;
728 params.count = 1;
729 params.sockets[0].socket = client;
730 params.sockets[0].flags = AFD_POLL_READ;
731 params.sockets[0].status = 0xdeadbeef;
733 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, (void *)0xdeadbeef, &io,
734 IOCTL_AFD_POLL, &params, sizeof(params), &params, sizeof(params));
735 ok(!ret, "got %#x\n", ret);
737 ret = NtRemoveIoCompletion(port, &key, &value, &io, &zero);
738 ok(!ret, "got %#x\n", ret);
739 ok(!key, "got key %#Ix\n", key);
740 ok(value == 0xdeadbeef, "got value %#Ix\n", value);
742 /* Close a socket while polling on another. */
744 params.timeout = -100 * 10000;
745 params.count = 1;
746 params.sockets[0].socket = server;
747 params.sockets[0].flags = AFD_POLL_READ;
748 params.sockets[0].status = 0xdeadbeef;
750 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, (void *)0xdeadbeef, &io,
751 IOCTL_AFD_POLL, &params, sizeof(params), &params, sizeof(params));
752 ok(ret == STATUS_PENDING, "got %#x\n", ret);
754 closesocket(client);
756 ret = WaitForSingleObject(event, 1000);
757 ok(!ret, "got %#x\n", ret);
758 todo_wine ok(io.Status == STATUS_TIMEOUT, "got %#x\n", io.Status);
759 todo_wine ok(io.Information == offsetof(struct afd_poll_params, sockets[0]), "got %#Ix\n", io.Information);
760 todo_wine ok(!params.count, "got count %u\n", params.count);
762 ret = NtRemoveIoCompletion(port, &key, &value, &io, &zero);
763 ok(!ret, "got %#x\n", ret);
764 ok(!key, "got key %#Ix\n", key);
765 ok(value == 0xdeadbeef, "got value %#Ix\n", value);
767 CloseHandle(port);
768 closesocket(server);
769 CloseHandle(event);
772 static void test_recv(void)
774 const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
775 struct afd_recv_params params = {0};
776 SOCKET client, server, listener;
777 struct sockaddr addr;
778 IO_STATUS_BLOCK io;
779 WSABUF wsabufs[2];
780 char buffer[8];
781 HANDLE event;
782 int ret, len;
784 event = CreateEventW(NULL, TRUE, FALSE, NULL);
786 listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
787 ret = bind(listener, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
788 ok(!ret, "got error %u\n", WSAGetLastError());
789 ret = listen(listener, 1);
790 ok(!ret, "got error %u\n", WSAGetLastError());
791 len = sizeof(addr);
792 ret = getsockname(listener, (struct sockaddr *)&addr, &len);
793 ok(!ret, "got error %u\n", WSAGetLastError());
795 memset(&io, 0, sizeof(io));
796 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io, IOCTL_AFD_RECV, NULL, 0, NULL, 0);
797 todo_wine ok(ret == STATUS_INVALID_CONNECTION, "got %#x\n", ret);
798 todo_wine ok(!io.Status, "got status %#x\n", io.Status);
799 ok(!io.Information, "got information %#Ix\n", io.Information);
801 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
802 ret = connect(client, (struct sockaddr *)&addr, sizeof(addr));
803 ok(!ret, "got error %u\n", WSAGetLastError());
804 server = accept(listener, NULL, NULL);
805 ok(server != -1, "got error %u\n", WSAGetLastError());
807 memset(&io, 0, sizeof(io));
808 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io, IOCTL_AFD_RECV, NULL, 0, NULL, 0);
809 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
810 todo_wine ok(!io.Status, "got status %#x\n", io.Status);
811 ok(!io.Information, "got information %#Ix\n", io.Information);
813 wsabufs[0].len = sizeof(buffer);
814 wsabufs[0].buf = buffer;
815 params.buffers = wsabufs;
816 params.count = 1;
817 params.msg_flags = AFD_MSG_NOT_OOB;
819 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
820 IOCTL_AFD_RECV, &params, sizeof(params) - 1, NULL, 0);
821 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
823 memset(&io, 0, sizeof(io));
824 memset(buffer, 0xcc, sizeof(buffer));
825 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
826 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
827 ok(ret == STATUS_PENDING, "got %#x\n", ret);
828 ok(!io.Status, "got status %#x\n", io.Status);
829 ok(!io.Information, "got information %#Ix\n", io.Information);
831 /* These structures need not remain valid. */
832 memset(&params, 0xcc, sizeof(params));
833 memset(wsabufs, 0xcc, sizeof(wsabufs));
835 ret = send(server, "data", 5, 0);
836 ok(ret == 5, "got %d\n", ret);
838 ret = WaitForSingleObject(event, 200);
839 ok(!ret, "wait timed out\n");
840 ok(!io.Status, "got %#x\n", io.Status);
841 ok(io.Information == 5, "got %#Ix\n", io.Information);
842 ok(!strcmp(buffer, "data"), "got %s\n", debugstr_an(buffer, io.Information));
844 /* Test with multiple buffers. */
846 wsabufs[0].len = 2;
847 wsabufs[0].buf = buffer;
848 wsabufs[1].len = 4;
849 wsabufs[1].buf = buffer + 3;
850 memset(&params, 0, sizeof(params));
851 params.buffers = wsabufs;
852 params.count = 2;
853 params.msg_flags = AFD_MSG_NOT_OOB;
855 memset(&io, 0, sizeof(io));
856 memset(buffer, 0xcc, sizeof(buffer));
857 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
858 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
859 ok(ret == STATUS_PENDING, "got %#x\n", ret);
860 ok(!io.Status, "got status %#x\n", io.Status);
861 ok(!io.Information, "got information %#Ix\n", io.Information);
863 ret = send(server, "data", 5, 0);
864 ok(ret == 5, "got %d\n", ret);
866 ret = WaitForSingleObject(event, 200);
867 ok(!ret, "wait timed out\n");
868 ok(!io.Status, "got %#x\n", io.Status);
869 ok(io.Information == 5, "got %#Ix\n", io.Information);
870 ok(!strcmp(buffer, "da\xccta"), "got %s\n", debugstr_an(buffer, io.Information));
872 /* Test synchronous return. */
874 ret = send(server, "data", 5, 0);
875 ok(ret == 5, "got %d\n", ret);
877 /* wait for the data to be available */
878 check_poll_mask(client, event, AFD_POLL_READ, AFD_POLL_READ);
880 memset(&io, 0xcc, sizeof(io));
881 memset(buffer, 0xcc, sizeof(buffer));
882 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
883 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
884 ok(!ret, "got %#x\n", ret);
885 ok(!io.Status, "got %#x\n", io.Status);
886 ok(io.Information == 5, "got %#Ix\n", io.Information);
887 ok(!strcmp(buffer, "da\xccta"), "got %s\n", debugstr_an(buffer, io.Information));
889 /* Test nonblocking mode. */
891 set_blocking(client, FALSE);
893 memset(&io, 0, sizeof(io));
894 memset(buffer, 0xcc, sizeof(buffer));
895 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
896 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
897 ok(ret == STATUS_DEVICE_NOT_READY, "got %#x\n", ret);
898 todo_wine ok(!io.Status, "got status %#x\n", io.Status);
899 ok(!io.Information, "got information %#Ix\n", io.Information);
901 ret = send(server, "data", 5, 0);
902 ok(ret == 5, "got %d\n", ret);
904 /* wait for the data to be available */
905 check_poll_mask(client, event, AFD_POLL_READ, AFD_POLL_READ);
907 memset(&io, 0xcc, sizeof(io));
908 memset(buffer, 0xcc, sizeof(buffer));
909 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
910 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
911 ok(!ret, "got %#x\n", ret);
912 ok(!io.Status, "got %#x\n", io.Status);
913 ok(io.Information == 5, "got %#Ix\n", io.Information);
914 ok(!strcmp(buffer, "da\xccta"), "got %s\n", debugstr_an(buffer, io.Information));
916 params.recv_flags = AFD_RECV_FORCE_ASYNC;
918 memset(&io, 0, sizeof(io));
919 memset(buffer, 0xcc, sizeof(buffer));
920 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
921 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
922 ok(ret == STATUS_PENDING, "got %#x\n", ret);
923 todo_wine ok(!io.Status, "got status %#x\n", io.Status);
924 todo_wine ok(!io.Information, "got information %#Ix\n", io.Information);
926 ret = send(server, "data", 5, 0);
927 ok(ret == 5, "got %d\n", ret);
929 ret = WaitForSingleObject(event, 200);
930 ok(!ret, "wait timed out\n");
931 ok(!io.Status, "got %#x\n", io.Status);
932 ok(io.Information == 5, "got %#Ix\n", io.Information);
933 ok(!strcmp(buffer, "da\xccta"), "got %s\n", debugstr_an(buffer, io.Information));
935 params.recv_flags = 0;
937 set_blocking(client, TRUE);
939 /* Test flags. */
941 ret = send(server, "a", 1, MSG_OOB);
942 ok(ret == 1, "got %d\n", ret);
944 ret = send(server, "data", 5, 0);
945 ok(ret == 5, "got %d\n", ret);
947 /* wait for the data to be available */
948 check_poll_mask(client, event, AFD_POLL_READ, AFD_POLL_READ);
950 memset(&io, 0xcc, sizeof(io));
951 memset(buffer, 0xcc, sizeof(buffer));
952 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
953 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
954 ok(!ret, "got %#x\n", ret);
955 ok(!io.Status, "got %#x\n", io.Status);
956 ok(io.Information == 5, "got %#Ix\n", io.Information);
957 ok(!strcmp(buffer, "da\xccta"), "got %s\n", debugstr_an(buffer, io.Information));
959 params.msg_flags = 0;
961 io.Status = 0xdeadbeef;
962 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
963 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
964 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
965 todo_wine ok(io.Status == 0xdeadbeef, "got %#x\n", io.Status);
967 params.msg_flags = AFD_MSG_OOB | AFD_MSG_NOT_OOB;
969 io.Status = 0xdeadbeef;
970 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
971 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
972 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
973 todo_wine ok(io.Status == 0xdeadbeef, "got %#x\n", io.Status);
975 params.msg_flags = AFD_MSG_OOB;
977 memset(buffer, 0xcc, sizeof(buffer));
978 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
979 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
980 todo_wine ok(!ret, "got %#x\n", ret);
981 todo_wine ok(!io.Status, "got %#x\n", io.Status);
982 todo_wine ok(io.Information == 1, "got %#Ix\n", io.Information);
983 todo_wine ok(buffer[0] == 'a', "got %s\n", debugstr_an(buffer, io.Information));
985 params.msg_flags = AFD_MSG_NOT_OOB | AFD_MSG_PEEK;
987 ret = send(server, "data", 4, 0);
988 ok(ret == 4, "got %d\n", ret);
990 /* wait for the data to be available */
991 check_poll_mask(client, event, AFD_POLL_READ, AFD_POLL_READ);
993 memset(buffer, 0xcc, sizeof(buffer));
994 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
995 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
996 ok(!ret, "got %#x\n", ret);
997 ok(!io.Status, "got %#x\n", io.Status);
998 ok(io.Information == 4, "got %#Ix\n", io.Information);
999 ok(!memcmp(buffer, "da\xccta", 5), "got %s\n", debugstr_an(buffer, io.Information));
1001 memset(buffer, 0xcc, sizeof(buffer));
1002 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1003 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1004 ok(!ret, "got %#x\n", ret);
1005 ok(!io.Status, "got %#x\n", io.Status);
1006 ok(io.Information == 4, "got %#Ix\n", io.Information);
1007 ok(!memcmp(buffer, "da\xccta", 5), "got %s\n", debugstr_an(buffer, io.Information));
1009 params.msg_flags = AFD_MSG_NOT_OOB | AFD_MSG_WAITALL;
1011 memset(buffer, 0xcc, sizeof(buffer));
1012 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1013 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1014 todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
1016 if (ret == STATUS_PENDING)
1018 ret = send(server, "s", 2, 0);
1019 ok(ret == 2, "got %d\n", ret);
1021 ret = WaitForSingleObject(event, 200);
1022 ok(!ret, "wait timed out\n");
1023 ok(!io.Status, "got %#x\n", io.Status);
1024 ok(io.Information == 6, "got %#Ix\n", io.Information);
1025 ok(!strcmp(buffer, "da\xcctas"), "got %s\n", debugstr_an(buffer, io.Information));
1028 params.msg_flags = AFD_MSG_NOT_OOB;
1030 /* Test shutdown. */
1032 memset(buffer, 0xcc, sizeof(buffer));
1033 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1034 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1035 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1037 closesocket(server);
1039 ret = WaitForSingleObject(event, 200);
1040 ok(!ret, "wait timed out\n");
1041 ok(!io.Status, "got %#x\n", io.Status);
1042 ok(!io.Information, "got %#Ix\n", io.Information);
1044 ret = shutdown(client, SD_RECEIVE);
1045 ok(!ret, "got error %u\n", WSAGetLastError());
1047 memset(&io, 0, sizeof(io));
1048 memset(buffer, 0xcc, sizeof(buffer));
1049 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1050 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1051 todo_wine ok(ret == STATUS_PIPE_DISCONNECTED, "got %#x\n", ret);
1052 ok(!io.Status, "got status %#x\n", io.Status);
1053 ok(!io.Information, "got information %#Ix\n", io.Information);
1055 closesocket(client);
1056 closesocket(listener);
1058 /* Test UDP datagrams. */
1060 client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
1061 server = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
1063 memset(buffer, 0xcc, sizeof(buffer));
1064 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1065 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1066 todo_wine ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
1067 if (ret == STATUS_PENDING)
1068 CancelIo((HANDLE)client);
1070 ret = bind(client, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
1071 ok(!ret, "got error %u\n", WSAGetLastError());
1072 len = sizeof(addr);
1073 ret = getsockname(client, (struct sockaddr *)&addr, &len);
1074 ok(!ret, "got error %u\n", WSAGetLastError());
1076 memset(buffer, 0xcc, sizeof(buffer));
1077 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1078 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1079 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1081 ret = sendto(server, "data", 5, 0, (struct sockaddr *)&addr, sizeof(addr));
1082 ok(ret == 5, "got %d\n", ret);
1084 ret = WaitForSingleObject(event, 200);
1085 ok(!ret, "wait timed out\n");
1086 ok(!io.Status, "got %#x\n", io.Status);
1087 ok(io.Information == 5, "got %#Ix\n", io.Information);
1088 ok(!strcmp(buffer, "da\xccta"), "got %s\n", debugstr_an(buffer, io.Information));
1090 /* Test a short read of a UDP datagram. */
1092 memset(buffer, 0xcc, sizeof(buffer));
1093 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1094 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1095 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1097 ret = sendto(server, "moredata", 9, 0, (struct sockaddr *)&addr, sizeof(addr));
1098 ok(ret == 9, "got %d\n", ret);
1100 ret = WaitForSingleObject(event, 200);
1101 ok(!ret, "wait timed out\n");
1102 ok(io.Status == STATUS_BUFFER_OVERFLOW, "got %#x\n", io.Status);
1103 ok(io.Information == 6, "got %#Ix\n", io.Information);
1104 ok(!memcmp(buffer, "mo\xccreda\xcc", 7), "got %s\n", debugstr_an(buffer, io.Information));
1106 ret = sendto(server, "moredata", 9, 0, (struct sockaddr *)&addr, sizeof(addr));
1107 ok(ret == 9, "got %d\n", ret);
1109 /* wait for the data to be available */
1110 check_poll_mask(client, event, AFD_POLL_READ, AFD_POLL_READ);
1112 memset(&io, 0, sizeof(io));
1113 memset(buffer, 0xcc, sizeof(buffer));
1114 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1115 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1116 ok(ret == STATUS_BUFFER_OVERFLOW, "got %#x\n", ret);
1117 ok(io.Status == STATUS_BUFFER_OVERFLOW, "got %#x\n", io.Status);
1118 ok(io.Information == 6, "got %#Ix\n", io.Information);
1119 ok(!memcmp(buffer, "mo\xccreda\xcc", 7), "got %s\n", debugstr_an(buffer, io.Information));
1121 /* Test closing a socket during an async. */
1123 memset(buffer, 0xcc, sizeof(buffer));
1124 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1125 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1126 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1128 closesocket(client);
1130 ret = WaitForSingleObject(event, 200);
1131 ok(!ret, "wait timed out\n");
1132 todo_wine ok(io.Status == STATUS_CANCELLED, "got %#x\n", io.Status);
1133 ok(!io.Information, "got %#Ix\n", io.Information);
1135 closesocket(server);
1136 CloseHandle(event);
1139 START_TEST(afd)
1141 WSADATA data;
1143 WSAStartup(MAKEWORD(2, 2), &data);
1145 test_open_device();
1146 test_poll();
1147 test_poll_completion_port();
1148 test_recv();
1150 WSACleanup();