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
24 #define WIN32_NO_STATUS
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
;
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());
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());
65 *dst
= accept(server
, (struct sockaddr
*)&addr
, &len
);
66 ok(*dst
!= INVALID_SOCKET
, "failed to accept socket, error %u\n", WSAGetLastError());
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
)
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};
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());
99 static void test_open_device(void)
101 OBJECT_BASIC_INFORMATION info
;
102 OBJECT_ATTRIBUTES attr
;
103 UNICODE_STRING string
;
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
);
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
);
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
);
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
);
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};
145 in_params
.timeout
= -1000 * 10000;
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;
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());
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
;
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
);
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
);
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
);
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
);
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
);
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
);
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
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
);
600 /* Test supplying multiple handles to the ioctl. */
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
);
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
);
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
);
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());
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());
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());
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
);
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
);
851 CancelIo((HANDLE
)server
);
852 ret
= WaitForSingleObject(event
, 100);
853 ok(!ret
, "wait timed out\n");
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
);
935 CloseHandle(overlapped
.hEvent
);
939 CloseHandle(afd_handle
);
942 struct poll_exclusive_thread_cb_ctx
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
;
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
);
967 #define POLL_SOCK_CNT 2
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]
983 SOCKET socks
[POLL_CNT
];
984 IO_STATUS_BLOCK io
[POLL_CNT
];
985 HANDLE events
[POLL_CNT
];
987 struct poll_exclusive_thread_cb_ctx cb_ctx
;
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];
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
);
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
);
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
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
;
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;
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
, ¶ms
, sizeof(params
), ¶ms
, 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
, ¶ms
, sizeof(params
), ¶ms
, 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
);
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
, ¶ms
, sizeof(params
), ¶ms
, 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;
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
, ¶ms
, sizeof(params
), ¶ms
, 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
);
1364 closesocket(server
);
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
;
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
);
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
;
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());
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
;
1457 params
.msg_flags
= AFD_MSG_NOT_OOB
;
1459 ret
= NtDeviceIoControlFile((HANDLE
)client
, event
, NULL
, NULL
, &io
,
1460 IOCTL_AFD_RECV
, ¶ms
, 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
, ¶ms
, 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(¶ms
, 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. */
1488 wsabufs
[0].buf
= buffer
;
1490 wsabufs
[1].buf
= buffer
+ 3;
1491 memset(¶ms
, 0, sizeof(params
));
1492 params
.buffers
= wsabufs
;
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
, ¶ms
, 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
, ¶ms
, 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
, ¶ms
, 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
, ¶ms
, 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
, ¶ms
, 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
);
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
, ¶ms
, 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
, ¶ms
, 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
, ¶ms
, 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
, ¶ms
, 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
, ¶ms
, 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
, ¶ms
, 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
, ¶ms
, 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
, ¶ms
, 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
, ¶ms
, 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
, ¶ms
, 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());
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
, ¶ms
, 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
, ¶ms
, 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
, ¶ms
, 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
, ¶ms
, 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
);
1786 static void test_event_select(void)
1788 struct afd_event_select_params params
;
1789 WSANETWORKEVENTS events
;
1790 SOCKET client
, server
;
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
);
1808 memset(&io
, 0xcc, sizeof(io
));
1809 ret
= NtDeviceIoControlFile((HANDLE
)client
, NULL
, NULL
, NULL
, &io
,
1810 IOCTL_AFD_EVENT_SELECT
, ¶ms
, 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
;
1817 memset(&io
, 0xcc, sizeof(io
));
1818 ret
= NtDeviceIoControlFile((HANDLE
)client
, NULL
, NULL
, NULL
, &io
,
1819 IOCTL_AFD_EVENT_SELECT
, ¶ms
, 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
, ¶ms
, 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
;
1853 memset(&io
, 0xcc, sizeof(io
));
1854 ret
= NtDeviceIoControlFile((HANDLE
)client
, NULL
, NULL
, NULL
, &io
,
1855 IOCTL_AFD_EVENT_SELECT
, ¶ms
, 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
);
1862 memset(&io
, 0xcc, sizeof(io
));
1863 ret
= NtDeviceIoControlFile((HANDLE
)client
, NULL
, NULL
, NULL
, &io
,
1864 IOCTL_AFD_EVENT_SELECT
, ¶ms
, 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
);
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
),
1887 struct afd_get_events_params params
;
1888 WSANETWORKEVENTS events
;
1889 SOCKET client
, server
;
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(¶ms
, 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(¶ms
, 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, ¶ms
, 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(¶ms
, 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, ¶ms
, 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(¶ms
, 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, ¶ms
, 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
);
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(¶ms
, 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, ¶ms
, 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
]);
1986 ok(!params
.status
[i
], "got status[%u] %#x\n", i
, params
.status
[i
]);
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(¶ms
, 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, ¶ms
, 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
]);
2007 ok(!params
.status
[i
], "got status[%u] %#x\n", i
, params
.status
[i
]);
2010 closesocket(client
);
2016 static void test_get_events_reset(void)
2018 struct afd_get_events_params params
;
2019 SOCKET client
, server
;
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(¶ms
, 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, ¶ms
, 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(¶ms
, 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, ¶ms
, 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
);
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
;
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(¶ms
->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(¶ms
->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(¶ms
->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(¶ms
->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(¶ms
->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(¶ms
->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(¶ms
->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
);
2166 s
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
2168 memcpy(¶ms
->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");
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
*)¶ms
->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");
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(¶ms
->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(¶ms
->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(¶ms
->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(¶ms
->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(¶ms
->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(¶ms
->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(¶ms
->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(¶ms
->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(¶ms
->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");
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(¶ms
->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
);
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
;
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
);
2406 HANDLE handle
, event
;
2407 PIO_APC_ROUTINE apc
;
2409 IO_STATUS_BLOCK
*io
;
2416 HANDLE complete_event
;
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
)
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
;
2443 p
.apc_context
= apc_context
;
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
);
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
);
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)
2480 PIO_APC_ROUTINE apc
;
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
;
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
));
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
);
2546 ret
= WaitForSingleObject(event
, 1000);
2547 ok(!ret
, "got %#x\n", ret
);
2549 winetest_pop_context();
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
));
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
);
2567 ok(ret
== STATUS_INVALID_PARAMETER
, "got %#x\n", ret
);
2568 winetest_pop_context();
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
));
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
);
2588 ok(ret
== WAIT_TIMEOUT
, "got %#x\n", ret
);
2590 winetest_pop_context();
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
));
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();
2612 closesocket(listener
);
2615 static DWORD WINAPI
sync_read_file_thread(void *arg
)
2617 HANDLE server
= arg
;
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
));
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
;
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
);
2761 WSAStartup(MAKEWORD(2, 2), &data
);
2765 test_poll_exclusive();
2766 test_poll_completion_port();
2769 test_event_select();
2771 test_get_events_reset();
2774 test_async_thread_termination();