server: Report AFD_POLL_CONNECT_ERR if a previous connection attempt failed.
[wine.git] / dlls / ws2_32 / tests / afd.c
blob4b8796157aa58e8f1c51e8102f1738925616a30f
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 == -1, "got %d\n", ret);
452 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
454 ret = WaitForSingleObject(event, 10000);
455 ok(!ret, "got %#x\n", ret);
456 ok(!io.Status, "got %#x\n", io.Status);
457 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
458 ok(out_params->count == 1, "got count %u\n", out_params->count);
459 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
460 ok(out_params->sockets[0].flags == AFD_POLL_CONNECT_ERR, "got flags %#x\n", out_params->sockets[0].flags);
461 ok(out_params->sockets[0].status == STATUS_CONNECTION_REFUSED, "got status %#x\n", out_params->sockets[0].status);
463 in_params->timeout = now.QuadPart;
464 memset(out_params, 0xcc, sizeof(out_buffer));
465 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
466 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
467 ok(!ret, "got %#x\n", ret);
468 ok(!io.Status, "got %#x\n", io.Status);
469 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
470 ok(out_params->count == 1, "got count %u\n", out_params->count);
471 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
472 ok(out_params->sockets[0].flags == AFD_POLL_CONNECT_ERR, "got flags %#x\n", out_params->sockets[0].flags);
473 ok(out_params->sockets[0].status == STATUS_CONNECTION_REFUSED, "got status %#x\n", out_params->sockets[0].status);
475 memset(out_params, 0xcc, sizeof(out_buffer));
476 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
477 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
478 ok(!ret, "got %#x\n", ret);
479 ok(!io.Status, "got %#x\n", io.Status);
480 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
481 ok(out_params->count == 1, "got count %u\n", out_params->count);
482 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
483 ok(out_params->sockets[0].flags == AFD_POLL_CONNECT_ERR, "got flags %#x\n", out_params->sockets[0].flags);
484 ok(out_params->sockets[0].status == STATUS_CONNECTION_REFUSED, "got status %#x\n", out_params->sockets[0].status);
486 ret = connect(client, (struct sockaddr *)&addr, sizeof(addr));
487 ok(ret == -1, "got %d\n", ret);
488 todo_wine ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
489 if (WSAGetLastError() == WSAECONNABORTED)
491 ret = connect(client, (struct sockaddr *)&addr, sizeof(addr));
492 ok(ret == -1, "got %d\n", ret);
493 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
496 /* A subsequent poll call returns no events, or times out. However, this
497 * can't be reliably tested, as e.g. Linux will fail the connection
498 * immediately. */
500 closesocket(client);
502 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
504 ret = connect(client, (struct sockaddr *)&addr, sizeof(addr));
505 ok(ret == -1, "expected failure\n");
506 ok(WSAGetLastError() == WSAECONNREFUSED, "got error %u\n", WSAGetLastError());
508 memset(out_params, 0xcc, sizeof(out_buffer));
509 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
510 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
511 ok(!ret, "got %#x\n", ret);
512 ok(!io.Status, "got %#x\n", io.Status);
513 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
514 ok(out_params->count == 1, "got count %u\n", out_params->count);
515 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
516 ok(out_params->sockets[0].flags == AFD_POLL_CONNECT_ERR, "got flags %#x\n", out_params->sockets[0].flags);
517 ok(out_params->sockets[0].status == STATUS_CONNECTION_REFUSED, "got status %#x\n", out_params->sockets[0].status);
519 closesocket(client);
522 /* Test supplying multiple handles to the ioctl. */
524 len = sizeof(addr);
525 ret = getsockname(listener, (struct sockaddr *)&addr, &len);
526 ok(!ret, "got error %u\n", WSAGetLastError());
528 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
529 ret = connect(client, (struct sockaddr *)&addr, sizeof(addr));
530 ok(!ret, "got error %u\n", WSAGetLastError());
531 server = accept(listener, NULL, NULL);
532 ok(server != -1, "got error %u\n", WSAGetLastError());
534 in_params->timeout = -1000 * 10000;
535 in_params->count = 2;
536 in_params->sockets[0].socket = client;
537 in_params->sockets[0].flags = AFD_POLL_READ;
538 in_params->sockets[1].socket = server;
539 in_params->sockets[1].flags = AFD_POLL_READ;
541 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
542 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
543 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
545 params_size = offsetof(struct afd_poll_params, sockets[2]);
547 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
548 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
549 ok(ret == STATUS_PENDING, "got %#x\n", ret);
551 ret = send(client, "data", 5, 0);
552 ok(ret == 5, "got %d\n", ret);
554 ret = WaitForSingleObject(event, 100);
555 ok(!ret, "got %#x\n", ret);
556 ok(!io.Status, "got %#x\n", io.Status);
557 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
558 ok(out_params->count == 1, "got count %u\n", out_params->count);
559 ok(out_params->sockets[0].socket == server, "got socket %#Ix\n", out_params->sockets[0].socket);
560 ok(out_params->sockets[0].flags == AFD_POLL_READ, "got flags %#x\n", out_params->sockets[0].flags);
561 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
563 in_params->count = 2;
564 in_params->sockets[0].socket = client;
565 in_params->sockets[0].flags = AFD_POLL_READ | AFD_POLL_WRITE;
566 in_params->sockets[1].socket = server;
567 in_params->sockets[1].flags = AFD_POLL_READ | AFD_POLL_WRITE;
569 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
570 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
571 ok(!ret, "got %#x\n", ret);
572 ok(!io.Status, "got %#x\n", io.Status);
573 ok(io.Information == offsetof(struct afd_poll_params, sockets[2]), "got %#Ix\n", io.Information);
574 ok(out_params->count == 2, "got count %u\n", out_params->count);
575 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
576 ok(out_params->sockets[0].flags == AFD_POLL_WRITE, "got flags %#x\n", out_params->sockets[0].flags);
577 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
578 ok(out_params->sockets[1].socket == server, "got socket %#Ix\n", out_params->sockets[1].socket);
579 ok(out_params->sockets[1].flags == (AFD_POLL_READ | AFD_POLL_WRITE),
580 "got flags %#x\n", out_params->sockets[1].flags);
581 ok(!out_params->sockets[1].status, "got status %#x\n", out_params->sockets[1].status);
583 in_params->count = 2;
584 in_params->sockets[0].socket = client;
585 in_params->sockets[0].flags = AFD_POLL_READ | AFD_POLL_WRITE;
586 in_params->sockets[1].socket = server;
587 in_params->sockets[1].flags = AFD_POLL_READ | AFD_POLL_WRITE;
589 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
590 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
591 ok(!ret, "got %#x\n", ret);
592 ok(!io.Status, "got %#x\n", io.Status);
593 ok(io.Information == offsetof(struct afd_poll_params, sockets[2]), "got %#Ix\n", io.Information);
594 ok(out_params->count == 2, "got count %u\n", out_params->count);
595 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
596 ok(out_params->sockets[0].flags == AFD_POLL_WRITE, "got flags %#x\n", out_params->sockets[0].flags);
597 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
598 ok(out_params->sockets[1].socket == server, "got socket %#Ix\n", out_params->sockets[1].socket);
599 ok(out_params->sockets[1].flags == (AFD_POLL_READ | AFD_POLL_WRITE),
600 "got flags %#x\n", out_params->sockets[1].flags);
601 ok(!out_params->sockets[1].status, "got status %#x\n", out_params->sockets[1].status);
603 /* Close a socket while polling on another. */
605 in_params->timeout = -100 * 10000;
606 in_params->count = 1;
607 in_params->sockets[0].socket = client;
608 in_params->sockets[0].flags = AFD_POLL_READ;
609 params_size = offsetof(struct afd_poll_params, sockets[1]);
611 ret = NtDeviceIoControlFile((HANDLE)server, event, NULL, NULL, &io,
612 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
613 ok(ret == STATUS_PENDING, "got %#x\n", ret);
615 closesocket(server);
617 ret = WaitForSingleObject(event, 1000);
618 ok(!ret, "got %#x\n", ret);
619 todo_wine ok(io.Status == STATUS_TIMEOUT, "got %#x\n", io.Status);
620 todo_wine ok(io.Information == offsetof(struct afd_poll_params, sockets[0]), "got %#Ix\n", io.Information);
621 todo_wine ok(!out_params->count, "got count %u\n", out_params->count);
623 closesocket(client);
625 closesocket(listener);
627 /* Test UDP sockets. */
629 client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
630 server = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
632 check_poll(client, event, AFD_POLL_WRITE);
633 check_poll(server, event, AFD_POLL_WRITE);
635 ret = bind(client, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
636 ok(!ret, "got error %u\n", WSAGetLastError());
637 len = sizeof(addr);
638 ret = getsockname(client, (struct sockaddr *)&addr, &len);
639 ok(!ret, "got error %u\n", WSAGetLastError());
641 check_poll(client, event, AFD_POLL_WRITE);
642 check_poll(server, event, AFD_POLL_WRITE);
644 in_params->timeout = -1000 * 10000;
645 in_params->count = 1;
646 in_params->sockets[0].socket = client;
647 in_params->sockets[0].flags = (~0) & ~AFD_POLL_WRITE;
648 params_size = offsetof(struct afd_poll_params, sockets[1]);
650 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
651 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
652 ok(ret == STATUS_PENDING, "got %#x\n", ret);
654 ret = sendto(server, "data", 5, 0, (struct sockaddr *)&addr, sizeof(addr));
655 ok(ret == 5, "got %d\n", ret);
657 ret = WaitForSingleObject(event, 100);
658 ok(!ret, "got %#x\n", ret);
659 ok(!io.Status, "got %#x\n", io.Status);
660 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
661 ok(out_params->count == 1, "got count %u\n", out_params->count);
662 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
663 ok(out_params->sockets[0].flags == AFD_POLL_READ, "got flags %#x\n", out_params->sockets[0].flags);
664 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
666 closesocket(client);
667 closesocket(server);
669 /* Passing any invalid sockets yields STATUS_INVALID_HANDLE.
671 * Note however that WSAPoll() happily accepts invalid sockets. It seems
672 * user-side cached data is used: closing a handle with CloseHandle() before
673 * passing it to WSAPoll() yields ENOTSOCK. */
675 tcp_socketpair(&client, &server);
677 in_params->count = 2;
678 in_params->sockets[0].socket = 0xabacab;
679 in_params->sockets[0].flags = AFD_POLL_READ | AFD_POLL_WRITE;
680 in_params->sockets[1].socket = client;
681 in_params->sockets[1].flags = AFD_POLL_READ | AFD_POLL_WRITE;
682 params_size = offsetof(struct afd_poll_params, sockets[2]);
684 memset(&io, 0, sizeof(io));
685 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
686 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
687 ok(ret == STATUS_INVALID_HANDLE, "got %#x\n", ret);
688 todo_wine ok(!io.Status, "got %#x\n", io.Status);
689 ok(!io.Information, "got %#Ix\n", io.Information);
691 /* Test passing the same handle twice. */
693 in_params->count = 3;
694 in_params->sockets[0].socket = client;
695 in_params->sockets[0].flags = AFD_POLL_READ | AFD_POLL_WRITE;
696 in_params->sockets[1].socket = client;
697 in_params->sockets[1].flags = AFD_POLL_READ | AFD_POLL_WRITE;
698 in_params->sockets[2].socket = client;
699 in_params->sockets[2].flags = AFD_POLL_READ | AFD_POLL_WRITE | AFD_POLL_CONNECT;
700 params_size = offsetof(struct afd_poll_params, sockets[3]);
702 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
703 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
704 ok(!ret, "got %#x\n", ret);
705 ok(!io.Status, "got %#x\n", io.Status);
706 ok(io.Information == offsetof(struct afd_poll_params, sockets[3]), "got %#Ix\n", io.Information);
707 ok(out_params->count == 3, "got count %u\n", out_params->count);
708 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
709 ok(out_params->sockets[0].flags == AFD_POLL_WRITE, "got flags %#x\n", out_params->sockets[0].flags);
710 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
711 ok(out_params->sockets[1].socket == client, "got socket %#Ix\n", out_params->sockets[1].socket);
712 ok(out_params->sockets[1].flags == AFD_POLL_WRITE, "got flags %#x\n", out_params->sockets[1].flags);
713 ok(!out_params->sockets[1].status, "got status %#x\n", out_params->sockets[1].status);
714 ok(out_params->sockets[2].socket == client, "got socket %#Ix\n", out_params->sockets[2].socket);
715 ok(out_params->sockets[2].flags == (AFD_POLL_WRITE | AFD_POLL_CONNECT),
716 "got flags %#x\n", out_params->sockets[2].flags);
717 ok(!out_params->sockets[2].status, "got status %#x\n", out_params->sockets[2].status);
719 in_params->count = 2;
720 in_params->sockets[0].socket = client;
721 in_params->sockets[0].flags = AFD_POLL_READ;
722 in_params->sockets[1].socket = client;
723 in_params->sockets[1].flags = AFD_POLL_READ;
724 params_size = offsetof(struct afd_poll_params, sockets[2]);
726 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
727 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
728 ok(ret == STATUS_PENDING, "got %#x\n", ret);
730 ret = send(server, "data", 5, 0);
731 ok(ret == 5, "got %d\n", ret);
733 ret = WaitForSingleObject(event, 100);
734 ok(!ret, "got %#x\n", ret);
735 ok(!io.Status, "got %#x\n", io.Status);
736 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
737 ok(out_params->count == 1, "got count %u\n", out_params->count);
738 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
739 ok(out_params->sockets[0].flags == AFD_POLL_READ, "got flags %#x\n", out_params->sockets[0].flags);
740 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
742 closesocket(client);
743 closesocket(server);
745 CloseHandle(event);
746 free(large_buffer);
749 static void test_poll_completion_port(void)
751 struct afd_poll_params params = {0};
752 LARGE_INTEGER zero = {{0}};
753 SOCKET client, server;
754 ULONG_PTR key, value;
755 IO_STATUS_BLOCK io;
756 HANDLE event, port;
757 int ret;
759 event = CreateEventW(NULL, TRUE, FALSE, NULL);
760 tcp_socketpair(&client, &server);
761 port = CreateIoCompletionPort((HANDLE)client, NULL, 0, 0);
763 params.timeout = -100 * 10000;
764 params.count = 1;
765 params.sockets[0].socket = client;
766 params.sockets[0].flags = AFD_POLL_WRITE;
767 params.sockets[0].status = 0xdeadbeef;
769 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
770 IOCTL_AFD_POLL, &params, sizeof(params), &params, sizeof(params));
771 ok(!ret, "got %#x\n", ret);
773 ret = NtRemoveIoCompletion(port, &key, &value, &io, &zero);
774 ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
776 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, (void *)0xdeadbeef, &io,
777 IOCTL_AFD_POLL, &params, sizeof(params), &params, sizeof(params));
778 ok(!ret, "got %#x\n", ret);
780 ret = NtRemoveIoCompletion(port, &key, &value, &io, &zero);
781 ok(!ret, "got %#x\n", ret);
782 ok(!key, "got key %#Ix\n", key);
783 ok(value == 0xdeadbeef, "got value %#Ix\n", value);
785 params.timeout = 0;
786 params.count = 1;
787 params.sockets[0].socket = client;
788 params.sockets[0].flags = AFD_POLL_READ;
789 params.sockets[0].status = 0xdeadbeef;
791 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, (void *)0xdeadbeef, &io,
792 IOCTL_AFD_POLL, &params, sizeof(params), &params, sizeof(params));
793 ok(!ret, "got %#x\n", ret);
795 ret = NtRemoveIoCompletion(port, &key, &value, &io, &zero);
796 ok(!ret, "got %#x\n", ret);
797 ok(!key, "got key %#Ix\n", key);
798 ok(value == 0xdeadbeef, "got value %#Ix\n", value);
800 /* Close a socket while polling on another. */
802 params.timeout = -100 * 10000;
803 params.count = 1;
804 params.sockets[0].socket = server;
805 params.sockets[0].flags = AFD_POLL_READ;
806 params.sockets[0].status = 0xdeadbeef;
808 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, (void *)0xdeadbeef, &io,
809 IOCTL_AFD_POLL, &params, sizeof(params), &params, sizeof(params));
810 ok(ret == STATUS_PENDING, "got %#x\n", ret);
812 closesocket(client);
814 ret = WaitForSingleObject(event, 1000);
815 ok(!ret, "got %#x\n", ret);
816 todo_wine ok(io.Status == STATUS_TIMEOUT, "got %#x\n", io.Status);
817 todo_wine ok(io.Information == offsetof(struct afd_poll_params, sockets[0]), "got %#Ix\n", io.Information);
818 todo_wine ok(!params.count, "got count %u\n", params.count);
820 ret = NtRemoveIoCompletion(port, &key, &value, &io, &zero);
821 ok(!ret, "got %#x\n", ret);
822 ok(!key, "got key %#Ix\n", key);
823 ok(value == 0xdeadbeef, "got value %#Ix\n", value);
825 CloseHandle(port);
826 closesocket(server);
827 CloseHandle(event);
830 static void test_recv(void)
832 const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
833 struct afd_recv_params params = {0};
834 SOCKET client, server, listener;
835 struct sockaddr addr;
836 IO_STATUS_BLOCK io;
837 WSABUF wsabufs[2];
838 char buffer[8];
839 HANDLE event;
840 int ret, len;
842 event = CreateEventW(NULL, TRUE, FALSE, NULL);
844 listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
845 ret = bind(listener, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
846 ok(!ret, "got error %u\n", WSAGetLastError());
847 ret = listen(listener, 1);
848 ok(!ret, "got error %u\n", WSAGetLastError());
849 len = sizeof(addr);
850 ret = getsockname(listener, (struct sockaddr *)&addr, &len);
851 ok(!ret, "got error %u\n", WSAGetLastError());
853 memset(&io, 0, sizeof(io));
854 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io, IOCTL_AFD_RECV, NULL, 0, NULL, 0);
855 todo_wine ok(ret == STATUS_INVALID_CONNECTION, "got %#x\n", ret);
856 todo_wine ok(!io.Status, "got status %#x\n", io.Status);
857 ok(!io.Information, "got information %#Ix\n", io.Information);
859 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
860 ret = connect(client, (struct sockaddr *)&addr, sizeof(addr));
861 ok(!ret, "got error %u\n", WSAGetLastError());
862 server = accept(listener, NULL, NULL);
863 ok(server != -1, "got error %u\n", WSAGetLastError());
865 memset(&io, 0, sizeof(io));
866 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io, IOCTL_AFD_RECV, NULL, 0, NULL, 0);
867 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
868 todo_wine ok(!io.Status, "got status %#x\n", io.Status);
869 ok(!io.Information, "got information %#Ix\n", io.Information);
871 wsabufs[0].len = sizeof(buffer);
872 wsabufs[0].buf = buffer;
873 params.buffers = wsabufs;
874 params.count = 1;
875 params.msg_flags = AFD_MSG_NOT_OOB;
877 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
878 IOCTL_AFD_RECV, &params, sizeof(params) - 1, NULL, 0);
879 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
881 memset(&io, 0, sizeof(io));
882 memset(buffer, 0xcc, sizeof(buffer));
883 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
884 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
885 ok(ret == STATUS_PENDING, "got %#x\n", ret);
886 ok(!io.Status, "got status %#x\n", io.Status);
887 ok(!io.Information, "got information %#Ix\n", io.Information);
889 /* These structures need not remain valid. */
890 memset(&params, 0xcc, sizeof(params));
891 memset(wsabufs, 0xcc, sizeof(wsabufs));
893 ret = send(server, "data", 5, 0);
894 ok(ret == 5, "got %d\n", ret);
896 ret = WaitForSingleObject(event, 200);
897 ok(!ret, "wait timed out\n");
898 ok(!io.Status, "got %#x\n", io.Status);
899 ok(io.Information == 5, "got %#Ix\n", io.Information);
900 ok(!strcmp(buffer, "data"), "got %s\n", debugstr_an(buffer, io.Information));
902 /* Test with multiple buffers. */
904 wsabufs[0].len = 2;
905 wsabufs[0].buf = buffer;
906 wsabufs[1].len = 4;
907 wsabufs[1].buf = buffer + 3;
908 memset(&params, 0, sizeof(params));
909 params.buffers = wsabufs;
910 params.count = 2;
911 params.msg_flags = AFD_MSG_NOT_OOB;
913 memset(&io, 0, sizeof(io));
914 memset(buffer, 0xcc, sizeof(buffer));
915 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
916 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
917 ok(ret == STATUS_PENDING, "got %#x\n", ret);
918 ok(!io.Status, "got status %#x\n", io.Status);
919 ok(!io.Information, "got information %#Ix\n", io.Information);
921 ret = send(server, "data", 5, 0);
922 ok(ret == 5, "got %d\n", ret);
924 ret = WaitForSingleObject(event, 200);
925 ok(!ret, "wait timed out\n");
926 ok(!io.Status, "got %#x\n", io.Status);
927 ok(io.Information == 5, "got %#Ix\n", io.Information);
928 ok(!strcmp(buffer, "da\xccta"), "got %s\n", debugstr_an(buffer, io.Information));
930 /* Test synchronous return. */
932 ret = send(server, "data", 5, 0);
933 ok(ret == 5, "got %d\n", ret);
935 /* wait for the data to be available */
936 check_poll_mask(client, event, AFD_POLL_READ, AFD_POLL_READ);
938 memset(&io, 0xcc, sizeof(io));
939 memset(buffer, 0xcc, sizeof(buffer));
940 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
941 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
942 ok(!ret, "got %#x\n", ret);
943 ok(!io.Status, "got %#x\n", io.Status);
944 ok(io.Information == 5, "got %#Ix\n", io.Information);
945 ok(!strcmp(buffer, "da\xccta"), "got %s\n", debugstr_an(buffer, io.Information));
947 /* Test nonblocking mode. */
949 set_blocking(client, FALSE);
951 memset(&io, 0, sizeof(io));
952 memset(buffer, 0xcc, sizeof(buffer));
953 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
954 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
955 ok(ret == STATUS_DEVICE_NOT_READY, "got %#x\n", ret);
956 todo_wine ok(!io.Status, "got status %#x\n", io.Status);
957 ok(!io.Information, "got information %#Ix\n", io.Information);
959 ret = send(server, "data", 5, 0);
960 ok(ret == 5, "got %d\n", ret);
962 /* wait for the data to be available */
963 check_poll_mask(client, event, AFD_POLL_READ, AFD_POLL_READ);
965 memset(&io, 0xcc, sizeof(io));
966 memset(buffer, 0xcc, sizeof(buffer));
967 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
968 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
969 ok(!ret, "got %#x\n", ret);
970 ok(!io.Status, "got %#x\n", io.Status);
971 ok(io.Information == 5, "got %#Ix\n", io.Information);
972 ok(!strcmp(buffer, "da\xccta"), "got %s\n", debugstr_an(buffer, io.Information));
974 params.recv_flags = AFD_RECV_FORCE_ASYNC;
976 memset(&io, 0, sizeof(io));
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 ok(ret == STATUS_PENDING, "got %#x\n", ret);
981 todo_wine ok(!io.Status, "got status %#x\n", io.Status);
982 todo_wine ok(!io.Information, "got information %#Ix\n", io.Information);
984 ret = send(server, "data", 5, 0);
985 ok(ret == 5, "got %d\n", ret);
987 ret = WaitForSingleObject(event, 200);
988 ok(!ret, "wait timed out\n");
989 ok(!io.Status, "got %#x\n", io.Status);
990 ok(io.Information == 5, "got %#Ix\n", io.Information);
991 ok(!strcmp(buffer, "da\xccta"), "got %s\n", debugstr_an(buffer, io.Information));
993 params.recv_flags = 0;
995 set_blocking(client, TRUE);
997 /* Test flags. */
999 ret = send(server, "a", 1, MSG_OOB);
1000 ok(ret == 1, "got %d\n", ret);
1002 ret = send(server, "data", 5, 0);
1003 ok(ret == 5, "got %d\n", ret);
1005 /* wait for the data to be available */
1006 check_poll_mask(client, event, AFD_POLL_READ, AFD_POLL_READ);
1008 memset(&io, 0xcc, sizeof(io));
1009 memset(buffer, 0xcc, sizeof(buffer));
1010 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1011 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1012 ok(!ret, "got %#x\n", ret);
1013 ok(!io.Status, "got %#x\n", io.Status);
1014 ok(io.Information == 5, "got %#Ix\n", io.Information);
1015 ok(!strcmp(buffer, "da\xccta"), "got %s\n", debugstr_an(buffer, io.Information));
1017 params.msg_flags = 0;
1019 io.Status = 0xdeadbeef;
1020 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1021 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1022 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
1023 todo_wine ok(io.Status == 0xdeadbeef, "got %#x\n", io.Status);
1025 params.msg_flags = AFD_MSG_OOB | AFD_MSG_NOT_OOB;
1027 io.Status = 0xdeadbeef;
1028 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1029 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1030 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
1031 todo_wine ok(io.Status == 0xdeadbeef, "got %#x\n", io.Status);
1033 params.msg_flags = AFD_MSG_OOB;
1035 memset(buffer, 0xcc, sizeof(buffer));
1036 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1037 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1038 todo_wine ok(!ret, "got %#x\n", ret);
1039 todo_wine ok(!io.Status, "got %#x\n", io.Status);
1040 todo_wine ok(io.Information == 1, "got %#Ix\n", io.Information);
1041 todo_wine ok(buffer[0] == 'a', "got %s\n", debugstr_an(buffer, io.Information));
1043 params.msg_flags = AFD_MSG_NOT_OOB | AFD_MSG_PEEK;
1045 ret = send(server, "data", 4, 0);
1046 ok(ret == 4, "got %d\n", ret);
1048 /* wait for the data to be available */
1049 check_poll_mask(client, event, AFD_POLL_READ, AFD_POLL_READ);
1051 memset(buffer, 0xcc, sizeof(buffer));
1052 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1053 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1054 ok(!ret, "got %#x\n", ret);
1055 ok(!io.Status, "got %#x\n", io.Status);
1056 ok(io.Information == 4, "got %#Ix\n", io.Information);
1057 ok(!memcmp(buffer, "da\xccta", 5), "got %s\n", debugstr_an(buffer, io.Information));
1059 memset(buffer, 0xcc, sizeof(buffer));
1060 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1061 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1062 ok(!ret, "got %#x\n", ret);
1063 ok(!io.Status, "got %#x\n", io.Status);
1064 ok(io.Information == 4, "got %#Ix\n", io.Information);
1065 ok(!memcmp(buffer, "da\xccta", 5), "got %s\n", debugstr_an(buffer, io.Information));
1067 params.msg_flags = AFD_MSG_NOT_OOB | AFD_MSG_WAITALL;
1069 memset(buffer, 0xcc, sizeof(buffer));
1070 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1071 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1072 todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
1074 if (ret == STATUS_PENDING)
1076 ret = send(server, "s", 2, 0);
1077 ok(ret == 2, "got %d\n", ret);
1079 ret = WaitForSingleObject(event, 200);
1080 ok(!ret, "wait timed out\n");
1081 ok(!io.Status, "got %#x\n", io.Status);
1082 ok(io.Information == 6, "got %#Ix\n", io.Information);
1083 ok(!strcmp(buffer, "da\xcctas"), "got %s\n", debugstr_an(buffer, io.Information));
1086 params.msg_flags = AFD_MSG_NOT_OOB;
1088 /* Test shutdown. */
1090 memset(buffer, 0xcc, sizeof(buffer));
1091 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1092 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1093 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1095 closesocket(server);
1097 ret = WaitForSingleObject(event, 200);
1098 ok(!ret, "wait timed out\n");
1099 ok(!io.Status, "got %#x\n", io.Status);
1100 ok(!io.Information, "got %#Ix\n", io.Information);
1102 ret = shutdown(client, SD_RECEIVE);
1103 ok(!ret, "got error %u\n", WSAGetLastError());
1105 memset(&io, 0, sizeof(io));
1106 memset(buffer, 0xcc, sizeof(buffer));
1107 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1108 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1109 todo_wine ok(ret == STATUS_PIPE_DISCONNECTED, "got %#x\n", ret);
1110 ok(!io.Status, "got status %#x\n", io.Status);
1111 ok(!io.Information, "got information %#Ix\n", io.Information);
1113 closesocket(client);
1114 closesocket(listener);
1116 /* Test UDP datagrams. */
1118 client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
1119 server = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
1121 memset(buffer, 0xcc, sizeof(buffer));
1122 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1123 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1124 todo_wine ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
1125 if (ret == STATUS_PENDING)
1126 CancelIo((HANDLE)client);
1128 ret = bind(client, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
1129 ok(!ret, "got error %u\n", WSAGetLastError());
1130 len = sizeof(addr);
1131 ret = getsockname(client, (struct sockaddr *)&addr, &len);
1132 ok(!ret, "got error %u\n", WSAGetLastError());
1134 memset(buffer, 0xcc, sizeof(buffer));
1135 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1136 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1137 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1139 ret = sendto(server, "data", 5, 0, (struct sockaddr *)&addr, sizeof(addr));
1140 ok(ret == 5, "got %d\n", ret);
1142 ret = WaitForSingleObject(event, 200);
1143 ok(!ret, "wait timed out\n");
1144 ok(!io.Status, "got %#x\n", io.Status);
1145 ok(io.Information == 5, "got %#Ix\n", io.Information);
1146 ok(!strcmp(buffer, "da\xccta"), "got %s\n", debugstr_an(buffer, io.Information));
1148 /* Test a short read of a UDP datagram. */
1150 memset(buffer, 0xcc, sizeof(buffer));
1151 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1152 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1153 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1155 ret = sendto(server, "moredata", 9, 0, (struct sockaddr *)&addr, sizeof(addr));
1156 ok(ret == 9, "got %d\n", ret);
1158 ret = WaitForSingleObject(event, 200);
1159 ok(!ret, "wait timed out\n");
1160 ok(io.Status == STATUS_BUFFER_OVERFLOW, "got %#x\n", io.Status);
1161 ok(io.Information == 6, "got %#Ix\n", io.Information);
1162 ok(!memcmp(buffer, "mo\xccreda\xcc", 7), "got %s\n", debugstr_an(buffer, io.Information));
1164 ret = sendto(server, "moredata", 9, 0, (struct sockaddr *)&addr, sizeof(addr));
1165 ok(ret == 9, "got %d\n", ret);
1167 /* wait for the data to be available */
1168 check_poll_mask(client, event, AFD_POLL_READ, AFD_POLL_READ);
1170 memset(&io, 0, sizeof(io));
1171 memset(buffer, 0xcc, sizeof(buffer));
1172 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1173 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1174 ok(ret == STATUS_BUFFER_OVERFLOW, "got %#x\n", ret);
1175 ok(io.Status == STATUS_BUFFER_OVERFLOW, "got %#x\n", io.Status);
1176 ok(io.Information == 6, "got %#Ix\n", io.Information);
1177 ok(!memcmp(buffer, "mo\xccreda\xcc", 7), "got %s\n", debugstr_an(buffer, io.Information));
1179 /* Test closing a socket during an async. */
1181 memset(buffer, 0xcc, sizeof(buffer));
1182 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1183 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1184 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1186 closesocket(client);
1188 ret = WaitForSingleObject(event, 200);
1189 ok(!ret, "wait timed out\n");
1190 todo_wine ok(io.Status == STATUS_CANCELLED, "got %#x\n", io.Status);
1191 ok(!io.Information, "got %#Ix\n", io.Information);
1193 closesocket(server);
1194 CloseHandle(event);
1197 static void test_event_select(void)
1199 struct afd_event_select_params params;
1200 WSANETWORKEVENTS events;
1201 SOCKET client, server;
1202 IO_STATUS_BLOCK io;
1203 HANDLE event;
1204 int ret;
1206 event = CreateEventW(NULL, TRUE, FALSE, NULL);
1208 tcp_socketpair(&client, &server);
1210 memset(&io, 0xcc, sizeof(io));
1211 ret = NtDeviceIoControlFile((HANDLE)client, NULL, NULL, NULL, &io,
1212 IOCTL_AFD_EVENT_SELECT, NULL, 0, NULL, 0);
1213 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
1214 ok(io.Status == STATUS_INVALID_PARAMETER, "got status %#x\n", io.Status);
1215 ok(!io.Information, "got information %#Ix\n", io.Information);
1217 params.event = 0;
1218 params.mask = ~0;
1219 memset(&io, 0xcc, sizeof(io));
1220 ret = NtDeviceIoControlFile((HANDLE)client, NULL, NULL, NULL, &io,
1221 IOCTL_AFD_EVENT_SELECT, &params, sizeof(params), NULL, 0);
1222 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
1223 ok(io.Status == STATUS_INVALID_PARAMETER, "got status %#x\n", io.Status);
1224 ok(!io.Information, "got information %#Ix\n", io.Information);
1226 params.event = event;
1227 params.mask = ~0;
1228 memset(&io, 0xcc, sizeof(io));
1229 ret = NtDeviceIoControlFile((HANDLE)client, NULL, NULL, NULL, &io,
1230 IOCTL_AFD_EVENT_SELECT, &params, sizeof(params), NULL, 0);
1231 ok(!ret, "got %#x\n", ret);
1232 ok(!io.Status, "got status %#x\n", io.Status);
1233 ok(!io.Information, "got information %#Ix\n", io.Information);
1235 ret = WSAEnumNetworkEvents(client, event, &events);
1236 ok(!ret, "got error %u\n", WSAGetLastError());
1237 ok(events.lNetworkEvents == (FD_CONNECT | FD_WRITE), "got events %#x\n", events.lNetworkEvents);
1239 closesocket(client);
1240 closesocket(server);
1242 tcp_socketpair(&client, &server);
1244 params.event = event;
1245 params.mask = AFD_POLL_CONNECT;
1246 memset(&io, 0xcc, sizeof(io));
1247 ret = NtDeviceIoControlFile((HANDLE)client, NULL, NULL, NULL, &io,
1248 IOCTL_AFD_EVENT_SELECT, &params, sizeof(params), NULL, 0);
1249 ok(!ret, "got %#x\n", ret);
1250 ok(!io.Status, "got status %#x\n", io.Status);
1251 ok(!io.Information, "got information %#Ix\n", io.Information);
1253 ret = WSAEnumNetworkEvents(client, event, &events);
1254 ok(!ret, "got error %u\n", WSAGetLastError());
1255 ok(events.lNetworkEvents == FD_CONNECT, "got events %#x\n", events.lNetworkEvents);
1257 closesocket(client);
1258 closesocket(server);
1260 tcp_socketpair(&client, &server);
1262 params.event = event;
1263 params.mask = ~0;
1264 memset(&io, 0xcc, sizeof(io));
1265 ret = NtDeviceIoControlFile((HANDLE)client, NULL, NULL, NULL, &io,
1266 IOCTL_AFD_EVENT_SELECT, &params, sizeof(params), NULL, 0);
1267 ok(!ret, "got %#x\n", ret);
1268 ok(!io.Status, "got status %#x\n", io.Status);
1269 ok(!io.Information, "got information %#Ix\n", io.Information);
1271 params.event = 0;
1272 params.mask = 0;
1273 memset(&io, 0xcc, sizeof(io));
1274 ret = NtDeviceIoControlFile((HANDLE)client, NULL, NULL, NULL, &io,
1275 IOCTL_AFD_EVENT_SELECT, &params, sizeof(params), NULL, 0);
1276 ok(!ret, "got %#x\n", ret);
1277 ok(!io.Status, "got status %#x\n", io.Status);
1278 ok(!io.Information, "got information %#Ix\n", io.Information);
1280 ret = WSAEnumNetworkEvents(client, event, &events);
1281 ok(!ret, "got error %u\n", WSAGetLastError());
1282 ok(!events.lNetworkEvents, "got events %#x\n", events.lNetworkEvents);
1284 closesocket(client);
1285 closesocket(server);
1287 CloseHandle(event);
1290 static void test_get_events(void)
1292 const struct sockaddr_in invalid_addr =
1294 .sin_family = AF_INET,
1295 .sin_addr.s_addr = htonl(INADDR_LOOPBACK),
1296 .sin_port = 255,
1298 struct afd_get_events_params params;
1299 WSANETWORKEVENTS events;
1300 SOCKET client, server;
1301 IO_STATUS_BLOCK io;
1302 unsigned int i;
1303 HANDLE event;
1304 int ret;
1306 event = CreateEventW(NULL, TRUE, FALSE, NULL);
1308 tcp_socketpair(&client, &server);
1310 ret = WSAEventSelect(client, event, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
1311 ok(!ret, "got error %u\n", GetLastError());
1313 memset(&params, 0xcc, sizeof(params));
1314 memset(&io, 0xcc, sizeof(io));
1315 ret = NtDeviceIoControlFile((HANDLE)client, NULL, NULL, NULL, &io,
1316 IOCTL_AFD_GET_EVENTS, NULL, 0, NULL, 0);
1317 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
1319 memset(&params, 0xcc, sizeof(params));
1320 memset(&io, 0xcc, sizeof(io));
1321 ret = NtDeviceIoControlFile((HANDLE)client, NULL, NULL, NULL, &io,
1322 IOCTL_AFD_GET_EVENTS, NULL, 0, &params, sizeof(params));
1323 ok(!ret, "got %#x\n", ret);
1324 ok(params.flags == (AFD_POLL_WRITE | AFD_POLL_CONNECT), "got flags %#x\n", params.flags);
1325 for (i = 0; i < ARRAY_SIZE(params.status); ++i)
1326 ok(!params.status[i], "got status[%u] %#x\n", i, params.status[i]);
1328 ret = WSAEnumNetworkEvents(client, event, &events);
1329 ok(!ret, "got error %u\n", GetLastError());
1330 ok(!events.lNetworkEvents, "got events %#x\n", events.lNetworkEvents);
1332 closesocket(client);
1333 closesocket(server);
1335 tcp_socketpair(&client, &server);
1337 ret = WSAEventSelect(client, event, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
1338 ok(!ret, "got error %u\n", GetLastError());
1340 ret = WSAEnumNetworkEvents(client, event, &events);
1341 ok(!ret, "got error %u\n", GetLastError());
1342 ok(events.lNetworkEvents == (FD_WRITE | FD_CONNECT), "got events %#x\n", events.lNetworkEvents);
1344 memset(&params, 0xcc, sizeof(params));
1345 memset(&io, 0xcc, sizeof(io));
1346 ret = NtDeviceIoControlFile((HANDLE)client, NULL, NULL, NULL, &io,
1347 IOCTL_AFD_GET_EVENTS, NULL, 0, &params, sizeof(params));
1348 ok(!ret, "got %#x\n", ret);
1349 ok(!params.flags, "got flags %#x\n", params.flags);
1350 for (i = 0; i < ARRAY_SIZE(params.status); ++i)
1351 ok(!params.status[i], "got status[%u] %#x\n", i, params.status[i]);
1353 closesocket(client);
1354 closesocket(server);
1356 /* Test a failed connection. The following call can take over 2 seconds to
1357 * complete, so make the test interactive-only. */
1359 if (winetest_interactive)
1361 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1363 ResetEvent(event);
1364 ret = WSAEventSelect(client, event, FD_CONNECT);
1365 ok(!ret, "got error %u\n", GetLastError());
1367 ret = connect(client, (struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
1368 ok(ret == -1, "expected failure\n");
1369 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
1371 ret = WaitForSingleObject(event, 10000);
1372 ok(!ret, "got %#x\n", ret);
1374 memset(&params, 0xcc, sizeof(params));
1375 memset(&io, 0xcc, sizeof(io));
1376 ret = NtDeviceIoControlFile((HANDLE)client, NULL, NULL, NULL, &io,
1377 IOCTL_AFD_GET_EVENTS, NULL, 0, &params, sizeof(params));
1378 ok(!ret, "got %#x\n", ret);
1379 ok(params.flags == AFD_POLL_CONNECT_ERR, "got flags %#x\n", params.flags);
1380 for (i = 0; i < ARRAY_SIZE(params.status); ++i)
1382 if (i == AFD_POLL_BIT_CONNECT_ERR)
1383 ok(params.status[i] == STATUS_CONNECTION_REFUSED, "got status[%u] %#x\n", i, params.status[i]);
1384 else
1385 ok(!params.status[i], "got status[%u] %#x\n", i, params.status[i]);
1388 ResetEvent(event);
1389 ret = WSAEventSelect(client, event, FD_CONNECT);
1390 ok(!ret, "got error %u\n", GetLastError());
1392 ret = WaitForSingleObject(event, 0);
1393 ok(ret == WAIT_TIMEOUT, "got %#x\n", ret);
1395 memset(&params, 0xcc, sizeof(params));
1396 memset(&io, 0xcc, sizeof(io));
1397 ret = NtDeviceIoControlFile((HANDLE)client, NULL, NULL, NULL, &io,
1398 IOCTL_AFD_GET_EVENTS, NULL, 0, &params, sizeof(params));
1399 ok(!ret, "got %#x\n", ret);
1400 ok(!params.flags, "got flags %#x\n", params.flags);
1401 for (i = 0; i < ARRAY_SIZE(params.status); ++i)
1403 if (i == AFD_POLL_BIT_CONNECT_ERR)
1404 ok(params.status[i] == STATUS_CONNECTION_REFUSED, "got status[%u] %#x\n", i, params.status[i]);
1405 else
1406 ok(!params.status[i], "got status[%u] %#x\n", i, params.status[i]);
1409 closesocket(client);
1412 CloseHandle(event);
1415 static void test_bind(void)
1417 const struct sockaddr_in invalid_addr = {.sin_family = AF_INET, .sin_addr.s_addr = inet_addr("192.0.2.0")};
1418 const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
1419 struct afd_bind_params params = {0};
1420 struct sockaddr_in addr, addr2;
1421 struct hostent *host;
1422 IO_STATUS_BLOCK io;
1423 unsigned int i;
1424 HANDLE event;
1425 SOCKET s, s2;
1426 int ret;
1428 event = CreateEventW(NULL, TRUE, FALSE, NULL);
1429 memset(&addr, 0xcc, sizeof(addr));
1431 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1433 params.addr.sa_family = 0xdead;
1434 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
1435 &params, sizeof(params), &addr, sizeof(addr));
1436 ok(ret == STATUS_INVALID_ADDRESS, "got %#x\n", ret);
1438 memcpy(&params.addr, &bind_addr, sizeof(bind_addr));
1439 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
1440 &params, sizeof(params) - 1, &addr, sizeof(addr));
1441 ok(ret == STATUS_INVALID_ADDRESS, "got %#x\n", ret);
1443 memcpy(&params.addr, &bind_addr, sizeof(bind_addr));
1444 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
1445 &params, offsetof(struct afd_bind_params, addr.sa_data), &addr, sizeof(addr));
1446 ok(ret == STATUS_INVALID_ADDRESS, "got %#x\n", ret);
1448 memcpy(&params.addr, &bind_addr, sizeof(bind_addr));
1449 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
1450 &params, offsetof(struct afd_bind_params, addr.sa_data) - 1, &addr, sizeof(addr));
1451 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
1453 memcpy(&params.addr, &invalid_addr, sizeof(invalid_addr));
1454 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
1455 &params, sizeof(params), &addr, sizeof(addr));
1456 todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
1457 ret = WaitForSingleObject(event, 0);
1458 ok(!ret, "got %#x\n", ret);
1459 ok(io.Status == STATUS_INVALID_ADDRESS_COMPONENT, "got %#x\n", io.Status);
1461 memcpy(&params.addr, &bind_addr, sizeof(bind_addr));
1462 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
1463 &params, sizeof(params), &addr, sizeof(addr) - 1);
1464 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
1466 memcpy(&params.addr, &bind_addr, sizeof(bind_addr));
1467 memset(&io, 0xcc, sizeof(io));
1468 memset(&addr, 0xcc, sizeof(addr));
1469 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
1470 &params, sizeof(params), &addr, sizeof(addr));
1471 todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
1472 ret = WaitForSingleObject(event, 0);
1473 ok(!ret, "got %#x\n", ret);
1474 ok(!io.Status, "got %#x\n", io.Status);
1475 ok(io.Information == sizeof(addr), "got %#Ix\n", io.Information);
1476 ok(addr.sin_family == AF_INET, "got family %u\n", addr.sin_family);
1477 ok(addr.sin_addr.s_addr == htonl(INADDR_LOOPBACK), "got address %#08x\n", addr.sin_addr.s_addr);
1478 ok(addr.sin_port, "expected nonzero port\n");
1480 /* getsockname() returns EINVAL here. Possibly the socket name is cached (in shared memory?) */
1481 memset(&addr2, 0xcc, sizeof(addr2));
1482 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io,
1483 IOCTL_AFD_GETSOCKNAME, NULL, 0, &addr2, sizeof(addr2));
1484 ok(!ret, "got %#x\n", ret);
1485 ok(!memcmp(&addr, &addr2, sizeof(addr)), "addresses didn't match\n");
1487 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
1488 &params, sizeof(params), &addr, sizeof(addr));
1489 ok(ret == STATUS_ADDRESS_ALREADY_ASSOCIATED, "got %#x\n", ret);
1491 s2 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1493 memcpy(&params.addr, &addr2, sizeof(addr2));
1494 memset(&io, 0xcc, sizeof(io));
1495 memset(&addr, 0xcc, sizeof(addr));
1496 ret = NtDeviceIoControlFile((HANDLE)s2, event, NULL, NULL, &io, IOCTL_AFD_BIND,
1497 &params, sizeof(params), &addr, sizeof(addr));
1498 todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
1499 ret = WaitForSingleObject(event, 0);
1500 ok(!ret, "got %#x\n", ret);
1501 ok(io.Status == STATUS_SHARING_VIOLATION, "got %#x\n", io.Status);
1502 ok(!io.Information, "got %#Ix\n", io.Information);
1504 closesocket(s2);
1505 closesocket(s);
1507 /* test UDP */
1509 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
1511 memcpy(&params.addr, &bind_addr, sizeof(bind_addr));
1512 memset(&io, 0xcc, sizeof(io));
1513 memset(&addr, 0xcc, sizeof(addr));
1514 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
1515 &params, sizeof(params), &addr, sizeof(addr));
1516 todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
1517 ret = WaitForSingleObject(event, 0);
1518 ok(!ret, "got %#x\n", ret);
1519 ok(!io.Status, "got %#x\n", io.Status);
1520 ok(io.Information == sizeof(addr), "got %#Ix\n", io.Information);
1521 ok(addr.sin_family == AF_INET, "got family %u\n", addr.sin_family);
1522 ok(addr.sin_addr.s_addr == htonl(INADDR_LOOPBACK), "got address %#08x\n", addr.sin_addr.s_addr);
1523 ok(addr.sin_port, "expected nonzero port\n");
1525 memset(&addr2, 0xcc, sizeof(addr2));
1526 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io,
1527 IOCTL_AFD_GETSOCKNAME, NULL, 0, &addr2, sizeof(addr2));
1528 ok(!ret, "got %#x\n", ret);
1529 ok(!memcmp(&addr, &addr2, sizeof(addr)), "addresses didn't match\n");
1531 closesocket(s);
1533 host = gethostbyname("");
1534 if (host && host->h_length == 4)
1536 for (i = 0; host->h_addr_list[i]; ++i)
1538 ULONG in_addr = *(ULONG *)host->h_addr_list[i];
1540 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
1542 ((struct sockaddr_in *)&params.addr)->sin_addr.s_addr = in_addr;
1543 memset(&io, 0xcc, sizeof(io));
1544 memset(&addr, 0xcc, sizeof(addr));
1545 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
1546 &params, sizeof(params), &addr, sizeof(addr));
1547 todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
1548 ret = WaitForSingleObject(event, 0);
1549 ok(!ret, "got %#x\n", ret);
1550 ok(!io.Status, "got %#x\n", io.Status);
1551 ok(io.Information == sizeof(addr), "got %#Ix\n", io.Information);
1552 ok(addr.sin_family == AF_INET, "got family %u\n", addr.sin_family);
1553 ok(addr.sin_addr.s_addr == in_addr, "expected address %#08x, got %#08x\n", in_addr, addr.sin_addr.s_addr);
1554 ok(addr.sin_port, "expected nonzero port\n");
1556 memset(&addr2, 0xcc, sizeof(addr2));
1557 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io,
1558 IOCTL_AFD_GETSOCKNAME, NULL, 0, &addr2, sizeof(addr2));
1559 ok(!ret, "got %#x\n", ret);
1560 ok(!memcmp(&addr, &addr2, sizeof(addr)), "addresses didn't match\n");
1562 closesocket(s);
1566 CloseHandle(event);
1569 static void test_getsockname(void)
1571 const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
1572 struct sockaddr addr, addr2;
1573 SOCKET server, client;
1574 IO_STATUS_BLOCK io;
1575 HANDLE event;
1576 int ret, len;
1578 event = CreateEventW(NULL, TRUE, FALSE, NULL);
1580 tcp_socketpair(&client, &server);
1582 memset(&addr, 0xcc, sizeof(addr));
1583 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1584 IOCTL_AFD_GETSOCKNAME, NULL, 0, &addr, sizeof(addr) - 1);
1585 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#x\n", ret);
1587 memset(&io, 0xcc, sizeof(io));
1588 memset(&addr, 0xcc, sizeof(addr));
1589 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1590 IOCTL_AFD_GETSOCKNAME, NULL, 0, &addr, sizeof(addr));
1591 ok(!ret, "got %#x\n", ret);
1592 ok(!io.Status, "got %#x\n", io.Status);
1593 ok(io.Information == sizeof(addr), "got %#Ix\n", io.Information);
1594 len = sizeof(addr2);
1595 ret = getsockname(client, (struct sockaddr *)&addr2, &len);
1596 ok(!ret, "got error %u\n", WSAGetLastError());
1597 ok(!memcmp(&addr, &addr2, sizeof(struct sockaddr)), "addresses didn't match\n");
1599 memset(&io, 0xcc, sizeof(io));
1600 memset(&addr, 0xcc, sizeof(addr));
1601 ret = NtDeviceIoControlFile((HANDLE)server, event, NULL, NULL, &io,
1602 IOCTL_AFD_GETSOCKNAME, NULL, 0, &addr, sizeof(addr));
1603 ok(!ret, "got %#x\n", ret);
1604 ok(!io.Status, "got %#x\n", io.Status);
1605 ok(io.Information == sizeof(addr), "got %#Ix\n", io.Information);
1606 len = sizeof(addr2);
1607 ret = getsockname(server, (struct sockaddr *)&addr2, &len);
1608 ok(!ret, "got error %u\n", WSAGetLastError());
1609 ok(!memcmp(&addr, &addr2, sizeof(struct sockaddr)), "addresses didn't match\n");
1611 closesocket(server);
1612 closesocket(client);
1614 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1616 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1617 IOCTL_AFD_GETSOCKNAME, NULL, 0, &addr, sizeof(addr));
1618 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
1620 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1621 IOCTL_AFD_GETSOCKNAME, NULL, 0, &addr, sizeof(addr) - 1);
1622 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
1624 ret = bind(client, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
1625 ok(!ret, "got error %u\n", WSAGetLastError());
1627 memset(&io, 0xcc, sizeof(io));
1628 memset(&addr, 0xcc, sizeof(addr));
1629 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1630 IOCTL_AFD_GETSOCKNAME, NULL, 0, &addr, sizeof(addr));
1631 ok(!ret, "got %#x\n", ret);
1632 ok(!io.Status, "got %#x\n", io.Status);
1633 ok(io.Information == sizeof(addr), "got %#Ix\n", io.Information);
1634 len = sizeof(addr2);
1635 ret = getsockname(client, (struct sockaddr *)&addr2, &len);
1636 ok(!ret, "got error %u\n", WSAGetLastError());
1637 ok(!memcmp(&addr, &addr2, sizeof(struct sockaddr)), "addresses didn't match\n");
1639 closesocket(client);
1641 CloseHandle(event);
1644 START_TEST(afd)
1646 WSADATA data;
1648 WSAStartup(MAKEWORD(2, 2), &data);
1650 test_open_device();
1651 test_poll();
1652 test_poll_completion_port();
1653 test_recv();
1654 test_event_select();
1655 test_get_events();
1656 test_bind();
1657 test_getsockname();
1659 WSACleanup();