wineps: Handle EMR_INVERTRGN record in spool files.
[wine.git] / dlls / ws2_32 / tests / afd.c
blobd0191ba8dbf02f529cee8bde78945c2cfb3584a7
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 #define TIMEOUT_INFINITE _I64_MAX
36 static void tcp_socketpair_flags(SOCKET *src, SOCKET *dst, DWORD flags)
38 SOCKET server = INVALID_SOCKET;
39 struct sockaddr_in addr;
40 int len, ret;
42 *src = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, flags);
43 ok(*src != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
45 server = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, flags);
46 ok(server != INVALID_SOCKET, "failed to create socket, error %u\n", WSAGetLastError());
48 memset(&addr, 0, sizeof(addr));
49 addr.sin_family = AF_INET;
50 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
51 ret = bind(server, (struct sockaddr *)&addr, sizeof(addr));
52 ok(!ret, "failed to bind socket, error %u\n", WSAGetLastError());
54 len = sizeof(addr);
55 ret = getsockname(server, (struct sockaddr *)&addr, &len);
56 ok(!ret, "failed to get address, error %u\n", WSAGetLastError());
58 ret = listen(server, 1);
59 ok(!ret, "failed to listen, error %u\n", WSAGetLastError());
61 ret = connect(*src, (struct sockaddr *)&addr, sizeof(addr));
62 ok(!ret, "failed to connect, error %u\n", WSAGetLastError());
64 len = sizeof(addr);
65 *dst = accept(server, (struct sockaddr *)&addr, &len);
66 ok(*dst != INVALID_SOCKET, "failed to accept socket, error %u\n", WSAGetLastError());
68 closesocket(server);
71 static void tcp_socketpair(SOCKET *src, SOCKET *dst)
73 tcp_socketpair_flags(src, dst, WSA_FLAG_OVERLAPPED);
76 static void set_blocking(SOCKET s, ULONG blocking)
78 int ret;
79 blocking = !blocking;
80 ret = ioctlsocket(s, FIONBIO, &blocking);
81 ok(!ret, "got error %u\n", WSAGetLastError());
84 /* Set the linger timeout to zero and close the socket. This will trigger an
85 * RST on the connection on Windows as well as on Unix systems. */
86 static void close_with_rst(SOCKET s)
88 static const struct linger linger = {.l_onoff = 1};
89 int ret;
91 SetLastError(0xdeadbeef);
92 ret = setsockopt(s, SOL_SOCKET, SO_LINGER, (const char *)&linger, sizeof(linger));
93 ok(!ret, "got %d\n", ret);
94 ok(!GetLastError(), "got error %lu\n", GetLastError());
96 closesocket(s);
99 static void test_open_device(void)
101 OBJECT_BASIC_INFORMATION info;
102 OBJECT_ATTRIBUTES attr;
103 UNICODE_STRING string;
104 IO_STATUS_BLOCK io;
105 HANDLE handle;
106 SOCKET s;
107 int ret;
109 RtlInitUnicodeString(&string, L"\\Device\\Afd");
110 InitializeObjectAttributes(&attr, &string, 0, NULL, NULL);
111 ret = NtOpenFile(&handle, SYNCHRONIZE, &attr, &io, 0, 0);
112 ok(!ret, "got %#x\n", ret);
113 CloseHandle(handle);
115 RtlInitUnicodeString(&string, L"\\Device\\Afd\\");
116 InitializeObjectAttributes(&attr, &string, 0, NULL, NULL);
117 ret = NtOpenFile(&handle, SYNCHRONIZE, &attr, &io, 0, 0);
118 ok(!ret, "got %#x\n", ret);
119 CloseHandle(handle);
121 RtlInitUnicodeString(&string, L"\\Device\\Afd\\foobar");
122 InitializeObjectAttributes(&attr, &string, 0, NULL, NULL);
123 ret = NtOpenFile(&handle, SYNCHRONIZE, &attr, &io, 0, 0);
124 ok(!ret, "got %#x\n", ret);
125 CloseHandle(handle);
127 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
128 ret = NtQueryObject((HANDLE)s, ObjectBasicInformation, &info, sizeof(info), NULL);
129 ok(!ret, "got %#x\n", ret);
130 todo_wine ok(info.Attributes == OBJ_INHERIT, "got attributes %#lx\n", info.Attributes);
131 todo_wine ok(info.GrantedAccess == (FILE_GENERIC_READ | FILE_GENERIC_WRITE | WRITE_DAC), "got access %#lx\n", info.GrantedAccess);
133 closesocket(s);
136 #define check_poll(a, b, c) check_poll_(__LINE__, a, b, ~0, c, FALSE)
137 #define check_poll_mask(a, b, c, d) check_poll_(__LINE__, a, b, c, d, FALSE)
138 #define check_poll_todo(a, b, c) check_poll_(__LINE__, a, b, ~0, c, TRUE)
139 static void check_poll_(int line, SOCKET s, HANDLE event, int mask, int expect, BOOL todo)
141 struct afd_poll_params in_params = {0}, out_params = {0};
142 IO_STATUS_BLOCK io;
143 NTSTATUS ret;
145 in_params.timeout = -1000 * 10000;
146 in_params.count = 1;
147 in_params.sockets[0].socket = s;
148 in_params.sockets[0].flags = mask;
149 in_params.sockets[0].status = 0xdeadbeef;
151 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io,
152 IOCTL_AFD_POLL, &in_params, sizeof(in_params), &out_params, sizeof(out_params));
153 ok_(__FILE__, line)(!ret || ret == STATUS_PENDING, "got %#lx\n", ret);
154 if (ret == STATUS_PENDING)
156 ret = WaitForSingleObject(event, 1000);
157 ok_(__FILE__, line)(!ret, "wait timed out\n");
159 ok_(__FILE__, line)(!io.Status, "got %#lx\n", io.Status);
160 ok_(__FILE__, line)(io.Information == sizeof(out_params), "got %#Ix\n", io.Information);
161 ok_(__FILE__, line)(out_params.timeout == in_params.timeout, "got timeout %I64d\n", out_params.timeout);
162 ok_(__FILE__, line)(out_params.count == 1, "got count %u\n", out_params.count);
163 ok_(__FILE__, line)(out_params.sockets[0].socket == s, "got socket %#Ix\n", out_params.sockets[0].socket);
164 todo_wine_if (todo) ok_(__FILE__, line)(out_params.sockets[0].flags == expect, "got flags %#x\n", out_params.sockets[0].flags);
165 ok_(__FILE__, line)(!out_params.sockets[0].status, "got status %#x\n", out_params.sockets[0].status);
168 static void test_poll(void)
170 const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
171 char in_buffer[offsetof(struct afd_poll_params, sockets[3])];
172 char out_buffer[offsetof(struct afd_poll_params, sockets[3])];
173 struct afd_poll_params *in_params = (struct afd_poll_params *)in_buffer;
174 struct afd_poll_params *out_params = (struct afd_poll_params *)out_buffer;
175 int large_buffer_size = 1024 * 1024;
176 GUID acceptex_guid = WSAID_ACCEPTEX;
177 SOCKET client, server, listener;
178 OVERLAPPED overlapped = {0};
179 HANDLE event, afd_handle;
180 LPFN_ACCEPTEX pAcceptEx;
181 struct sockaddr_in addr;
182 OBJECT_ATTRIBUTES attr;
183 UNICODE_STRING string;
184 DWORD size, flags = 0;
185 char *large_buffer;
186 IO_STATUS_BLOCK io;
187 LARGE_INTEGER now;
188 ULONG params_size;
189 WSABUF wsabuf;
190 int ret, len;
192 large_buffer = malloc(large_buffer_size);
193 memset(in_buffer, 0, sizeof(in_buffer));
194 memset(out_buffer, 0, sizeof(out_buffer));
195 event = CreateEventW(NULL, TRUE, FALSE, NULL);
196 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
198 RtlInitUnicodeString(&string, L"\\Device\\Afd\\deadbeef");
199 InitializeObjectAttributes(&attr, &string, 0, NULL, NULL);
200 ret = NtOpenFile(&afd_handle, SYNCHRONIZE, &attr, &io, 0, 0);
201 ok(!ret, "got %#x\n", ret);
203 listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
204 ret = bind(listener, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
205 ok(!ret, "got error %u\n", WSAGetLastError());
206 ret = listen(listener, 1);
207 ok(!ret, "got error %u\n", WSAGetLastError());
208 len = sizeof(addr);
209 ret = getsockname(listener, (struct sockaddr *)&addr, &len);
210 ok(!ret, "got error %u\n", WSAGetLastError());
212 ret = WSAIoctl(listener, SIO_GET_EXTENSION_FUNCTION_POINTER, &acceptex_guid, sizeof(acceptex_guid),
213 &pAcceptEx, sizeof(pAcceptEx), &size, NULL, NULL);
214 ok(!ret, "failed to get AcceptEx, error %u\n", WSAGetLastError());
216 params_size = offsetof(struct afd_poll_params, sockets[1]);
217 in_params->count = 1;
219 /* out_size must be at least as large as in_size. */
221 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io,
222 IOCTL_AFD_POLL, in_params, params_size, NULL, 0);
223 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
225 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io,
226 IOCTL_AFD_POLL, NULL, 0, out_params, params_size);
227 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
229 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io,
230 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size + 1);
231 ok(ret == STATUS_INVALID_HANDLE, "got %#x\n", ret);
233 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io,
234 IOCTL_AFD_POLL, in_params, params_size + 1, out_params, params_size);
235 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
237 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io,
238 IOCTL_AFD_POLL, in_params, params_size - 1, out_params, params_size - 1);
239 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
241 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io,
242 IOCTL_AFD_POLL, in_params, params_size + 1, out_params, params_size + 1);
243 ok(ret == STATUS_INVALID_HANDLE, "got %#x\n", ret);
245 in_params->count = 0;
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_INVALID_PARAMETER, "got %#x\n", ret);
250 /* Basic semantics of the ioctl. */
252 in_params->timeout = 0;
253 in_params->count = 1;
254 in_params->exclusive = FALSE;
255 in_params->sockets[0].socket = listener;
256 in_params->sockets[0].flags = ~0;
257 in_params->sockets[0].status = 0xdeadbeef;
259 memset(out_params, 0, params_size);
260 ret = NtDeviceIoControlFile(afd_handle, event, NULL, NULL, &io,
261 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
262 ok(!ret, "got %#x\n", ret);
263 ok(!io.Status, "got %#lx\n", io.Status);
264 ok(io.Information == offsetof(struct afd_poll_params, sockets[0]), "got %#Ix\n", io.Information);
265 ok(!out_params->timeout, "got timeout %#I64x\n", out_params->timeout);
266 ok(!out_params->count, "got count %u\n", out_params->count);
267 ok(!out_params->sockets[0].socket, "got socket %#Ix\n", out_params->sockets[0].socket);
268 ok(!out_params->sockets[0].flags, "got flags %#x\n", out_params->sockets[0].flags);
269 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
271 NtQuerySystemTime(&now);
272 in_params->timeout = now.QuadPart;
274 ret = NtDeviceIoControlFile(afd_handle, event, NULL, NULL, &io,
275 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
276 ok(ret == STATUS_PENDING, "got %#x\n", ret);
277 ret = WaitForSingleObject(event, 100);
278 ok(!ret, "got %#x\n", ret);
279 ok(io.Status == STATUS_TIMEOUT, "got %#lx\n", io.Status);
280 ok(io.Information == offsetof(struct afd_poll_params, sockets[0]), "got %#Ix\n", io.Information);
281 ok(out_params->timeout == now.QuadPart, "got timeout %#I64x\n", out_params->timeout);
282 ok(!out_params->count, "got count %u\n", out_params->count);
284 in_params->timeout = -1000 * 10000;
286 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io,
287 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
288 ok(ret == STATUS_PENDING, "got %#x\n", ret);
290 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
291 set_blocking(client, FALSE);
292 ret = connect(client, (struct sockaddr *)&addr, sizeof(addr));
293 ok(!ret || WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
295 ret = WaitForSingleObject(event, 100);
296 ok(!ret, "got %#x\n", ret);
297 ok(!io.Status, "got %#lx\n", io.Status);
298 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
299 ok(out_params->timeout == -1000 * 10000, "got timeout %#I64x\n", out_params->timeout);
300 ok(out_params->count == 1, "got count %u\n", out_params->count);
301 ok(out_params->sockets[0].socket == listener, "got socket %#Ix\n", out_params->sockets[0].socket);
302 ok(out_params->sockets[0].flags == AFD_POLL_ACCEPT, "got flags %#x\n", out_params->sockets[0].flags);
303 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
305 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io,
306 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
307 ok(!ret, "got %#x\n", ret);
308 ok(!io.Status, "got %#lx\n", io.Status);
309 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
310 ok(out_params->timeout == -1000 * 10000, "got timeout %#I64x\n", out_params->timeout);
311 ok(out_params->count == 1, "got count %u\n", out_params->count);
312 ok(out_params->sockets[0].socket == listener, "got socket %#Ix\n", out_params->sockets[0].socket);
313 ok(out_params->sockets[0].flags == AFD_POLL_ACCEPT, "got flags %#x\n", out_params->sockets[0].flags);
314 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
316 in_params->timeout = now.QuadPart;
317 in_params->sockets[0].flags = (~0) & ~AFD_POLL_ACCEPT;
319 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io,
320 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
321 ok(ret == STATUS_PENDING, "got %#x\n", ret);
322 ret = WaitForSingleObject(event, 100);
323 ok(!ret, "got %#x\n", ret);
324 ok(io.Status == STATUS_TIMEOUT, "got %#lx\n", io.Status);
325 ok(io.Information == offsetof(struct afd_poll_params, sockets[0]), "got %#Ix\n", io.Information);
326 ok(!out_params->count, "got count %u\n", out_params->count);
328 server = accept(listener, NULL, NULL);
329 ok(server != -1, "got error %u\n", WSAGetLastError());
330 set_blocking(server, FALSE);
332 /* Test flags exposed by connected sockets. */
334 check_poll(client, event, AFD_POLL_WRITE | AFD_POLL_CONNECT);
335 check_poll(server, event, AFD_POLL_WRITE | AFD_POLL_CONNECT);
337 /* It is valid to poll on a socket other than the one passed to
338 * NtDeviceIoControlFile(). */
340 in_params->count = 1;
341 in_params->sockets[0].socket = server;
342 in_params->sockets[0].flags = ~0;
344 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io,
345 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
346 ok(!ret, "got %#x\n", ret);
347 ok(!io.Status, "got %#lx\n", io.Status);
348 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
349 ok(out_params->count == 1, "got count %u\n", out_params->count);
350 ok(out_params->sockets[0].socket == server, "got socket %#Ix\n", out_params->sockets[0].socket);
351 ok(out_params->sockets[0].flags == (AFD_POLL_WRITE | AFD_POLL_CONNECT),
352 "got flags %#x\n", out_params->sockets[0].flags);
353 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
355 /* Test sending data. */
357 ret = send(server, "data", 5, 0);
358 ok(ret == 5, "got %d\n", ret);
360 check_poll_mask(client, event, AFD_POLL_READ, AFD_POLL_READ);
361 check_poll(client, event, AFD_POLL_WRITE | AFD_POLL_CONNECT | AFD_POLL_READ);
362 check_poll(server, event, AFD_POLL_WRITE | AFD_POLL_CONNECT);
364 while (send(server, large_buffer, large_buffer_size, 0) == large_buffer_size);
366 check_poll(client, event, AFD_POLL_WRITE | AFD_POLL_CONNECT | AFD_POLL_READ);
367 check_poll(server, event, AFD_POLL_CONNECT);
369 /* Test sending data while there is a pending WSARecv(). */
371 in_params->timeout = -1000 * 10000;
372 in_params->count = 1;
373 in_params->sockets[0].socket = server;
374 in_params->sockets[0].flags = AFD_POLL_READ;
376 ret = NtDeviceIoControlFile((HANDLE)server, event, NULL, NULL, &io,
377 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
378 ok(ret == STATUS_PENDING, "got %#x\n", ret);
380 wsabuf.buf = large_buffer;
381 wsabuf.len = 1;
382 ret = WSARecv(server, &wsabuf, 1, NULL, &flags, &overlapped, NULL);
383 ok(ret == -1, "got %d\n", ret);
384 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
386 ret = send(client, "a", 1, 0);
387 ok(ret == 1, "got %d\n", ret);
389 ret = WaitForSingleObject(overlapped.hEvent, 200);
390 ok(!ret, "got %d\n", ret);
391 ret = GetOverlappedResult((HANDLE)server, &overlapped, &size, FALSE);
392 ok(ret, "got error %lu\n", GetLastError());
393 ok(size == 1, "got size %lu\n", size);
395 ret = WaitForSingleObject(event, 0);
396 ok(ret == WAIT_TIMEOUT, "got %#x\n", ret);
398 ret = send(client, "a", 1, 0);
399 ok(ret == 1, "got %d\n", ret);
401 ret = WaitForSingleObject(event, 200);
402 ok(!ret, "got %#x\n", ret);
403 ok(!io.Status, "got %#lx\n", io.Status);
404 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
405 ok(out_params->count == 1, "got count %u\n", out_params->count);
406 ok(out_params->sockets[0].socket == server, "got socket %#Ix\n", out_params->sockets[0].socket);
407 ok(out_params->sockets[0].flags == AFD_POLL_READ, "got flags %#x\n", out_params->sockets[0].flags);
408 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
410 ret = recv(server, large_buffer, 1, 0);
411 ok(ret == 1, "got %d\n", ret);
413 /* Test sending out-of-band data. */
415 ret = send(client, "a", 1, MSG_OOB);
416 ok(ret == 1, "got %d\n", ret);
418 check_poll(client, event, AFD_POLL_WRITE | AFD_POLL_CONNECT | AFD_POLL_READ);
419 check_poll_mask(server, event, AFD_POLL_OOB, AFD_POLL_OOB);
420 check_poll(server, event, AFD_POLL_CONNECT | AFD_POLL_OOB);
422 ret = recv(server, large_buffer, 1, MSG_OOB);
423 ok(ret == 1, "got %d\n", ret);
425 check_poll(client, event, AFD_POLL_WRITE | AFD_POLL_CONNECT | AFD_POLL_READ);
426 check_poll(server, event, AFD_POLL_CONNECT);
428 ret = 1;
429 ret = setsockopt(server, SOL_SOCKET, SO_OOBINLINE, (char *)&ret, sizeof(ret));
430 ok(!ret, "got error %u\n", WSAGetLastError());
432 ret = send(client, "a", 1, MSG_OOB);
433 ok(ret == 1, "got %d\n", ret);
435 check_poll(client, event, AFD_POLL_WRITE | AFD_POLL_CONNECT | AFD_POLL_READ);
436 check_poll_mask(server, event, AFD_POLL_READ, AFD_POLL_READ);
437 check_poll(server, event, AFD_POLL_CONNECT | AFD_POLL_READ);
439 closesocket(client);
440 closesocket(server);
442 /* Test shutdown. */
444 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
445 ret = connect(client, (struct sockaddr *)&addr, sizeof(addr));
446 ok(!ret, "got error %u\n", WSAGetLastError());
447 server = accept(listener, NULL, NULL);
448 ok(server != -1, "got error %u\n", WSAGetLastError());
450 ret = shutdown(client, SD_RECEIVE);
451 ok(!ret, "got error %u\n", WSAGetLastError());
453 check_poll(client, event, AFD_POLL_WRITE | AFD_POLL_CONNECT);
454 check_poll(server, event, AFD_POLL_WRITE | AFD_POLL_CONNECT);
456 ret = shutdown(client, SD_SEND);
457 ok(!ret, "got error %u\n", WSAGetLastError());
459 check_poll(client, event, AFD_POLL_WRITE | AFD_POLL_CONNECT);
460 check_poll_mask(server, event, AFD_POLL_HUP, AFD_POLL_HUP);
461 check_poll(server, event, AFD_POLL_WRITE | AFD_POLL_CONNECT | AFD_POLL_HUP);
463 closesocket(client);
464 closesocket(server);
466 /* Test shutdown with data in the pipe. */
468 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
469 ret = connect(client, (struct sockaddr *)&addr, sizeof(addr));
470 ok(!ret, "got error %u\n", WSAGetLastError());
471 server = accept(listener, NULL, NULL);
472 ok(server != -1, "got error %u\n", WSAGetLastError());
474 ret = send(client, "data", 5, 0);
475 ok(ret == 5, "got %d\n", ret);
477 check_poll(client, event, AFD_POLL_WRITE | AFD_POLL_CONNECT);
478 check_poll_mask(server, event, AFD_POLL_READ, AFD_POLL_READ);
479 check_poll(server, event, AFD_POLL_WRITE | AFD_POLL_CONNECT | AFD_POLL_READ);
481 ret = shutdown(client, SD_SEND);
482 ok(!ret, "got error %u\n", WSAGetLastError());
484 check_poll(client, event, AFD_POLL_WRITE | AFD_POLL_CONNECT);
485 check_poll_mask(server, event, AFD_POLL_READ, AFD_POLL_READ);
486 check_poll_todo(server, event, AFD_POLL_WRITE | AFD_POLL_CONNECT | AFD_POLL_READ | AFD_POLL_HUP);
488 /* Test closing a socket while polling on it. Note that AFD_POLL_CLOSE
489 * is always returned, regardless of whether it's polled for. */
491 in_params->timeout = -1000 * 10000;
492 in_params->count = 1;
493 in_params->sockets[0].socket = client;
494 in_params->sockets[0].flags = 0;
496 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
497 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
498 ok(ret == STATUS_PENDING, "got %#x\n", ret);
500 closesocket(client);
502 ret = WaitForSingleObject(event, 100);
503 ok(!ret, "got %#x\n", ret);
504 ok(!io.Status, "got %#lx\n", io.Status);
505 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
506 ok(out_params->count == 1, "got count %u\n", out_params->count);
507 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
508 ok(out_params->sockets[0].flags == AFD_POLL_CLOSE,
509 "got flags %#x\n", out_params->sockets[0].flags);
510 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
512 closesocket(server);
514 /* Test a failed connection.
516 * The following poll works even where the equivalent WSAPoll() call fails.
517 * However, it can take over 2 seconds to complete on the testbot. */
519 if (winetest_interactive)
521 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
522 set_blocking(client, FALSE);
524 in_params->timeout = -10000 * 10000;
525 in_params->count = 1;
526 in_params->sockets[0].socket = client;
527 in_params->sockets[0].flags = ~0;
529 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
530 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
531 ok(ret == STATUS_PENDING, "got %#x\n", ret);
533 addr.sin_port = 255;
534 ret = connect(client, (struct sockaddr *)&addr, sizeof(addr));
535 ok(ret == -1, "got %d\n", ret);
536 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
538 ret = WaitForSingleObject(event, 10000);
539 ok(!ret, "got %#x\n", ret);
540 ok(!io.Status, "got %#lx\n", io.Status);
541 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
542 ok(out_params->count == 1, "got count %u\n", out_params->count);
543 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
544 ok(out_params->sockets[0].flags == AFD_POLL_CONNECT_ERR, "got flags %#x\n", out_params->sockets[0].flags);
545 ok(out_params->sockets[0].status == STATUS_CONNECTION_REFUSED, "got status %#x\n", out_params->sockets[0].status);
547 in_params->timeout = now.QuadPart;
548 memset(out_params, 0xcc, sizeof(out_buffer));
549 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
550 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
551 ok(!ret, "got %#x\n", ret);
552 ok(!io.Status, "got %#lx\n", io.Status);
553 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
554 ok(out_params->count == 1, "got count %u\n", out_params->count);
555 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
556 ok(out_params->sockets[0].flags == AFD_POLL_CONNECT_ERR, "got flags %#x\n", out_params->sockets[0].flags);
557 ok(out_params->sockets[0].status == STATUS_CONNECTION_REFUSED, "got status %#x\n", out_params->sockets[0].status);
559 memset(out_params, 0xcc, sizeof(out_buffer));
560 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
561 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
562 ok(!ret, "got %#x\n", ret);
563 ok(!io.Status, "got %#lx\n", io.Status);
564 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
565 ok(out_params->count == 1, "got count %u\n", out_params->count);
566 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
567 ok(out_params->sockets[0].flags == AFD_POLL_CONNECT_ERR, "got flags %#x\n", out_params->sockets[0].flags);
568 ok(out_params->sockets[0].status == STATUS_CONNECTION_REFUSED, "got status %#x\n", out_params->sockets[0].status);
570 ret = connect(client, (struct sockaddr *)&addr, sizeof(addr));
571 ok(ret == -1, "got %d\n", ret);
572 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
574 /* A subsequent poll call returns no events, or times out. However, this
575 * can't be reliably tested, as e.g. Linux will fail the connection
576 * immediately. */
578 closesocket(client);
580 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
582 ret = connect(client, (struct sockaddr *)&addr, sizeof(addr));
583 ok(ret == -1, "expected failure\n");
584 ok(WSAGetLastError() == WSAECONNREFUSED, "got error %u\n", WSAGetLastError());
586 memset(out_params, 0xcc, sizeof(out_buffer));
587 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
588 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
589 ok(!ret, "got %#x\n", ret);
590 ok(!io.Status, "got %#lx\n", io.Status);
591 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
592 ok(out_params->count == 1, "got count %u\n", out_params->count);
593 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
594 ok(out_params->sockets[0].flags == AFD_POLL_CONNECT_ERR, "got flags %#x\n", out_params->sockets[0].flags);
595 ok(out_params->sockets[0].status == STATUS_CONNECTION_REFUSED, "got status %#x\n", out_params->sockets[0].status);
597 closesocket(client);
600 /* Test supplying multiple handles to the ioctl. */
602 len = sizeof(addr);
603 ret = getsockname(listener, (struct sockaddr *)&addr, &len);
604 ok(!ret, "got error %u\n", WSAGetLastError());
606 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
607 ret = connect(client, (struct sockaddr *)&addr, sizeof(addr));
608 ok(!ret, "got error %u\n", WSAGetLastError());
609 server = accept(listener, NULL, NULL);
610 ok(server != -1, "got error %u\n", WSAGetLastError());
612 in_params->timeout = -1000 * 10000;
613 in_params->count = 2;
614 in_params->sockets[0].socket = client;
615 in_params->sockets[0].flags = AFD_POLL_READ;
616 in_params->sockets[1].socket = server;
617 in_params->sockets[1].flags = AFD_POLL_READ;
619 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
620 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
621 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
623 params_size = offsetof(struct afd_poll_params, sockets[2]);
625 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
626 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
627 ok(ret == STATUS_PENDING, "got %#x\n", ret);
629 ret = send(client, "data", 5, 0);
630 ok(ret == 5, "got %d\n", ret);
632 ret = WaitForSingleObject(event, 100);
633 ok(!ret, "got %#x\n", ret);
634 ok(!io.Status, "got %#lx\n", io.Status);
635 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
636 ok(out_params->count == 1, "got count %u\n", out_params->count);
637 ok(out_params->sockets[0].socket == server, "got socket %#Ix\n", out_params->sockets[0].socket);
638 ok(out_params->sockets[0].flags == AFD_POLL_READ, "got flags %#x\n", out_params->sockets[0].flags);
639 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
641 in_params->count = 2;
642 in_params->sockets[0].socket = client;
643 in_params->sockets[0].flags = AFD_POLL_READ | AFD_POLL_WRITE;
644 in_params->sockets[1].socket = server;
645 in_params->sockets[1].flags = AFD_POLL_READ | AFD_POLL_WRITE;
647 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
648 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
649 ok(!ret, "got %#x\n", ret);
650 ok(!io.Status, "got %#lx\n", io.Status);
651 ok(io.Information == offsetof(struct afd_poll_params, sockets[2]), "got %#Ix\n", io.Information);
652 ok(out_params->count == 2, "got count %u\n", out_params->count);
653 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
654 ok(out_params->sockets[0].flags == AFD_POLL_WRITE, "got flags %#x\n", out_params->sockets[0].flags);
655 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
656 ok(out_params->sockets[1].socket == server, "got socket %#Ix\n", out_params->sockets[1].socket);
657 ok(out_params->sockets[1].flags == (AFD_POLL_READ | AFD_POLL_WRITE),
658 "got flags %#x\n", out_params->sockets[1].flags);
659 ok(!out_params->sockets[1].status, "got status %#x\n", out_params->sockets[1].status);
661 in_params->count = 2;
662 in_params->sockets[0].socket = client;
663 in_params->sockets[0].flags = AFD_POLL_READ | AFD_POLL_WRITE;
664 in_params->sockets[1].socket = server;
665 in_params->sockets[1].flags = AFD_POLL_READ | AFD_POLL_WRITE;
667 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
668 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
669 ok(!ret, "got %#x\n", ret);
670 ok(!io.Status, "got %#lx\n", io.Status);
671 ok(io.Information == offsetof(struct afd_poll_params, sockets[2]), "got %#Ix\n", io.Information);
672 ok(out_params->count == 2, "got count %u\n", out_params->count);
673 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
674 ok(out_params->sockets[0].flags == AFD_POLL_WRITE, "got flags %#x\n", out_params->sockets[0].flags);
675 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
676 ok(out_params->sockets[1].socket == server, "got socket %#Ix\n", out_params->sockets[1].socket);
677 ok(out_params->sockets[1].flags == (AFD_POLL_READ | AFD_POLL_WRITE),
678 "got flags %#x\n", out_params->sockets[1].flags);
679 ok(!out_params->sockets[1].status, "got status %#x\n", out_params->sockets[1].status);
681 /* Close a socket while polling on another. */
683 in_params->timeout = -100 * 10000;
684 in_params->count = 1;
685 in_params->sockets[0].socket = client;
686 in_params->sockets[0].flags = AFD_POLL_READ;
687 params_size = offsetof(struct afd_poll_params, sockets[1]);
689 ret = NtDeviceIoControlFile((HANDLE)server, event, NULL, NULL, &io,
690 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
691 ok(ret == STATUS_PENDING, "got %#x\n", ret);
693 closesocket(server);
695 ret = WaitForSingleObject(event, 1000);
696 ok(!ret, "got %#x\n", ret);
697 todo_wine ok(io.Status == STATUS_TIMEOUT, "got %#lx\n", io.Status);
698 todo_wine ok(io.Information == offsetof(struct afd_poll_params, sockets[0]), "got %#Ix\n", io.Information);
699 todo_wine ok(!out_params->count, "got count %u\n", out_params->count);
701 closesocket(client);
703 /* Test connecting while there is a pending AcceptEx(). */
705 in_params->timeout = -1000 * 10000;
706 in_params->count = 1;
707 in_params->sockets[0].socket = listener;
708 in_params->sockets[0].flags = AFD_POLL_ACCEPT;
710 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io,
711 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
712 ok(ret == STATUS_PENDING, "got %#x\n", ret);
714 server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
715 ret = pAcceptEx(listener, server, large_buffer, 0, 0, sizeof(struct sockaddr_in) + 16, NULL, &overlapped);
716 ok(!ret, "got %d\n", ret);
717 ok(WSAGetLastError() == ERROR_IO_PENDING, "got error %u\n", WSAGetLastError());
719 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
720 ret = connect(client, (struct sockaddr *)&addr, sizeof(addr));
721 ok(!ret, "got error %u\n", WSAGetLastError());
723 ret = WaitForSingleObject(overlapped.hEvent, 200);
724 ok(!ret, "got %d\n", ret);
725 ret = GetOverlappedResult((HANDLE)listener, &overlapped, &size, FALSE);
726 ok(ret, "got error %lu\n", GetLastError());
727 ok(!size, "got size %lu\n", size);
729 ret = WaitForSingleObject(event, 0);
730 ok(ret == WAIT_TIMEOUT, "got %#x\n", ret);
732 closesocket(server);
733 closesocket(client);
735 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
736 ret = connect(client, (struct sockaddr *)&addr, sizeof(addr));
737 ok(!ret, "got error %u\n", WSAGetLastError());
739 ret = WaitForSingleObject(event, 200);
740 ok(!ret, "got %#x\n", ret);
741 ok(!io.Status, "got %#lx\n", io.Status);
742 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
743 ok(out_params->count == 1, "got count %u\n", out_params->count);
744 ok(out_params->sockets[0].socket == listener, "got socket %#Ix\n", out_params->sockets[0].socket);
745 ok(out_params->sockets[0].flags == AFD_POLL_ACCEPT, "got flags %#x\n", out_params->sockets[0].flags);
746 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
748 server = accept(listener, NULL, NULL);
749 ok(server != -1, "got error %u\n", WSAGetLastError());
750 closesocket(server);
751 closesocket(client);
753 /* Verify that CONNECT and WRITE are signaled simultaneously. */
755 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
757 in_params->timeout = -1000 * 10000;
758 in_params->count = 1;
759 in_params->sockets[0].socket = client;
760 in_params->sockets[0].flags = ~0;
761 params_size = offsetof(struct afd_poll_params, sockets[1]);
763 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
764 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
765 ok(ret == STATUS_PENDING, "got %#x\n", ret);
767 ret = connect(client, (struct sockaddr *)&addr, sizeof(addr));
768 ok(!ret, "got error %u\n", WSAGetLastError());
770 ret = WaitForSingleObject(event, 200);
771 ok(!ret, "got %#x\n", ret);
772 ok(!io.Status, "got %#lx\n", io.Status);
773 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
774 ok(out_params->count == 1, "got count %u\n", out_params->count);
775 ok(out_params->sockets[0].flags == (AFD_POLL_CONNECT | AFD_POLL_WRITE),
776 "got flags %#x\n", out_params->sockets[0].flags);
777 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
779 server = accept(listener, NULL, NULL);
780 ok(server != -1, "got error %u\n", WSAGetLastError());
781 closesocket(server);
782 closesocket(client);
784 closesocket(listener);
786 /* Test UDP sockets. */
788 client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
789 server = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
791 check_poll(client, event, AFD_POLL_WRITE);
792 check_poll(server, event, AFD_POLL_WRITE);
794 ret = bind(client, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
795 ok(!ret, "got error %u\n", WSAGetLastError());
796 len = sizeof(addr);
797 ret = getsockname(client, (struct sockaddr *)&addr, &len);
798 ok(!ret, "got error %u\n", WSAGetLastError());
800 check_poll(client, event, AFD_POLL_WRITE);
801 check_poll(server, event, AFD_POLL_WRITE);
803 in_params->timeout = -1000 * 10000;
804 in_params->count = 1;
805 in_params->sockets[0].socket = client;
806 in_params->sockets[0].flags = (~0) & ~AFD_POLL_WRITE;
807 params_size = offsetof(struct afd_poll_params, sockets[1]);
809 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
810 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
811 ok(ret == STATUS_PENDING, "got %#x\n", ret);
813 ret = sendto(server, "data", 5, 0, (struct sockaddr *)&addr, sizeof(addr));
814 ok(ret == 5, "got %d\n", ret);
816 ret = WaitForSingleObject(event, 100);
817 ok(!ret, "got %#x\n", ret);
818 ok(!io.Status, "got %#lx\n", io.Status);
819 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
820 ok(out_params->count == 1, "got count %u\n", out_params->count);
821 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
822 ok(out_params->sockets[0].flags == AFD_POLL_READ, "got flags %#x\n", out_params->sockets[0].flags);
823 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
825 in_params->timeout = -1000 * 10000;
826 in_params->count = 1;
827 in_params->sockets[0].socket = server;
828 in_params->sockets[0].flags = AFD_POLL_CONNECT;
829 params_size = offsetof(struct afd_poll_params, sockets[1]);
831 ret = NtDeviceIoControlFile((HANDLE)server, event, NULL, NULL, &io,
832 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
833 ok(ret == STATUS_PENDING, "got %#x\n", ret);
835 ret = connect(server, (struct sockaddr *)&addr, sizeof(addr));
836 ok(!ret, "got error %lu\n", GetLastError());
838 ret = WaitForSingleObject(event, 100);
839 todo_wine ok(!ret, "got %#x\n", ret);
840 if (!ret)
842 ok(!io.Status, "got %#lx\n", io.Status);
843 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
844 ok(out_params->count == 1, "got count %u\n", out_params->count);
845 ok(out_params->sockets[0].socket == server, "got socket %#Ix\n", out_params->sockets[0].socket);
846 ok(out_params->sockets[0].flags == AFD_POLL_CONNECT, "got flags %#x\n", out_params->sockets[0].flags);
847 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
849 else
851 CancelIo((HANDLE)server);
852 ret = WaitForSingleObject(event, 100);
853 ok(!ret, "wait timed out\n");
856 closesocket(client);
857 closesocket(server);
859 /* Passing any invalid sockets yields STATUS_INVALID_HANDLE.
861 * Note however that WSAPoll() happily accepts invalid sockets. It seems
862 * user-side cached data is used: closing a handle with CloseHandle() before
863 * passing it to WSAPoll() yields ENOTSOCK. */
865 tcp_socketpair(&client, &server);
867 in_params->count = 2;
868 in_params->sockets[0].socket = 0xabacab;
869 in_params->sockets[0].flags = AFD_POLL_READ | AFD_POLL_WRITE;
870 in_params->sockets[1].socket = client;
871 in_params->sockets[1].flags = AFD_POLL_READ | AFD_POLL_WRITE;
872 params_size = offsetof(struct afd_poll_params, sockets[2]);
874 memset(&io, 0, sizeof(io));
875 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
876 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
877 ok(ret == STATUS_INVALID_HANDLE, "got %#x\n", ret);
878 ok(!io.Status, "got %#lx\n", io.Status);
879 ok(!io.Information, "got %#Ix\n", io.Information);
881 /* Test passing the same handle twice. */
883 in_params->count = 3;
884 in_params->sockets[0].socket = client;
885 in_params->sockets[0].flags = AFD_POLL_READ | AFD_POLL_WRITE;
886 in_params->sockets[1].socket = client;
887 in_params->sockets[1].flags = AFD_POLL_READ | AFD_POLL_WRITE;
888 in_params->sockets[2].socket = client;
889 in_params->sockets[2].flags = AFD_POLL_READ | AFD_POLL_WRITE | AFD_POLL_CONNECT;
890 params_size = offsetof(struct afd_poll_params, sockets[3]);
892 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
893 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
894 ok(!ret, "got %#x\n", ret);
895 ok(!io.Status, "got %#lx\n", io.Status);
896 ok(io.Information == offsetof(struct afd_poll_params, sockets[3]), "got %#Ix\n", io.Information);
897 ok(out_params->count == 3, "got count %u\n", out_params->count);
898 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
899 ok(out_params->sockets[0].flags == AFD_POLL_WRITE, "got flags %#x\n", out_params->sockets[0].flags);
900 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
901 ok(out_params->sockets[1].socket == client, "got socket %#Ix\n", out_params->sockets[1].socket);
902 ok(out_params->sockets[1].flags == AFD_POLL_WRITE, "got flags %#x\n", out_params->sockets[1].flags);
903 ok(!out_params->sockets[1].status, "got status %#x\n", out_params->sockets[1].status);
904 ok(out_params->sockets[2].socket == client, "got socket %#Ix\n", out_params->sockets[2].socket);
905 ok(out_params->sockets[2].flags == (AFD_POLL_WRITE | AFD_POLL_CONNECT),
906 "got flags %#x\n", out_params->sockets[2].flags);
907 ok(!out_params->sockets[2].status, "got status %#x\n", out_params->sockets[2].status);
909 in_params->count = 2;
910 in_params->sockets[0].socket = client;
911 in_params->sockets[0].flags = AFD_POLL_READ;
912 in_params->sockets[1].socket = client;
913 in_params->sockets[1].flags = AFD_POLL_READ;
914 params_size = offsetof(struct afd_poll_params, sockets[2]);
916 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
917 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
918 ok(ret == STATUS_PENDING, "got %#x\n", ret);
920 ret = send(server, "data", 5, 0);
921 ok(ret == 5, "got %d\n", ret);
923 ret = WaitForSingleObject(event, 100);
924 ok(!ret, "got %#x\n", ret);
925 ok(!io.Status, "got %#lx\n", io.Status);
926 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
927 ok(out_params->count == 1, "got count %u\n", out_params->count);
928 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
929 ok(out_params->sockets[0].flags == AFD_POLL_READ, "got flags %#x\n", out_params->sockets[0].flags);
930 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
932 closesocket(client);
933 closesocket(server);
935 CloseHandle(overlapped.hEvent);
936 CloseHandle(event);
937 free(large_buffer);
939 CloseHandle(afd_handle);
942 struct poll_exclusive_thread_cb_ctx
944 SOCKET ctl_sock;
945 HANDLE event;
946 IO_STATUS_BLOCK *io;
947 ULONG params_size;
948 struct afd_poll_params *in_params;
949 struct afd_poll_params *out_params;
952 static DWORD WINAPI poll_exclusive_thread_cb(void *param)
954 struct poll_exclusive_thread_cb_ctx *ctx = param;
955 int ret;
957 ret = NtDeviceIoControlFile((HANDLE)ctx->ctl_sock, ctx->event, NULL, NULL, ctx->io,
958 IOCTL_AFD_POLL, ctx->in_params, ctx->params_size, ctx->out_params, ctx->params_size);
959 ok(ret == STATUS_PENDING, "got %#x\n", ret);
961 ret = WaitForSingleObject(ctx->event, 100);
962 ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
964 return 0;
967 #define POLL_SOCK_CNT 2
968 #define POLL_CNT 4
970 static void test_poll_exclusive(void)
972 char in_buffer[offsetof(struct afd_poll_params, sockets[POLL_SOCK_CNT + 1])];
973 char out_buffers[POLL_CNT][offsetof(struct afd_poll_params, sockets[POLL_SOCK_CNT + 1])];
974 struct afd_poll_params *in_params = (struct afd_poll_params *)in_buffer;
975 struct afd_poll_params *out_params[POLL_CNT] =
977 (struct afd_poll_params *)out_buffers[0],
978 (struct afd_poll_params *)out_buffers[1],
979 (struct afd_poll_params *)out_buffers[2],
980 (struct afd_poll_params *)out_buffers[3]
982 SOCKET ctl_sock;
983 SOCKET socks[POLL_CNT];
984 IO_STATUS_BLOCK io[POLL_CNT];
985 HANDLE events[POLL_CNT];
986 ULONG params_size;
987 struct poll_exclusive_thread_cb_ctx cb_ctx;
988 HANDLE thrd;
989 size_t i;
990 int ret;
992 ctl_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
994 for (i = 0; i < POLL_CNT; i++)
996 socks[i] = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
997 events[i] = CreateEventW(NULL, TRUE, FALSE, NULL);
1000 params_size = offsetof(struct afd_poll_params, sockets[1]);
1002 in_params->timeout = TIMEOUT_INFINITE;
1003 in_params->count = 1;
1004 in_params->exclusive = FALSE;
1005 in_params->sockets[0].socket = socks[0];
1006 in_params->sockets[0].flags = ~0;
1007 in_params->sockets[0].status = 0;
1009 /***** Exclusive explicitly terminated *****/
1011 in_params->exclusive = TRUE;
1013 ret = NtDeviceIoControlFile((HANDLE)ctl_sock, events[0], NULL, NULL, &io[0],
1014 IOCTL_AFD_POLL, in_params, params_size, out_params[0], params_size);
1015 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1017 ret = WaitForSingleObject(events[0], 100);
1018 ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
1020 CancelIo((HANDLE)ctl_sock);
1022 ret = WaitForSingleObject(events[0], 100);
1023 ok(ret == STATUS_SUCCESS, "got %#x\n", ret);
1025 /***** Same socket tests *****/
1027 /* Basic non-exclusive behavior as reference. */
1029 in_params->exclusive = FALSE;
1031 ret = NtDeviceIoControlFile((HANDLE)ctl_sock, events[0], NULL, NULL, &io[0],
1032 IOCTL_AFD_POLL, in_params, params_size, out_params[0], params_size);
1033 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1035 ret = NtDeviceIoControlFile((HANDLE)ctl_sock, events[1], NULL, NULL, &io[1],
1036 IOCTL_AFD_POLL, in_params, params_size, out_params[1], params_size);
1037 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1039 ret = WaitForSingleObject(events[0], 100);
1040 ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
1042 ret = WaitForSingleObject(events[1], 100);
1043 ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
1045 CancelIo((HANDLE)ctl_sock);
1047 /* If the main poll is exclusive it is terminated by the following exclusive. */
1049 in_params->exclusive = TRUE;
1051 ret = NtDeviceIoControlFile((HANDLE)ctl_sock, events[0], NULL, NULL, &io[0],
1052 IOCTL_AFD_POLL, in_params, params_size, out_params[0], params_size);
1053 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1055 ret = NtDeviceIoControlFile((HANDLE)ctl_sock, events[1], NULL, NULL, &io[1],
1056 IOCTL_AFD_POLL, in_params, params_size, out_params[1], params_size);
1057 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1059 ret = WaitForSingleObject(events[0], 100);
1060 ok(ret == STATUS_SUCCESS, "got %#x\n", ret);
1062 ret = WaitForSingleObject(events[1], 100);
1063 ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
1065 CancelIo((HANDLE)ctl_sock);
1067 /* If the main poll is non-exclusive neither itself nor the following exclusives are terminated. */
1069 in_params->exclusive = FALSE;
1071 ret = NtDeviceIoControlFile((HANDLE)ctl_sock, events[0], NULL, NULL, &io[0],
1072 IOCTL_AFD_POLL, in_params, params_size, out_params[0], params_size);
1073 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1075 in_params->exclusive = TRUE;
1077 ret = NtDeviceIoControlFile((HANDLE)ctl_sock, events[1], NULL, NULL, &io[1],
1078 IOCTL_AFD_POLL, in_params, params_size, out_params[1], params_size);
1079 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1081 ret = NtDeviceIoControlFile((HANDLE)ctl_sock, events[2], NULL, NULL, &io[2],
1082 IOCTL_AFD_POLL, in_params, params_size, out_params[2], params_size);
1083 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1085 ret = WaitForSingleObject(events[0], 100);
1086 ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
1088 ret = WaitForSingleObject(events[1], 100);
1089 ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
1091 ret = WaitForSingleObject(events[2], 100);
1092 ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
1094 CancelIo((HANDLE)ctl_sock);
1096 /* A new poll is considered the main poll if no others are queued at the time. */
1098 in_params->exclusive = FALSE;
1100 ret = NtDeviceIoControlFile((HANDLE)socks[0], events[0], NULL, NULL, &io[0],
1101 IOCTL_AFD_POLL, in_params, params_size, out_params[0], params_size);
1102 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1104 CancelIo((HANDLE)socks[0]);
1106 ret = WaitForSingleObject(events[0], 100);
1107 ok(ret == STATUS_SUCCESS, "got %#x\n", ret);
1109 in_params->exclusive = TRUE;
1111 ret = NtDeviceIoControlFile((HANDLE)ctl_sock, events[1], NULL, NULL, &io[1],
1112 IOCTL_AFD_POLL, in_params, params_size, out_params[1], params_size);
1113 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1115 ret = NtDeviceIoControlFile((HANDLE)ctl_sock, events[2], NULL, NULL, &io[2],
1116 IOCTL_AFD_POLL, in_params, params_size, out_params[2], params_size);
1117 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1119 ret = WaitForSingleObject(events[1], 100);
1120 ok(ret == STATUS_SUCCESS, "got %#x\n", ret);
1122 ret = WaitForSingleObject(events[2], 100);
1123 ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
1125 CancelIo((HANDLE)ctl_sock);
1127 /* The exclusive check does not happen again after the call to NtDeviceIoControlFile(). */
1129 in_params->exclusive = FALSE;
1131 ret = NtDeviceIoControlFile((HANDLE)socks[0], events[0], NULL, NULL, &io[0],
1132 IOCTL_AFD_POLL, in_params, params_size, out_params[0], params_size);
1133 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1135 in_params->exclusive = TRUE;
1137 ret = NtDeviceIoControlFile((HANDLE)ctl_sock, events[1], NULL, NULL, &io[1],
1138 IOCTL_AFD_POLL, in_params, params_size, out_params[1], params_size);
1139 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1141 CancelIo((HANDLE)socks[0]);
1143 ret = WaitForSingleObject(events[0], 100);
1144 ok(ret == STATUS_SUCCESS, "got %#x\n", ret);
1146 ret = NtDeviceIoControlFile((HANDLE)ctl_sock, events[2], NULL, NULL, &io[2],
1147 IOCTL_AFD_POLL, in_params, params_size, out_params[2], params_size);
1148 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1150 ret = WaitForSingleObject(events[1], 100);
1151 ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
1153 ret = WaitForSingleObject(events[2], 100);
1154 ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
1156 CancelIo((HANDLE)ctl_sock);
1158 /* After the main poll is terminated, any subsequent poll becomes the main
1159 * and can be terminated if exclusive. */
1161 in_params->exclusive = FALSE;
1163 ret = NtDeviceIoControlFile((HANDLE)socks[0], events[0], NULL, NULL, &io[0],
1164 IOCTL_AFD_POLL, in_params, params_size, out_params[0], params_size);
1165 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1167 in_params->exclusive = TRUE;
1169 ret = NtDeviceIoControlFile((HANDLE)ctl_sock, events[1], NULL, NULL, &io[1],
1170 IOCTL_AFD_POLL, in_params, params_size, out_params[1], params_size);
1171 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1173 CancelIo((HANDLE)socks[0]);
1175 ret = WaitForSingleObject(events[0], 100);
1176 ok(ret == STATUS_SUCCESS, "got %#x\n", ret);
1178 ret = NtDeviceIoControlFile((HANDLE)ctl_sock, events[2], NULL, NULL, &io[2],
1179 IOCTL_AFD_POLL, in_params, params_size, out_params[2], params_size);
1180 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1182 ret = NtDeviceIoControlFile((HANDLE)ctl_sock, events[3], NULL, NULL, &io[3],
1183 IOCTL_AFD_POLL, in_params, params_size, out_params[3], params_size);
1184 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1186 ret = WaitForSingleObject(events[1], 100);
1187 ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
1189 ret = WaitForSingleObject(events[2], 100);
1190 ok(ret == STATUS_SUCCESS, "got %#x\n", ret);
1192 ret = WaitForSingleObject(events[3], 100);
1193 ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
1195 CancelIo((HANDLE)ctl_sock);
1197 /***** Exclusive poll on different sockets *****/
1199 in_params->exclusive = TRUE;
1200 in_params->sockets[0].socket = socks[0];
1202 ret = NtDeviceIoControlFile((HANDLE)ctl_sock, events[0], NULL, NULL, &io[0],
1203 IOCTL_AFD_POLL, in_params, params_size, out_params[0], params_size);
1204 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1206 in_params->sockets[0].socket = socks[1];
1208 ret = NtDeviceIoControlFile((HANDLE)ctl_sock, events[1], NULL, NULL, &io[1],
1209 IOCTL_AFD_POLL, in_params, params_size, out_params[1], params_size);
1210 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1212 ret = WaitForSingleObject(events[0], 100);
1213 ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
1215 ret = WaitForSingleObject(events[1], 100);
1216 ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
1218 CancelIo((HANDLE)ctl_sock);
1220 /***** Exclusive poll from other thread *****/
1222 in_params->exclusive = TRUE;
1223 in_params->sockets[0].socket = ctl_sock;
1225 ret = NtDeviceIoControlFile((HANDLE)ctl_sock, events[0], NULL, NULL, &io[0],
1226 IOCTL_AFD_POLL, in_params, params_size, out_params[0], params_size);
1227 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1229 cb_ctx.ctl_sock = ctl_sock;
1230 cb_ctx.event = events[1];
1231 cb_ctx.io = &io[1];
1232 cb_ctx.params_size = params_size;
1233 cb_ctx.in_params = in_params;
1234 cb_ctx.out_params = out_params[1];
1236 thrd = CreateThread(NULL, 0, poll_exclusive_thread_cb, &cb_ctx, 0, NULL);
1237 WaitForSingleObject(thrd, INFINITE);
1238 CloseHandle(thrd);
1240 ret = WaitForSingleObject(events[0], 100);
1241 ok(ret == STATUS_SUCCESS, "got %#x\n", ret);
1243 CancelIo((HANDLE)ctl_sock);
1245 /***** Exclusive poll on overlapping socket sets *****/
1247 params_size = offsetof(struct afd_poll_params, sockets[2]);
1249 in_params->exclusive = TRUE;
1250 in_params->count = 2;
1251 in_params->sockets[0].socket = ctl_sock;
1252 in_params->sockets[1].socket = socks[0];
1254 ret = NtDeviceIoControlFile((HANDLE)ctl_sock, events[0], NULL, NULL, &io[0],
1255 IOCTL_AFD_POLL, in_params, params_size, out_params[0], params_size);
1256 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1258 in_params->sockets[0].socket = ctl_sock;
1259 in_params->sockets[1].socket = socks[1];
1261 ret = NtDeviceIoControlFile((HANDLE)ctl_sock, events[1], NULL, NULL, &io[1],
1262 IOCTL_AFD_POLL, in_params, params_size, out_params[1], params_size);
1263 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1265 ret = WaitForSingleObject(events[0], 100);
1266 ok(ret == STATUS_SUCCESS, "got %#x\n", ret);
1268 ret = WaitForSingleObject(events[1], 100);
1269 ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
1271 CancelIo((HANDLE)ctl_sock);
1273 /* Cleanup. */
1275 closesocket(ctl_sock);
1277 for (i = 0; i < POLL_CNT; i++)
1279 closesocket(socks[i]);
1280 CloseHandle(events[i]);
1284 #undef POLL_SOCK_CNT
1285 #undef POLL_CNT
1287 static void test_poll_completion_port(void)
1289 struct afd_poll_params params = {0};
1290 LARGE_INTEGER zero = {{0}};
1291 SOCKET client, server;
1292 ULONG_PTR key, value;
1293 IO_STATUS_BLOCK io;
1294 HANDLE event, port;
1295 int ret;
1297 event = CreateEventW(NULL, TRUE, FALSE, NULL);
1298 tcp_socketpair(&client, &server);
1299 port = CreateIoCompletionPort((HANDLE)client, NULL, 0, 0);
1301 params.timeout = -100 * 10000;
1302 params.count = 1;
1303 params.sockets[0].socket = client;
1304 params.sockets[0].flags = AFD_POLL_WRITE;
1305 params.sockets[0].status = 0xdeadbeef;
1307 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1308 IOCTL_AFD_POLL, &params, sizeof(params), &params, sizeof(params));
1309 ok(!ret, "got %#x\n", ret);
1311 ret = NtRemoveIoCompletion(port, &key, &value, &io, &zero);
1312 ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
1314 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, (void *)0xdeadbeef, &io,
1315 IOCTL_AFD_POLL, &params, sizeof(params), &params, sizeof(params));
1316 ok(!ret, "got %#x\n", ret);
1318 ret = NtRemoveIoCompletion(port, &key, &value, &io, &zero);
1319 ok(!ret, "got %#x\n", ret);
1320 ok(!key, "got key %#Ix\n", key);
1321 ok(value == 0xdeadbeef, "got value %#Ix\n", value);
1323 params.timeout = 0;
1324 params.count = 1;
1325 params.sockets[0].socket = client;
1326 params.sockets[0].flags = AFD_POLL_READ;
1327 params.sockets[0].status = 0xdeadbeef;
1329 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, (void *)0xdeadbeef, &io,
1330 IOCTL_AFD_POLL, &params, sizeof(params), &params, sizeof(params));
1331 ok(!ret, "got %#x\n", ret);
1333 ret = NtRemoveIoCompletion(port, &key, &value, &io, &zero);
1334 ok(!ret, "got %#x\n", ret);
1335 ok(!key, "got key %#Ix\n", key);
1336 ok(value == 0xdeadbeef, "got value %#Ix\n", value);
1338 /* Close a socket while polling on another. */
1340 params.timeout = -100 * 10000;
1341 params.count = 1;
1342 params.sockets[0].socket = server;
1343 params.sockets[0].flags = AFD_POLL_READ;
1344 params.sockets[0].status = 0xdeadbeef;
1346 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, (void *)0xdeadbeef, &io,
1347 IOCTL_AFD_POLL, &params, sizeof(params), &params, sizeof(params));
1348 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1350 closesocket(client);
1352 ret = WaitForSingleObject(event, 1000);
1353 ok(!ret, "got %#x\n", ret);
1354 todo_wine ok(io.Status == STATUS_TIMEOUT, "got %#lx\n", io.Status);
1355 todo_wine ok(io.Information == offsetof(struct afd_poll_params, sockets[0]), "got %#Ix\n", io.Information);
1356 todo_wine ok(!params.count, "got count %u\n", params.count);
1358 ret = NtRemoveIoCompletion(port, &key, &value, &io, &zero);
1359 ok(!ret, "got %#x\n", ret);
1360 ok(!key, "got key %#Ix\n", key);
1361 ok(value == 0xdeadbeef, "got value %#Ix\n", value);
1363 CloseHandle(port);
1364 closesocket(server);
1365 CloseHandle(event);
1368 static void test_poll_reset(void)
1370 char in_buffer[offsetof(struct afd_poll_params, sockets[3])];
1371 char out_buffer[offsetof(struct afd_poll_params, sockets[3])];
1372 struct afd_poll_params *in_params = (struct afd_poll_params *)in_buffer;
1373 struct afd_poll_params *out_params = (struct afd_poll_params *)out_buffer;
1374 SOCKET client, server;
1375 IO_STATUS_BLOCK io;
1376 ULONG params_size;
1377 HANDLE event;
1378 int ret;
1380 memset(in_buffer, 0, sizeof(in_buffer));
1381 memset(out_buffer, 0, sizeof(out_buffer));
1382 event = CreateEventW(NULL, TRUE, FALSE, NULL);
1383 tcp_socketpair(&client, &server);
1385 in_params->timeout = -1000 * 10000;
1386 in_params->count = 1;
1387 in_params->sockets[0].socket = client;
1388 in_params->sockets[0].flags = ~(AFD_POLL_WRITE | AFD_POLL_CONNECT);
1389 params_size = offsetof(struct afd_poll_params, sockets[1]);
1391 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1392 IOCTL_AFD_POLL, in_params, params_size, out_params, params_size);
1393 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1395 close_with_rst(server);
1397 ret = WaitForSingleObject(event, 100);
1398 ok(!ret, "got %#x\n", ret);
1399 ok(!io.Status, "got %#lx\n", io.Status);
1400 ok(io.Information == offsetof(struct afd_poll_params, sockets[1]), "got %#Ix\n", io.Information);
1401 ok(out_params->count == 1, "got count %u\n", out_params->count);
1402 ok(out_params->sockets[0].socket == client, "got socket %#Ix\n", out_params->sockets[0].socket);
1403 ok(out_params->sockets[0].flags == AFD_POLL_RESET, "got flags %#x\n", out_params->sockets[0].flags);
1404 ok(!out_params->sockets[0].status, "got status %#x\n", out_params->sockets[0].status);
1406 check_poll(client, event, AFD_POLL_WRITE | AFD_POLL_CONNECT | AFD_POLL_RESET);
1408 closesocket(client);
1409 CloseHandle(event);
1412 static void test_recv(void)
1414 const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
1415 struct afd_recv_params params = {0};
1416 SOCKET client, server, listener;
1417 struct sockaddr addr;
1418 IO_STATUS_BLOCK io;
1419 WSABUF wsabufs[2];
1420 char buffer[8];
1421 HANDLE event;
1422 int ret, len;
1424 event = CreateEventW(NULL, TRUE, FALSE, NULL);
1426 listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1427 ret = bind(listener, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
1428 ok(!ret, "got error %u\n", WSAGetLastError());
1429 ret = listen(listener, 1);
1430 ok(!ret, "got error %u\n", WSAGetLastError());
1431 len = sizeof(addr);
1432 ret = getsockname(listener, (struct sockaddr *)&addr, &len);
1433 ok(!ret, "got error %u\n", WSAGetLastError());
1435 memset(&io, 0, sizeof(io));
1436 ret = NtDeviceIoControlFile((HANDLE)listener, event, NULL, NULL, &io, IOCTL_AFD_RECV, NULL, 0, NULL, 0);
1437 todo_wine ok(ret == STATUS_INVALID_CONNECTION, "got %#x\n", ret);
1438 ok(!io.Status, "got status %#lx\n", io.Status);
1439 ok(!io.Information, "got information %#Ix\n", io.Information);
1441 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1442 ret = connect(client, (struct sockaddr *)&addr, sizeof(addr));
1443 ok(!ret, "got error %u\n", WSAGetLastError());
1444 server = accept(listener, NULL, NULL);
1445 ok(server != -1, "got error %u\n", WSAGetLastError());
1447 memset(&io, 0, sizeof(io));
1448 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io, IOCTL_AFD_RECV, NULL, 0, NULL, 0);
1449 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
1450 ok(!io.Status, "got status %#lx\n", io.Status);
1451 ok(!io.Information, "got information %#Ix\n", io.Information);
1453 wsabufs[0].len = sizeof(buffer);
1454 wsabufs[0].buf = buffer;
1455 params.buffers = wsabufs;
1456 params.count = 1;
1457 params.msg_flags = AFD_MSG_NOT_OOB;
1459 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1460 IOCTL_AFD_RECV, &params, sizeof(params) - 1, NULL, 0);
1461 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
1463 io.Status = 0xdeadbeef;
1464 io.Information = 0xdeadbeef;
1465 memset(buffer, 0xcc, sizeof(buffer));
1466 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1467 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1468 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1469 ok(io.Status == 0xdeadbeef, "got status %#lx\n", io.Status);
1470 ok(io.Information == 0xdeadbeef, "got information %#Ix\n", io.Information);
1472 /* These structures need not remain valid. */
1473 memset(&params, 0xcc, sizeof(params));
1474 memset(wsabufs, 0xcc, sizeof(wsabufs));
1476 ret = send(server, "data", 5, 0);
1477 ok(ret == 5, "got %d\n", ret);
1479 ret = WaitForSingleObject(event, 200);
1480 ok(!ret, "wait timed out\n");
1481 ok(!io.Status, "got %#lx\n", io.Status);
1482 ok(io.Information == 5, "got %#Ix\n", io.Information);
1483 ok(!strcmp(buffer, "data"), "got %s\n", debugstr_an(buffer, io.Information));
1485 /* Test with multiple buffers. */
1487 wsabufs[0].len = 2;
1488 wsabufs[0].buf = buffer;
1489 wsabufs[1].len = 4;
1490 wsabufs[1].buf = buffer + 3;
1491 memset(&params, 0, sizeof(params));
1492 params.buffers = wsabufs;
1493 params.count = 2;
1494 params.msg_flags = AFD_MSG_NOT_OOB;
1496 memset(&io, 0, sizeof(io));
1497 memset(buffer, 0xcc, sizeof(buffer));
1498 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1499 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1500 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1501 ok(!io.Status, "got status %#lx\n", io.Status);
1502 ok(!io.Information, "got information %#Ix\n", io.Information);
1504 ret = send(server, "data", 5, 0);
1505 ok(ret == 5, "got %d\n", ret);
1507 ret = WaitForSingleObject(event, 200);
1508 ok(!ret, "wait timed out\n");
1509 ok(!io.Status, "got %#lx\n", io.Status);
1510 ok(io.Information == 5, "got %#Ix\n", io.Information);
1511 ok(!strcmp(buffer, "da\xccta"), "got %s\n", debugstr_an(buffer, io.Information));
1513 /* Test synchronous return. */
1515 ret = send(server, "data", 5, 0);
1516 ok(ret == 5, "got %d\n", ret);
1518 /* wait for the data to be available */
1519 check_poll_mask(client, event, AFD_POLL_READ, AFD_POLL_READ);
1521 memset(&io, 0xcc, sizeof(io));
1522 memset(buffer, 0xcc, sizeof(buffer));
1523 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1524 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1525 ok(!ret, "got %#x\n", ret);
1526 ok(!io.Status, "got %#lx\n", io.Status);
1527 ok(io.Information == 5, "got %#Ix\n", io.Information);
1528 ok(!strcmp(buffer, "da\xccta"), "got %s\n", debugstr_an(buffer, io.Information));
1530 /* Test nonblocking mode. */
1532 set_blocking(client, FALSE);
1534 memset(&io, 0, sizeof(io));
1535 memset(buffer, 0xcc, sizeof(buffer));
1536 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1537 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1538 ok(ret == STATUS_DEVICE_NOT_READY, "got %#x\n", ret);
1539 ok(!io.Status, "got status %#lx\n", io.Status);
1540 ok(!io.Information, "got information %#Ix\n", io.Information);
1542 ret = send(server, "data", 5, 0);
1543 ok(ret == 5, "got %d\n", ret);
1545 /* wait for the data to be available */
1546 check_poll_mask(client, event, AFD_POLL_READ, AFD_POLL_READ);
1548 memset(&io, 0xcc, sizeof(io));
1549 memset(buffer, 0xcc, sizeof(buffer));
1550 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1551 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1552 ok(!ret, "got %#x\n", ret);
1553 ok(!io.Status, "got %#lx\n", io.Status);
1554 ok(io.Information == 5, "got %#Ix\n", io.Information);
1555 ok(!strcmp(buffer, "da\xccta"), "got %s\n", debugstr_an(buffer, io.Information));
1557 params.recv_flags = AFD_RECV_FORCE_ASYNC;
1559 memset(&io, 0, sizeof(io));
1560 memset(buffer, 0xcc, sizeof(buffer));
1561 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1562 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1563 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1564 ok(!io.Status, "got status %#lx\n", io.Status);
1565 ok(!io.Information, "got information %#Ix\n", io.Information);
1567 ret = send(server, "data", 5, 0);
1568 ok(ret == 5, "got %d\n", ret);
1570 ret = WaitForSingleObject(event, 200);
1571 ok(!ret, "wait timed out\n");
1572 ok(!io.Status, "got %#lx\n", io.Status);
1573 ok(io.Information == 5, "got %#Ix\n", io.Information);
1574 ok(!strcmp(buffer, "da\xccta"), "got %s\n", debugstr_an(buffer, io.Information));
1576 params.recv_flags = 0;
1578 set_blocking(client, TRUE);
1580 /* Test flags. */
1582 ret = send(server, "a", 1, MSG_OOB);
1583 ok(ret == 1, "got %d\n", ret);
1585 ret = send(server, "data", 5, 0);
1586 ok(ret == 5, "got %d\n", ret);
1588 /* wait for the data to be available */
1589 check_poll_mask(client, event, AFD_POLL_READ, AFD_POLL_READ);
1591 memset(&io, 0xcc, sizeof(io));
1592 memset(buffer, 0xcc, sizeof(buffer));
1593 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1594 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1595 ok(!ret, "got %#x\n", ret);
1596 ok(!io.Status, "got %#lx\n", io.Status);
1597 ok(io.Information == 5, "got %#Ix\n", io.Information);
1598 ok(!strcmp(buffer, "da\xccta"), "got %s\n", debugstr_an(buffer, io.Information));
1600 params.msg_flags = 0;
1602 io.Status = 0xdeadbeef;
1603 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1604 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1605 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
1606 ok(io.Status == 0xdeadbeef, "got %#lx\n", io.Status);
1608 params.msg_flags = AFD_MSG_OOB | AFD_MSG_NOT_OOB;
1610 io.Status = 0xdeadbeef;
1611 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1612 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1613 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
1614 ok(io.Status == 0xdeadbeef, "got %#lx\n", io.Status);
1616 params.msg_flags = AFD_MSG_OOB;
1618 memset(buffer, 0xcc, sizeof(buffer));
1619 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1620 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1621 todo_wine ok(!ret, "got %#x\n", ret);
1622 todo_wine ok(!io.Status, "got %#lx\n", io.Status);
1623 todo_wine ok(io.Information == 1, "got %#Ix\n", io.Information);
1624 todo_wine ok(buffer[0] == 'a', "got %s\n", debugstr_an(buffer, io.Information));
1625 if (ret == STATUS_PENDING)
1627 CancelIo((HANDLE)client);
1628 ret = WaitForSingleObject(event, 100);
1629 ok(!ret, "wait timed out\n");
1632 params.msg_flags = AFD_MSG_NOT_OOB | AFD_MSG_PEEK;
1634 ret = send(server, "data", 4, 0);
1635 ok(ret == 4, "got %d\n", ret);
1637 /* wait for the data to be available */
1638 check_poll_mask(client, event, AFD_POLL_READ, AFD_POLL_READ);
1640 memset(buffer, 0xcc, sizeof(buffer));
1641 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1642 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1643 ok(!ret, "got %#x\n", ret);
1644 ok(!io.Status, "got %#lx\n", io.Status);
1645 ok(io.Information == 4, "got %#Ix\n", io.Information);
1646 ok(!memcmp(buffer, "da\xccta", 5), "got %s\n", debugstr_an(buffer, io.Information));
1648 memset(buffer, 0xcc, sizeof(buffer));
1649 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1650 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1651 ok(!ret, "got %#x\n", ret);
1652 ok(!io.Status, "got %#lx\n", io.Status);
1653 ok(io.Information == 4, "got %#Ix\n", io.Information);
1654 ok(!memcmp(buffer, "da\xccta", 5), "got %s\n", debugstr_an(buffer, io.Information));
1656 params.msg_flags = AFD_MSG_NOT_OOB | AFD_MSG_WAITALL;
1658 memset(buffer, 0xcc, sizeof(buffer));
1659 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1660 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1661 todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
1663 if (ret == STATUS_PENDING)
1665 ret = send(server, "s", 2, 0);
1666 ok(ret == 2, "got %d\n", ret);
1668 ret = WaitForSingleObject(event, 200);
1669 ok(!ret, "wait timed out\n");
1670 ok(!io.Status, "got %#lx\n", io.Status);
1671 ok(io.Information == 6, "got %#Ix\n", io.Information);
1672 ok(!strcmp(buffer, "da\xcctas"), "got %s\n", debugstr_an(buffer, io.Information));
1675 params.msg_flags = AFD_MSG_NOT_OOB;
1677 /* Test shutdown. */
1679 memset(buffer, 0xcc, sizeof(buffer));
1680 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1681 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1682 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1684 closesocket(server);
1686 ret = WaitForSingleObject(event, 200);
1687 ok(!ret, "wait timed out\n");
1688 ok(!io.Status, "got %#lx\n", io.Status);
1689 ok(!io.Information, "got %#Ix\n", io.Information);
1691 ret = shutdown(client, SD_RECEIVE);
1692 ok(!ret, "got error %u\n", WSAGetLastError());
1694 memset(&io, 0, sizeof(io));
1695 memset(buffer, 0xcc, sizeof(buffer));
1696 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1697 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1698 ok(ret == STATUS_PIPE_DISCONNECTED, "got %#x\n", ret);
1699 ok(!io.Status, "got status %#lx\n", io.Status);
1700 ok(!io.Information, "got information %#Ix\n", io.Information);
1702 closesocket(client);
1703 closesocket(listener);
1705 /* Test UDP datagrams. */
1707 client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
1708 server = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
1710 memset(buffer, 0xcc, sizeof(buffer));
1711 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1712 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1713 todo_wine ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
1714 if (ret == STATUS_PENDING)
1715 CancelIo((HANDLE)client);
1717 ret = bind(client, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
1718 ok(!ret, "got error %u\n", WSAGetLastError());
1719 len = sizeof(addr);
1720 ret = getsockname(client, (struct sockaddr *)&addr, &len);
1721 ok(!ret, "got error %u\n", WSAGetLastError());
1723 memset(buffer, 0xcc, sizeof(buffer));
1724 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1725 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1726 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1728 ret = sendto(server, "data", 5, 0, (struct sockaddr *)&addr, sizeof(addr));
1729 ok(ret == 5, "got %d\n", ret);
1731 ret = WaitForSingleObject(event, 200);
1732 ok(!ret, "wait timed out\n");
1733 ok(!io.Status, "got %#lx\n", io.Status);
1734 ok(io.Information == 5, "got %#Ix\n", io.Information);
1735 ok(!strcmp(buffer, "da\xccta"), "got %s\n", debugstr_an(buffer, io.Information));
1737 /* Test a short read of a UDP datagram. */
1739 memset(buffer, 0xcc, sizeof(buffer));
1740 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1741 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1742 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1744 ret = sendto(server, "moredata", 9, 0, (struct sockaddr *)&addr, sizeof(addr));
1745 ok(ret == 9, "got %d\n", ret);
1747 ret = WaitForSingleObject(event, 200);
1748 ok(!ret, "wait timed out\n");
1749 ok(io.Status == STATUS_BUFFER_OVERFLOW, "got %#lx\n", io.Status);
1750 ok(io.Information == 6, "got %#Ix\n", io.Information);
1751 ok(!memcmp(buffer, "mo\xccreda\xcc", 7), "got %s\n", debugstr_an(buffer, io.Information));
1753 ret = sendto(server, "moredata", 9, 0, (struct sockaddr *)&addr, sizeof(addr));
1754 ok(ret == 9, "got %d\n", ret);
1756 /* wait for the data to be available */
1757 check_poll_mask(client, event, AFD_POLL_READ, AFD_POLL_READ);
1759 memset(&io, 0, sizeof(io));
1760 memset(buffer, 0xcc, sizeof(buffer));
1761 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1762 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1763 ok(ret == STATUS_BUFFER_OVERFLOW, "got %#x\n", ret);
1764 ok(io.Status == STATUS_BUFFER_OVERFLOW, "got %#lx\n", io.Status);
1765 ok(io.Information == 6, "got %#Ix\n", io.Information);
1766 ok(!memcmp(buffer, "mo\xccreda\xcc", 7), "got %s\n", debugstr_an(buffer, io.Information));
1768 /* Test closing a socket during an async. */
1770 memset(buffer, 0xcc, sizeof(buffer));
1771 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
1772 IOCTL_AFD_RECV, &params, sizeof(params), NULL, 0);
1773 ok(ret == STATUS_PENDING, "got %#x\n", ret);
1775 closesocket(client);
1777 ret = WaitForSingleObject(event, 200);
1778 ok(!ret, "wait timed out\n");
1779 todo_wine ok(io.Status == STATUS_CANCELLED, "got %#lx\n", io.Status);
1780 ok(!io.Information, "got %#Ix\n", io.Information);
1782 closesocket(server);
1783 CloseHandle(event);
1786 static void test_event_select(void)
1788 struct afd_event_select_params params;
1789 WSANETWORKEVENTS events;
1790 SOCKET client, server;
1791 IO_STATUS_BLOCK io;
1792 HANDLE event;
1793 int ret;
1795 event = CreateEventW(NULL, TRUE, FALSE, NULL);
1797 tcp_socketpair(&client, &server);
1799 memset(&io, 0xcc, sizeof(io));
1800 ret = NtDeviceIoControlFile((HANDLE)client, NULL, NULL, NULL, &io,
1801 IOCTL_AFD_EVENT_SELECT, NULL, 0, NULL, 0);
1802 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
1803 ok(io.Status == STATUS_INVALID_PARAMETER, "got status %#lx\n", io.Status);
1804 ok(!io.Information, "got information %#Ix\n", io.Information);
1806 params.event = 0;
1807 params.mask = ~0;
1808 memset(&io, 0xcc, sizeof(io));
1809 ret = NtDeviceIoControlFile((HANDLE)client, NULL, NULL, NULL, &io,
1810 IOCTL_AFD_EVENT_SELECT, &params, sizeof(params), NULL, 0);
1811 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
1812 ok(io.Status == STATUS_INVALID_PARAMETER, "got status %#lx\n", io.Status);
1813 ok(!io.Information, "got information %#Ix\n", io.Information);
1815 params.event = event;
1816 params.mask = ~0;
1817 memset(&io, 0xcc, sizeof(io));
1818 ret = NtDeviceIoControlFile((HANDLE)client, NULL, NULL, NULL, &io,
1819 IOCTL_AFD_EVENT_SELECT, &params, sizeof(params), NULL, 0);
1820 ok(!ret, "got %#x\n", ret);
1821 ok(!io.Status, "got status %#lx\n", io.Status);
1822 ok(!io.Information, "got information %#Ix\n", io.Information);
1824 ret = WSAEnumNetworkEvents(client, event, &events);
1825 ok(!ret, "got error %u\n", WSAGetLastError());
1826 ok(events.lNetworkEvents == (FD_CONNECT | FD_WRITE), "got events %#lx\n", events.lNetworkEvents);
1828 closesocket(client);
1829 closesocket(server);
1831 tcp_socketpair(&client, &server);
1833 params.event = event;
1834 params.mask = AFD_POLL_CONNECT;
1835 memset(&io, 0xcc, sizeof(io));
1836 ret = NtDeviceIoControlFile((HANDLE)client, NULL, NULL, NULL, &io,
1837 IOCTL_AFD_EVENT_SELECT, &params, sizeof(params), NULL, 0);
1838 ok(!ret, "got %#x\n", ret);
1839 ok(!io.Status, "got status %#lx\n", io.Status);
1840 ok(!io.Information, "got information %#Ix\n", io.Information);
1842 ret = WSAEnumNetworkEvents(client, event, &events);
1843 ok(!ret, "got error %u\n", WSAGetLastError());
1844 ok(events.lNetworkEvents == FD_CONNECT, "got events %#lx\n", events.lNetworkEvents);
1846 closesocket(client);
1847 closesocket(server);
1849 tcp_socketpair(&client, &server);
1851 params.event = event;
1852 params.mask = ~0;
1853 memset(&io, 0xcc, sizeof(io));
1854 ret = NtDeviceIoControlFile((HANDLE)client, NULL, NULL, NULL, &io,
1855 IOCTL_AFD_EVENT_SELECT, &params, sizeof(params), NULL, 0);
1856 ok(!ret, "got %#x\n", ret);
1857 ok(!io.Status, "got status %#lx\n", io.Status);
1858 ok(!io.Information, "got information %#Ix\n", io.Information);
1860 params.event = 0;
1861 params.mask = 0;
1862 memset(&io, 0xcc, sizeof(io));
1863 ret = NtDeviceIoControlFile((HANDLE)client, NULL, NULL, NULL, &io,
1864 IOCTL_AFD_EVENT_SELECT, &params, sizeof(params), NULL, 0);
1865 ok(!ret, "got %#x\n", ret);
1866 ok(!io.Status, "got status %#lx\n", io.Status);
1867 ok(!io.Information, "got information %#Ix\n", io.Information);
1869 ret = WSAEnumNetworkEvents(client, event, &events);
1870 ok(!ret, "got error %u\n", WSAGetLastError());
1871 ok(!events.lNetworkEvents, "got events %#lx\n", events.lNetworkEvents);
1873 closesocket(client);
1874 closesocket(server);
1876 CloseHandle(event);
1879 static void test_get_events(void)
1881 const struct sockaddr_in invalid_addr =
1883 .sin_family = AF_INET,
1884 .sin_addr.s_addr = htonl(INADDR_LOOPBACK),
1885 .sin_port = 255,
1887 struct afd_get_events_params params;
1888 WSANETWORKEVENTS events;
1889 SOCKET client, server;
1890 IO_STATUS_BLOCK io;
1891 unsigned int i;
1892 HANDLE event;
1893 int ret;
1895 event = CreateEventW(NULL, TRUE, FALSE, NULL);
1897 tcp_socketpair(&client, &server);
1899 ret = WSAEventSelect(client, event, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
1900 ok(!ret, "got error %lu\n", GetLastError());
1902 memset(&params, 0xcc, sizeof(params));
1903 memset(&io, 0xcc, sizeof(io));
1904 ret = NtDeviceIoControlFile((HANDLE)client, NULL, NULL, NULL, &io,
1905 IOCTL_AFD_GET_EVENTS, NULL, 0, NULL, 0);
1906 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
1908 memset(&params, 0xcc, sizeof(params));
1909 memset(&io, 0xcc, sizeof(io));
1910 ret = NtDeviceIoControlFile((HANDLE)client, NULL, NULL, NULL, &io,
1911 IOCTL_AFD_GET_EVENTS, NULL, 0, &params, sizeof(params));
1912 ok(!ret, "got %#x\n", ret);
1913 ok(params.flags == (AFD_POLL_WRITE | AFD_POLL_CONNECT), "got flags %#x\n", params.flags);
1914 for (i = 0; i < ARRAY_SIZE(params.status); ++i)
1915 ok(!params.status[i], "got status[%u] %#x\n", i, params.status[i]);
1917 ret = WSAEnumNetworkEvents(client, event, &events);
1918 ok(!ret, "got error %lu\n", GetLastError());
1919 ok(!events.lNetworkEvents, "got events %#lx\n", events.lNetworkEvents);
1921 ret = WSAEventSelect(server, event, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
1922 ok(!ret, "got error %lu\n", GetLastError());
1924 memset(&params, 0xcc, sizeof(params));
1925 memset(&io, 0xcc, sizeof(io));
1926 ret = NtDeviceIoControlFile((HANDLE)server, NULL, NULL, NULL, &io,
1927 IOCTL_AFD_GET_EVENTS, NULL, 0, &params, sizeof(params));
1928 ok(!ret, "got %#x\n", ret);
1929 ok(params.flags == AFD_POLL_WRITE, "got flags %#x\n", params.flags);
1930 for (i = 0; i < ARRAY_SIZE(params.status); ++i)
1931 ok(!params.status[i], "got status[%u] %#x\n", i, params.status[i]);
1933 closesocket(client);
1934 closesocket(server);
1936 tcp_socketpair(&client, &server);
1938 ret = WSAEventSelect(client, event, FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_OOB | FD_READ | FD_WRITE);
1939 ok(!ret, "got error %lu\n", GetLastError());
1941 ret = WSAEnumNetworkEvents(client, event, &events);
1942 ok(!ret, "got error %lu\n", GetLastError());
1943 ok(events.lNetworkEvents == (FD_WRITE | FD_CONNECT), "got events %#lx\n", events.lNetworkEvents);
1945 memset(&params, 0xcc, sizeof(params));
1946 memset(&io, 0xcc, sizeof(io));
1947 ret = NtDeviceIoControlFile((HANDLE)client, NULL, NULL, NULL, &io,
1948 IOCTL_AFD_GET_EVENTS, NULL, 0, &params, sizeof(params));
1949 ok(!ret, "got %#x\n", ret);
1950 ok(!params.flags, "got flags %#x\n", params.flags);
1951 for (i = 0; i < ARRAY_SIZE(params.status); ++i)
1952 ok(!params.status[i], "got status[%u] %#x\n", i, params.status[i]);
1954 closesocket(client);
1955 closesocket(server);
1957 /* Test a failed connection. The following call can take over 2 seconds to
1958 * complete, so make the test interactive-only. */
1960 if (winetest_interactive)
1962 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1964 ResetEvent(event);
1965 ret = WSAEventSelect(client, event, FD_CONNECT);
1966 ok(!ret, "got error %lu\n", GetLastError());
1968 ret = connect(client, (struct sockaddr *)&invalid_addr, sizeof(invalid_addr));
1969 ok(ret == -1, "expected failure\n");
1970 ok(WSAGetLastError() == WSAEWOULDBLOCK, "got error %u\n", WSAGetLastError());
1972 ret = WaitForSingleObject(event, 10000);
1973 ok(!ret, "got %#x\n", ret);
1975 memset(&params, 0xcc, sizeof(params));
1976 memset(&io, 0xcc, sizeof(io));
1977 ret = NtDeviceIoControlFile((HANDLE)client, NULL, NULL, NULL, &io,
1978 IOCTL_AFD_GET_EVENTS, NULL, 0, &params, sizeof(params));
1979 ok(!ret, "got %#x\n", ret);
1980 ok(params.flags == AFD_POLL_CONNECT_ERR, "got flags %#x\n", params.flags);
1981 for (i = 0; i < ARRAY_SIZE(params.status); ++i)
1983 if (i == AFD_POLL_BIT_CONNECT_ERR)
1984 ok(params.status[i] == STATUS_CONNECTION_REFUSED, "got status[%u] %#x\n", i, params.status[i]);
1985 else
1986 ok(!params.status[i], "got status[%u] %#x\n", i, params.status[i]);
1989 ResetEvent(event);
1990 ret = WSAEventSelect(client, event, FD_CONNECT);
1991 ok(!ret, "got error %lu\n", GetLastError());
1993 ret = WaitForSingleObject(event, 0);
1994 ok(ret == WAIT_TIMEOUT, "got %#x\n", ret);
1996 memset(&params, 0xcc, sizeof(params));
1997 memset(&io, 0xcc, sizeof(io));
1998 ret = NtDeviceIoControlFile((HANDLE)client, NULL, NULL, NULL, &io,
1999 IOCTL_AFD_GET_EVENTS, NULL, 0, &params, sizeof(params));
2000 ok(!ret, "got %#x\n", ret);
2001 ok(!params.flags, "got flags %#x\n", params.flags);
2002 for (i = 0; i < ARRAY_SIZE(params.status); ++i)
2004 if (i == AFD_POLL_BIT_CONNECT_ERR)
2005 ok(params.status[i] == STATUS_CONNECTION_REFUSED, "got status[%u] %#x\n", i, params.status[i]);
2006 else
2007 ok(!params.status[i], "got status[%u] %#x\n", i, params.status[i]);
2010 closesocket(client);
2013 CloseHandle(event);
2016 static void test_get_events_reset(void)
2018 struct afd_get_events_params params;
2019 SOCKET client, server;
2020 IO_STATUS_BLOCK io;
2021 unsigned int i;
2022 HANDLE event;
2023 int ret;
2025 event = CreateEventW(NULL, TRUE, FALSE, NULL);
2027 tcp_socketpair(&client, &server);
2029 ret = WSAEventSelect(client, event, FD_ACCEPT | FD_CONNECT | FD_CLOSE | FD_OOB | FD_READ | FD_WRITE);
2030 ok(!ret, "got error %lu\n", GetLastError());
2032 close_with_rst(server);
2034 memset(&params, 0xcc, sizeof(params));
2035 memset(&io, 0xcc, sizeof(io));
2036 ret = NtDeviceIoControlFile((HANDLE)client, NULL, NULL, NULL, &io,
2037 IOCTL_AFD_GET_EVENTS, NULL, 0, &params, sizeof(params));
2038 ok(!ret, "got %#x\n", ret);
2039 ok(params.flags == (AFD_POLL_RESET | AFD_POLL_CONNECT | AFD_POLL_WRITE), "got flags %#x\n", params.flags);
2040 for (i = 0; i < ARRAY_SIZE(params.status); ++i)
2041 ok(!params.status[i], "got status[%u] %#x\n", i, params.status[i]);
2043 closesocket(client);
2045 tcp_socketpair(&client, &server);
2047 ret = WSAEventSelect(server, event, FD_ACCEPT | FD_CONNECT | FD_CLOSE | FD_OOB | FD_READ | FD_WRITE);
2048 ok(!ret, "got error %lu\n", GetLastError());
2050 close_with_rst(client);
2052 memset(&params, 0xcc, sizeof(params));
2053 memset(&io, 0xcc, sizeof(io));
2054 ret = NtDeviceIoControlFile((HANDLE)server, NULL, NULL, NULL, &io,
2055 IOCTL_AFD_GET_EVENTS, NULL, 0, &params, sizeof(params));
2056 ok(!ret, "got %#x\n", ret);
2057 ok(params.flags == (AFD_POLL_RESET | AFD_POLL_WRITE), "got flags %#x\n", params.flags);
2058 for (i = 0; i < ARRAY_SIZE(params.status); ++i)
2059 ok(!params.status[i], "got status[%u] %#x\n", i, params.status[i]);
2061 closesocket(server);
2063 CloseHandle(event);
2066 static void test_bind(void)
2068 const struct sockaddr_in6 bind_addr6 = {.sin6_family = AF_INET6, .sin6_addr.s6_words = {0, 0, 0, 0, 0, 0, 0, htons(1)}};
2069 const struct sockaddr_in6 invalid_addr6 = {.sin6_family = AF_INET6, .sin6_addr.s6_words = {htons(0x0100)}};
2070 const struct sockaddr_in invalid_addr = {.sin_family = AF_INET, .sin_addr.s_addr = inet_addr("192.0.2.0")};
2071 const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
2072 static const size_t params6_size = offsetof(struct afd_bind_params, addr) + sizeof(struct sockaddr_in6);
2073 static const size_t params4_size = offsetof(struct afd_bind_params, addr) + sizeof(struct sockaddr_in);
2074 struct afd_bind_params *params = malloc(params6_size);
2075 struct sockaddr_in6 addr6, addr6_2;
2076 struct sockaddr_in addr, addr2;
2077 struct hostent *host;
2078 IO_STATUS_BLOCK io;
2079 unsigned int i;
2080 HANDLE event;
2081 SOCKET s, s2;
2082 int ret;
2084 event = CreateEventW(NULL, TRUE, FALSE, NULL);
2085 memset(&addr, 0xcc, sizeof(addr));
2086 memset(params, 0, params6_size);
2088 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
2090 params->addr.sa_family = 0xdead;
2091 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
2092 params, params4_size, &addr, sizeof(addr));
2093 ok(ret == STATUS_INVALID_ADDRESS, "got %#x\n", ret);
2095 memcpy(&params->addr, &bind_addr, sizeof(bind_addr));
2096 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
2097 params, params4_size - 1, &addr, sizeof(addr));
2098 ok(ret == STATUS_INVALID_ADDRESS, "got %#x\n", ret);
2100 memcpy(&params->addr, &bind_addr, sizeof(bind_addr));
2101 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
2102 params, offsetof(struct afd_bind_params, addr.sa_data), &addr, sizeof(addr));
2103 ok(ret == STATUS_INVALID_ADDRESS, "got %#x\n", ret);
2105 memcpy(&params->addr, &bind_addr, sizeof(bind_addr));
2106 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
2107 params, offsetof(struct afd_bind_params, addr.sa_data) - 1, &addr, sizeof(addr));
2108 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
2110 memcpy(&params->addr, &invalid_addr, sizeof(invalid_addr));
2111 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
2112 params, params4_size, &addr, sizeof(addr));
2113 todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
2114 ret = WaitForSingleObject(event, 0);
2115 ok(!ret, "got %#x\n", ret);
2116 ok(io.Status == STATUS_INVALID_ADDRESS_COMPONENT, "got %#lx\n", io.Status);
2118 memcpy(&params->addr, &bind_addr, sizeof(bind_addr));
2119 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
2120 params, params4_size, &addr, sizeof(addr) - 1);
2121 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
2123 memcpy(&params->addr, &bind_addr, sizeof(bind_addr));
2124 memset(&io, 0xcc, sizeof(io));
2125 memset(&addr, 0xcc, sizeof(addr));
2126 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
2127 params, params4_size, &addr, sizeof(addr));
2128 todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
2129 ret = WaitForSingleObject(event, 0);
2130 ok(!ret, "got %#x\n", ret);
2131 ok(!io.Status, "got %#lx\n", io.Status);
2132 ok(io.Information == sizeof(addr), "got %#Ix\n", io.Information);
2133 ok(addr.sin_family == AF_INET, "got family %u\n", addr.sin_family);
2134 ok(addr.sin_addr.s_addr == htonl(INADDR_LOOPBACK), "got address %#08lx\n", addr.sin_addr.s_addr);
2135 ok(addr.sin_port, "expected nonzero port\n");
2137 /* getsockname() returns EINVAL here. Possibly the socket name is cached (in shared memory?) */
2138 memset(&addr2, 0xcc, sizeof(addr2));
2139 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io,
2140 IOCTL_AFD_GETSOCKNAME, NULL, 0, &addr2, sizeof(addr2));
2141 ok(!ret, "got %#x\n", ret);
2142 ok(!memcmp(&addr, &addr2, sizeof(addr)), "addresses didn't match\n");
2144 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
2145 params, params4_size, &addr, sizeof(addr));
2146 ok(ret == STATUS_ADDRESS_ALREADY_ASSOCIATED, "got %#x\n", ret);
2148 s2 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
2150 memcpy(&params->addr, &addr2, sizeof(addr2));
2151 memset(&io, 0xcc, sizeof(io));
2152 memset(&addr, 0xcc, sizeof(addr));
2153 ret = NtDeviceIoControlFile((HANDLE)s2, event, NULL, NULL, &io, IOCTL_AFD_BIND,
2154 params, params4_size, &addr, sizeof(addr));
2155 todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
2156 ret = WaitForSingleObject(event, 0);
2157 ok(!ret, "got %#x\n", ret);
2158 ok(io.Status == STATUS_SHARING_VIOLATION, "got %#lx\n", io.Status);
2159 ok(!io.Information, "got %#Ix\n", io.Information);
2161 closesocket(s2);
2162 closesocket(s);
2164 /* test UDP */
2166 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
2168 memcpy(&params->addr, &bind_addr, sizeof(bind_addr));
2169 memset(&io, 0xcc, sizeof(io));
2170 memset(&addr, 0xcc, sizeof(addr));
2171 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
2172 params, params4_size, &addr, sizeof(addr));
2173 todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
2174 ret = WaitForSingleObject(event, 0);
2175 ok(!ret, "got %#x\n", ret);
2176 ok(!io.Status, "got %#lx\n", io.Status);
2177 ok(io.Information == sizeof(addr), "got %#Ix\n", io.Information);
2178 ok(addr.sin_family == AF_INET, "got family %u\n", addr.sin_family);
2179 ok(addr.sin_addr.s_addr == htonl(INADDR_LOOPBACK), "got address %#08lx\n", addr.sin_addr.s_addr);
2180 ok(addr.sin_port, "expected nonzero port\n");
2182 memset(&addr2, 0xcc, sizeof(addr2));
2183 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io,
2184 IOCTL_AFD_GETSOCKNAME, NULL, 0, &addr2, sizeof(addr2));
2185 ok(!ret, "got %#x\n", ret);
2186 ok(!memcmp(&addr, &addr2, sizeof(addr)), "addresses didn't match\n");
2188 closesocket(s);
2190 host = gethostbyname("");
2191 if (host && host->h_length == 4)
2193 for (i = 0; host->h_addr_list[i]; ++i)
2195 ULONG in_addr = *(ULONG *)host->h_addr_list[i];
2197 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
2199 ((struct sockaddr_in *)&params->addr)->sin_addr.s_addr = in_addr;
2200 memset(&io, 0xcc, sizeof(io));
2201 memset(&addr, 0xcc, sizeof(addr));
2202 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
2203 params, params4_size, &addr, sizeof(addr));
2204 todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
2205 ret = WaitForSingleObject(event, 0);
2206 ok(!ret, "got %#x\n", ret);
2207 ok(!io.Status, "got %#lx\n", io.Status);
2208 ok(io.Information == sizeof(addr), "got %#Ix\n", io.Information);
2209 ok(addr.sin_family == AF_INET, "got family %u\n", addr.sin_family);
2210 ok(addr.sin_addr.s_addr == in_addr, "expected address %#08lx, got %#08lx\n", in_addr, addr.sin_addr.s_addr);
2211 ok(addr.sin_port, "expected nonzero port\n");
2213 memset(&addr2, 0xcc, sizeof(addr2));
2214 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io,
2215 IOCTL_AFD_GETSOCKNAME, NULL, 0, &addr2, sizeof(addr2));
2216 ok(!ret, "got %#x\n", ret);
2217 ok(!memcmp(&addr, &addr2, sizeof(addr)), "addresses didn't match\n");
2219 closesocket(s);
2223 /* test IPv6 */
2225 s = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
2226 ok(s != -1, "failed to create IPv6 socket\n");
2228 params->addr.sa_family = 0xdead;
2229 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
2230 params, params6_size, &addr6, sizeof(addr6));
2231 ok(ret == STATUS_INVALID_ADDRESS, "got %#x\n", ret);
2233 memcpy(&params->addr, &bind_addr6, sizeof(bind_addr6));
2234 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
2235 params, params6_size - 1, &addr6, sizeof(addr6));
2236 ok(ret == STATUS_INVALID_ADDRESS, "got %#x\n", ret);
2238 memcpy(&params->addr, &bind_addr6, sizeof(bind_addr6));
2239 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
2240 params, offsetof(struct afd_bind_params, addr) + sizeof(struct sockaddr_in6_old), &addr6, sizeof(addr6));
2241 ok(ret == STATUS_INVALID_ADDRESS, "got %#x\n", ret);
2243 memcpy(&params->addr, &bind_addr6, sizeof(bind_addr6));
2244 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
2245 params, offsetof(struct afd_bind_params, addr.sa_data), &addr6, sizeof(addr6));
2246 ok(ret == STATUS_INVALID_ADDRESS, "got %#x\n", ret);
2248 memcpy(&params->addr, &bind_addr6, sizeof(bind_addr6));
2249 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
2250 params, offsetof(struct afd_bind_params, addr.sa_data) - 1, &addr6, sizeof(addr6));
2251 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
2253 memcpy(&params->addr, &invalid_addr6, sizeof(invalid_addr6));
2254 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
2255 params, params6_size, &addr6, sizeof(addr6));
2256 todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
2257 ret = WaitForSingleObject(event, 0);
2258 ok(!ret, "got %#x\n", ret);
2259 ok(io.Status == STATUS_INVALID_ADDRESS_COMPONENT, "got %#lx\n", io.Status);
2261 memcpy(&params->addr, &bind_addr6, sizeof(bind_addr6));
2262 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
2263 params, params6_size, &addr6, sizeof(addr6) - 1);
2264 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
2266 memcpy(&params->addr, &bind_addr6, sizeof(bind_addr6));
2267 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
2268 params, params6_size - 1, &addr6, sizeof(addr6) - 1);
2269 ok(ret == STATUS_INVALID_ADDRESS, "got %#x\n", ret);
2271 memcpy(&params->addr, &bind_addr6, sizeof(bind_addr6));
2272 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
2273 params, params6_size, &addr6, sizeof(struct sockaddr_in6_old));
2274 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
2276 memcpy(&params->addr, &bind_addr6, sizeof(bind_addr6));
2277 memset(&io, 0xcc, sizeof(io));
2278 memset(&addr6, 0xcc, sizeof(addr6));
2279 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
2280 params, params6_size, &addr6, sizeof(addr6));
2281 todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
2282 ret = WaitForSingleObject(event, 0);
2283 ok(!ret, "got %#x\n", ret);
2284 if (io.Status == STATUS_INVALID_ADDRESS_COMPONENT)
2286 skip("IPv6 not supported\n");
2287 closesocket(s);
2288 goto cleanup;
2290 ok(!io.Status, "got %#lx\n", io.Status);
2291 ok(io.Information == sizeof(addr6), "got %#Ix\n", io.Information);
2292 ok(addr6.sin6_family == AF_INET6, "got family %u\n", addr6.sin6_family);
2293 ok(!memcmp(&addr6.sin6_addr, &bind_addr6.sin6_addr, sizeof(addr6.sin6_addr)), "address didn't match\n");
2294 ok(!addr6.sin6_flowinfo, "got flow info %#lx\n", addr6.sin6_flowinfo);
2295 ok(addr6.sin6_port, "expected nonzero port\n");
2297 /* getsockname() returns EINVAL here. Possibly the socket name is cached (in shared memory?) */
2298 memset(&addr6_2, 0xcc, sizeof(addr6_2));
2299 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io,
2300 IOCTL_AFD_GETSOCKNAME, NULL, 0, &addr6_2, sizeof(addr6_2));
2301 ok(!ret, "got %#x\n", ret);
2302 ok(!memcmp(&addr6, &addr6_2, sizeof(addr6)), "addresses didn't match\n");
2304 ret = NtDeviceIoControlFile((HANDLE)s, event, NULL, NULL, &io, IOCTL_AFD_BIND,
2305 params, params6_size, &addr6, sizeof(addr6));
2306 ok(ret == STATUS_ADDRESS_ALREADY_ASSOCIATED, "got %#x\n", ret);
2308 s2 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
2310 memcpy(&params->addr, &addr6_2, sizeof(addr6_2));
2311 memset(&io, 0xcc, sizeof(io));
2312 memset(&addr6, 0xcc, sizeof(addr6));
2313 ret = NtDeviceIoControlFile((HANDLE)s2, event, NULL, NULL, &io, IOCTL_AFD_BIND,
2314 params, params6_size, &addr6, sizeof(addr6));
2315 todo_wine ok(ret == STATUS_PENDING, "got %#x\n", ret);
2316 ret = WaitForSingleObject(event, 0);
2317 ok(!ret, "got %#x\n", ret);
2318 ok(io.Status == STATUS_SHARING_VIOLATION, "got %#lx\n", io.Status);
2319 ok(!io.Information, "got %#Ix\n", io.Information);
2321 closesocket(s2);
2322 closesocket(s);
2324 cleanup:
2325 CloseHandle(event);
2326 free(params);
2329 static void test_getsockname(void)
2331 const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
2332 struct sockaddr addr, addr2;
2333 SOCKET server, client;
2334 IO_STATUS_BLOCK io;
2335 HANDLE event;
2336 int ret, len;
2338 event = CreateEventW(NULL, TRUE, FALSE, NULL);
2340 tcp_socketpair(&client, &server);
2342 memset(&addr, 0xcc, sizeof(addr));
2343 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
2344 IOCTL_AFD_GETSOCKNAME, NULL, 0, &addr, sizeof(addr) - 1);
2345 ok(ret == STATUS_BUFFER_TOO_SMALL, "got %#x\n", ret);
2347 memset(&io, 0xcc, sizeof(io));
2348 memset(&addr, 0xcc, sizeof(addr));
2349 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
2350 IOCTL_AFD_GETSOCKNAME, NULL, 0, &addr, sizeof(addr));
2351 ok(!ret, "got %#x\n", ret);
2352 ok(!io.Status, "got %#lx\n", io.Status);
2353 ok(io.Information == sizeof(addr), "got %#Ix\n", io.Information);
2354 len = sizeof(addr2);
2355 ret = getsockname(client, (struct sockaddr *)&addr2, &len);
2356 ok(!ret, "got error %u\n", WSAGetLastError());
2357 ok(!memcmp(&addr, &addr2, sizeof(struct sockaddr)), "addresses didn't match\n");
2359 memset(&io, 0xcc, sizeof(io));
2360 memset(&addr, 0xcc, sizeof(addr));
2361 ret = NtDeviceIoControlFile((HANDLE)server, event, NULL, NULL, &io,
2362 IOCTL_AFD_GETSOCKNAME, NULL, 0, &addr, sizeof(addr));
2363 ok(!ret, "got %#x\n", ret);
2364 ok(!io.Status, "got %#lx\n", io.Status);
2365 ok(io.Information == sizeof(addr), "got %#Ix\n", io.Information);
2366 len = sizeof(addr2);
2367 ret = getsockname(server, (struct sockaddr *)&addr2, &len);
2368 ok(!ret, "got error %u\n", WSAGetLastError());
2369 ok(!memcmp(&addr, &addr2, sizeof(struct sockaddr)), "addresses didn't match\n");
2371 closesocket(server);
2372 closesocket(client);
2374 client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
2376 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
2377 IOCTL_AFD_GETSOCKNAME, NULL, 0, &addr, sizeof(addr));
2378 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
2380 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
2381 IOCTL_AFD_GETSOCKNAME, NULL, 0, &addr, sizeof(addr) - 1);
2382 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
2384 ret = bind(client, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
2385 ok(!ret, "got error %u\n", WSAGetLastError());
2387 memset(&io, 0xcc, sizeof(io));
2388 memset(&addr, 0xcc, sizeof(addr));
2389 ret = NtDeviceIoControlFile((HANDLE)client, event, NULL, NULL, &io,
2390 IOCTL_AFD_GETSOCKNAME, NULL, 0, &addr, sizeof(addr));
2391 ok(!ret, "got %#x\n", ret);
2392 ok(!io.Status, "got %#lx\n", io.Status);
2393 ok(io.Information == sizeof(addr), "got %#Ix\n", io.Information);
2394 len = sizeof(addr2);
2395 ret = getsockname(client, (struct sockaddr *)&addr2, &len);
2396 ok(!ret, "got error %u\n", WSAGetLastError());
2397 ok(!memcmp(&addr, &addr2, sizeof(struct sockaddr)), "addresses didn't match\n");
2399 closesocket(client);
2401 CloseHandle(event);
2404 struct ioctl_params
2406 HANDLE handle, event;
2407 PIO_APC_ROUTINE apc;
2408 void *apc_context;
2409 IO_STATUS_BLOCK *io;
2410 ULONG code;
2411 void *in_buffer;
2412 ULONG in_size;
2413 void *out_buffer;
2414 ULONG out_size;
2415 NTSTATUS ret;
2416 HANDLE complete_event;
2417 BOOL kill_thread;
2420 static DWORD WINAPI async_ioctl_thread(void *params)
2422 struct ioctl_params *io = params;
2424 io->ret = NtDeviceIoControlFile(io->handle, io->event, io->apc, io->apc_context, io->io,
2425 io->code, io->in_buffer, io->in_size, io->out_buffer, io->out_size);
2426 SetEvent(io->complete_event);
2427 if (io->kill_thread)
2428 Sleep(3000);
2429 return io->ret;
2432 static NTSTATUS WINAPI thread_NtDeviceIoControlFile(BOOL kill_thread, HANDLE handle, HANDLE event,
2433 PIO_APC_ROUTINE apc, void *apc_context, IO_STATUS_BLOCK *io, ULONG code, void *in_buffer, ULONG in_size,
2434 void *out_buffer, ULONG out_size)
2436 struct ioctl_params p;
2437 HANDLE thread;
2438 DWORD ret;
2440 p.handle = handle;
2441 p.event = event;
2442 p.apc = apc;
2443 p.apc_context = apc_context;
2444 p.io = io;
2445 p.code = code;
2446 p.in_buffer = in_buffer;
2447 p.in_size = in_size;
2448 p.out_buffer = out_buffer;
2449 p.out_size = out_size;
2450 p.complete_event = CreateEventW(NULL, FALSE, FALSE, NULL);
2451 p.kill_thread = kill_thread;
2453 thread = CreateThread(NULL, 0, async_ioctl_thread, &p, 0, NULL);
2454 ok(!!thread, "got NULL.\n");
2455 ret = WaitForSingleObject(p.complete_event, INFINITE);
2456 ok(ret == WAIT_OBJECT_0, "got ret %#lx.\n", ret);
2457 if (kill_thread)
2458 TerminateThread(thread, -1);
2459 CloseHandle(p.complete_event);
2460 ret = WaitForSingleObject(thread, INFINITE);
2461 ok(ret == WAIT_OBJECT_0, "got ret %#lx.\n", ret);
2462 CloseHandle(thread);
2463 SleepEx(0, TRUE);
2464 return p.ret;
2467 static unsigned int test_async_thread_termination_apc_count;
2469 static void WINAPI test_async_thread_termination_apc( void *arg, IO_STATUS_BLOCK *iosb, ULONG reserved )
2471 ++test_async_thread_termination_apc_count;
2474 static void test_async_thread_termination(void)
2476 static const struct
2478 BOOL kill_thread;
2479 BOOL event;
2480 PIO_APC_ROUTINE apc;
2481 void *apc_context;
2483 tests[] =
2485 {FALSE, TRUE, NULL, NULL},
2486 {TRUE, TRUE, NULL, NULL},
2487 {FALSE, FALSE, NULL, NULL},
2488 {TRUE, FALSE, NULL, NULL},
2489 {FALSE, TRUE, test_async_thread_termination_apc, NULL},
2490 {TRUE, TRUE, test_async_thread_termination_apc, NULL},
2491 {FALSE, FALSE, test_async_thread_termination_apc, NULL},
2492 {TRUE, FALSE, test_async_thread_termination_apc, NULL},
2493 {FALSE, TRUE, NULL, (void *)0xdeadbeef},
2494 {TRUE, TRUE, NULL, (void *)0xdeadbeef},
2495 {FALSE, FALSE, NULL, (void *)0xdeadbeef},
2496 {TRUE, FALSE, NULL, (void *)0xdeadbeef},
2497 {FALSE, TRUE, test_async_thread_termination_apc, (void *)0xdeadbeef},
2498 {TRUE, TRUE, test_async_thread_termination_apc, (void *)0xdeadbeef},
2499 {FALSE, FALSE, test_async_thread_termination_apc, (void *)0xdeadbeef},
2500 {TRUE, FALSE, test_async_thread_termination_apc, (void *)0xdeadbeef},
2503 const struct sockaddr_in bind_addr = {.sin_family = AF_INET, .sin_addr.s_addr = htonl(INADDR_LOOPBACK)};
2504 char in_buffer[offsetof(struct afd_poll_params, sockets[3])];
2505 char out_buffer[offsetof(struct afd_poll_params, sockets[3])];
2506 struct afd_poll_params *in_params = (struct afd_poll_params *)in_buffer;
2507 struct afd_poll_params *out_params = (struct afd_poll_params *)out_buffer;
2508 LARGE_INTEGER zero = {{0}};
2509 ULONG_PTR key, value;
2510 IO_STATUS_BLOCK io;
2511 HANDLE event, port;
2512 ULONG params_size;
2513 SOCKET listener;
2514 unsigned int i;
2515 int ret;
2517 event = CreateEventW(NULL, FALSE, FALSE, NULL);
2519 listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
2520 ret = bind(listener, (const struct sockaddr *)&bind_addr, sizeof(bind_addr));
2521 ok(!ret, "got error %u\n", WSAGetLastError());
2522 ret = listen(listener, 1);
2523 ok(!ret, "got error %u\n", WSAGetLastError());
2525 in_params->count = 1;
2526 in_params->exclusive = FALSE;
2527 in_params->sockets[0].socket = listener;
2528 in_params->sockets[0].flags = ~0;
2529 in_params->sockets[0].status = 0xdeadbeef;
2530 params_size = offsetof(struct afd_poll_params, sockets[1]);
2531 in_params->timeout = -10 * 1000 * 1000 * 5;
2533 /* asyncs without completion port are always cancelled on thread exit. */
2534 for (i = 0; i < ARRAY_SIZE(tests); ++i)
2536 winetest_push_context("test %u", i);
2537 memset(&io, 0xcc, sizeof(io));
2538 ResetEvent(event);
2539 ret = thread_NtDeviceIoControlFile(tests[i].kill_thread, (HANDLE)listener, tests[i].event ? event : NULL,
2540 tests[i].apc, tests[i].apc_context, &io, IOCTL_AFD_POLL, in_params, params_size,
2541 out_params, params_size);
2542 ok(ret == STATUS_PENDING, "got %#x\n", ret);
2543 ok(io.Status == STATUS_CANCELLED, "got %#lx\n", io.Status);
2544 if (tests[i].event)
2546 ret = WaitForSingleObject(event, 1000);
2547 ok(!ret, "got %#x\n", ret);
2549 winetest_pop_context();
2552 SleepEx(0, TRUE);
2553 ok(!test_async_thread_termination_apc_count, "got APC.\n");
2555 port = CreateIoCompletionPort((HANDLE)listener, NULL, 0, 0);
2557 for (i = 0; i < ARRAY_SIZE(tests); ++i)
2559 winetest_push_context("test %u", i);
2560 memset(&io, 0xcc, sizeof(io));
2561 ResetEvent(event);
2562 ret = thread_NtDeviceIoControlFile(tests[i].kill_thread, (HANDLE)listener, tests[i].event ? event : NULL,
2563 tests[i].apc, tests[i].apc_context, &io, IOCTL_AFD_POLL, in_params, params_size,
2564 out_params, params_size);
2565 if (tests[i].apc)
2567 ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
2568 winetest_pop_context();
2569 continue;
2571 ok(ret == STATUS_PENDING, "got %#x\n", ret);
2572 if (!tests[i].apc_context || tests[i].event)
2574 ok(io.Status == STATUS_CANCELLED, "got %#lx\n", io.Status);
2575 memset(&io, 0xcc, sizeof(io));
2576 key = 0xcc;
2577 value = 0;
2578 ret = NtRemoveIoCompletion(port, &key, &value, &io, &zero);
2579 if (tests[i].apc_context)
2581 ok(!ret, "got %#x\n", ret);
2582 ok(!key, "got key %#Ix\n", key);
2583 ok(value == 0xdeadbeef, "got value %#Ix\n", value);
2584 ok(io.Status == STATUS_CANCELLED, "got %#lx\n", io.Status);
2586 else
2588 ok(ret == WAIT_TIMEOUT, "got %#x\n", ret);
2590 winetest_pop_context();
2591 continue;
2594 /* async is not cancelled if there is a completion port, completion key and no event. */
2595 ok(io.Status == 0xcccccccc, "got %#lx\n", io.Status);
2596 memset(&io, 0xcc, sizeof(io));
2597 key = 0xcc;
2598 value = 0;
2599 ret = NtRemoveIoCompletion(port, &key, &value, &io, &zero);
2600 ok(ret == WAIT_TIMEOUT, "got %#x\n", ret);
2601 CancelIoEx((HANDLE)listener, NULL);
2602 ret = NtRemoveIoCompletion(port, &key, &value, &io, &zero);
2603 ok(!ret, "got %#x\n", ret);
2604 ok(!key, "got key %#Ix\n", key);
2605 ok(value == 0xdeadbeef, "got value %#Ix\n", value);
2606 ok(io.Status == STATUS_CANCELLED, "got %#lx\n", io.Status);
2607 winetest_pop_context();
2610 CloseHandle(port);
2611 CloseHandle(event);
2612 closesocket(listener);
2615 static DWORD WINAPI sync_read_file_thread(void *arg)
2617 HANDLE server = arg;
2618 IO_STATUS_BLOCK io;
2619 char buffer[5];
2620 NTSTATUS ret;
2622 memset(buffer, 0xcc, sizeof(buffer));
2623 memset(&io, 0xcc, sizeof(io));
2624 ret = NtReadFile(server, NULL, NULL, NULL, &io, buffer, sizeof(buffer), NULL, NULL);
2625 ok(!ret, "got status %#lx\n", ret);
2626 ok(!io.Status, "got status %#lx\n", io.Status);
2627 ok(io.Information == 4, "got size %Iu\n", io.Information);
2628 ok(!memcmp(buffer, "data", 4), "got data %s\n", debugstr_an(buffer, io.Information));
2630 return 0;
2633 static void test_read_write(void)
2635 WSANETWORKEVENTS events;
2636 IO_STATUS_BLOCK io, io2;
2637 SOCKET client, server;
2638 LARGE_INTEGER offset;
2639 HANDLE event, thread;
2640 char buffer[5];
2641 NTSTATUS ret;
2643 event = CreateEventA(NULL, TRUE, FALSE, NULL);
2645 tcp_socketpair_flags(&client, &server, 0);
2646 set_blocking(server, FALSE);
2648 memset(&io, 0xcc, sizeof(io));
2649 ret = NtWriteFile((HANDLE)client, NULL, NULL, NULL, &io, "data", 4, NULL, NULL);
2650 ok(!ret, "got status %#lx\n", ret);
2651 ok(!io.Status, "got status %#lx\n", io.Status);
2652 ok(io.Information == 4, "got size %Iu\n", io.Information);
2654 memset(buffer, 0xcc, sizeof(buffer));
2655 memset(&io, 0xcc, sizeof(io));
2656 ret = NtReadFile((HANDLE)server, NULL, NULL, NULL, &io, buffer, sizeof(buffer), NULL, NULL);
2657 ok(!ret, "got status %#lx\n", ret);
2658 ok(!io.Status, "got status %#lx\n", io.Status);
2659 ok(io.Information == 4, "got size %Iu\n", io.Information);
2660 ok(!memcmp(buffer, "data", 4), "got data %s\n", debugstr_an(buffer, io.Information));
2662 ret = send(server, "data", 4, 0);
2663 ok(ret == 4, "got %ld\n", ret);
2665 ret = WSAEventSelect(client, event, FD_READ);
2666 ok(!ret, "got error %lu\n", GetLastError());
2668 ret = WSAEnumNetworkEvents(client, event, &events);
2669 ok(!ret, "got error %lu\n", GetLastError());
2670 ok(events.lNetworkEvents == FD_READ, "got events %#lx\n", events.lNetworkEvents);
2672 memset(buffer, 0xcc, sizeof(buffer));
2673 ret = NtReadFile((HANDLE)client, NULL, NULL, NULL, &io, buffer, 1, NULL, NULL);
2674 ok(!ret, "got status %#lx\n", ret);
2675 ok(io.Information == 1, "got size %Iu\n", io.Information);
2676 ok(buffer[0] == 'd', "got data %s\n", debugstr_an(buffer, io.Information));
2678 ret = WSAEnumNetworkEvents(client, event, &events);
2679 ok(!ret, "got error %lu\n", GetLastError());
2680 ok(events.lNetworkEvents == FD_READ, "got events %#lx\n", events.lNetworkEvents);
2682 memset(buffer, 0xcc, sizeof(buffer));
2683 ret = NtReadFile((HANDLE)client, NULL, NULL, NULL, &io, buffer, sizeof(buffer), NULL, NULL);
2684 ok(!ret, "got status %#lx\n", ret);
2685 ok(io.Information == 3, "got size %Iu\n", io.Information);
2686 ok(!memcmp(buffer, "ata", 3), "got data %s\n", debugstr_an(buffer, io.Information));
2688 /* NtReadFile always blocks, even when the socket is non-overlapped and nonblocking */
2690 thread = CreateThread(NULL, 0, sync_read_file_thread, (void *)server, 0, NULL);
2691 ret = WaitForSingleObject(thread, 100);
2692 ok(ret == WAIT_TIMEOUT, "got %ld\n", ret);
2694 ret = NtWriteFile((HANDLE)client, NULL, NULL, NULL, &io, "data", 4, NULL, NULL);
2695 ok(!ret, "got status %#lx\n", ret);
2697 ret = WaitForSingleObject(thread, 1000);
2698 ok(!ret, "got %ld\n", ret);
2699 CloseHandle(thread);
2701 closesocket(server);
2702 closesocket(client);
2704 tcp_socketpair(&client, &server);
2706 ret = NtReadFile((HANDLE)server, event, NULL, NULL, &io, buffer, sizeof(buffer), NULL, NULL);
2707 todo_wine ok(ret == STATUS_INVALID_PARAMETER, "got status %#lx\n", ret);
2708 if (ret == STATUS_PENDING)
2710 CancelIo((HANDLE)server);
2711 ret = WaitForSingleObject(event, 100);
2712 ok(!ret, "wait timed out\n");
2715 offset.QuadPart = -1;
2716 ret = NtReadFile((HANDLE)server, event, NULL, NULL, &io, buffer, sizeof(buffer), &offset, NULL);
2717 todo_wine ok(ret == STATUS_INVALID_PARAMETER, "got status %#lx\n", ret);
2718 if (ret == STATUS_PENDING)
2720 CancelIo((HANDLE)server);
2721 ret = WaitForSingleObject(event, 100);
2722 ok(!ret, "wait timed out\n");
2725 memset(buffer, 0xcc, sizeof(buffer));
2726 memset(&io, 0xcc, sizeof(io));
2727 offset.QuadPart = 1;
2728 ret = NtReadFile((HANDLE)server, event, NULL, NULL, &io, buffer, sizeof(buffer), &offset, NULL);
2729 ok(ret == STATUS_PENDING, "got status %#lx\n", ret);
2731 ret = NtWriteFile((HANDLE)client, NULL, NULL, NULL, &io2, "data", 4, NULL, NULL);
2732 todo_wine ok(ret == STATUS_INVALID_PARAMETER, "got status %#lx\n", ret);
2734 offset.QuadPart = -3;
2735 ret = NtWriteFile((HANDLE)client, NULL, NULL, NULL, &io2, "data", 4, &offset, NULL);
2736 todo_wine ok(ret == STATUS_INVALID_PARAMETER, "got status %#lx\n", ret);
2738 memset(&io2, 0xcc, sizeof(io2));
2739 offset.QuadPart = 2;
2740 ret = NtWriteFile((HANDLE)client, NULL, NULL, NULL, &io2, "data", 4, &offset, NULL);
2741 ok(!ret, "got status %#lx\n", ret);
2742 ok(!io2.Status, "got status %#lx\n", io2.Status);
2743 ok(io2.Information == 4, "got size %Iu\n", io2.Information);
2745 ret = WaitForSingleObject(event, 1000);
2746 ok(!ret, "wait timed out\n");
2747 ok(!io.Status, "got status %#lx\n", io.Status);
2748 ok(io.Information == 4, "got size %Iu\n", io.Information);
2749 ok(!memcmp(buffer, "data", 4), "got data %s\n", debugstr_an(buffer, io.Information));
2751 closesocket(server);
2752 closesocket(client);
2754 CloseHandle(event);
2757 START_TEST(afd)
2759 WSADATA data;
2761 WSAStartup(MAKEWORD(2, 2), &data);
2763 test_open_device();
2764 test_poll();
2765 test_poll_exclusive();
2766 test_poll_completion_port();
2767 test_poll_reset();
2768 test_recv();
2769 test_event_select();
2770 test_get_events();
2771 test_get_events_reset();
2772 test_bind();
2773 test_getsockname();
2774 test_async_thread_termination();
2775 test_read_write();
2777 WSACleanup();