2 * Unit tests for named pipe functions in Wine
4 * Copyright (c) 2002 Dan Kegel
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
25 #define WIN32_NO_STATUS
30 #include "wine/test.h"
32 #define PIPENAME "\\\\.\\PiPe\\tests_pipe.c"
33 #define PIPENAME_SPECIAL "\\\\.\\PiPe\\tests->pipe.c"
35 #define NB_SERVER_LOOPS 8
37 static HANDLE alarm_event
;
38 static BOOL (WINAPI
*pDuplicateTokenEx
)(HANDLE
,DWORD
,LPSECURITY_ATTRIBUTES
,
39 SECURITY_IMPERSONATION_LEVEL
,TOKEN_TYPE
,PHANDLE
);
40 static DWORD (WINAPI
*pQueueUserAPC
)(PAPCFUNC pfnAPC
, HANDLE hThread
, ULONG_PTR dwData
);
41 static BOOL (WINAPI
*pCancelIoEx
)(HANDLE handle
, LPOVERLAPPED lpOverlapped
);
43 static BOOL user_apc_ran
;
44 static void CALLBACK
user_apc(ULONG_PTR param
)
57 ULONG_PTR returnValue
;
63 static DWORD CALLBACK
rpcThreadMain(LPVOID arg
)
65 struct rpcThreadArgs
*rpcargs
= (struct rpcThreadArgs
*)arg
;
66 if (winetest_debug
> 1) trace("rpcThreadMain starting\n");
67 SetLastError( rpcargs
->lastError
);
72 rpcargs
->returnValue
= (ULONG_PTR
)ReadFile( (HANDLE
)rpcargs
->args
[0], /* hFile */
73 (LPVOID
)rpcargs
->args
[1], /* buffer */
74 (DWORD
)rpcargs
->args
[2], /* bytesToRead */
75 (LPDWORD
)rpcargs
->args
[3], /* bytesRead */
76 (LPOVERLAPPED
)rpcargs
->args
[4] ); /* overlapped */
80 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
81 rpcargs
->returnValue
= 0;
85 rpcargs
->lastError
= GetLastError();
86 if (winetest_debug
> 1) trace("rpcThreadMain returning\n");
90 /* Runs ReadFile(...) from a different thread */
91 static BOOL
RpcReadFile(HANDLE hFile
, LPVOID buffer
, DWORD bytesToRead
, LPDWORD bytesRead
, LPOVERLAPPED overlapped
)
93 struct rpcThreadArgs rpcargs
;
97 rpcargs
.returnValue
= 0;
98 rpcargs
.lastError
= GetLastError();
99 rpcargs
.op
= RPC_READFILE
;
100 rpcargs
.args
[0] = (ULONG_PTR
)hFile
;
101 rpcargs
.args
[1] = (ULONG_PTR
)buffer
;
102 rpcargs
.args
[2] = (ULONG_PTR
)bytesToRead
;
103 rpcargs
.args
[3] = (ULONG_PTR
)bytesRead
;
104 rpcargs
.args
[4] = (ULONG_PTR
)overlapped
;
106 thread
= CreateThread(NULL
, 0, rpcThreadMain
, (void *)&rpcargs
, 0, &threadId
);
107 ok(thread
!= NULL
, "CreateThread failed. %d\n", GetLastError());
108 ret
= WaitForSingleObject(thread
, INFINITE
);
109 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject failed with %d.\n", GetLastError());
112 SetLastError(rpcargs
.lastError
);
113 return (BOOL
)rpcargs
.returnValue
;
116 #define test_not_signaled(h) _test_not_signaled(__LINE__,h)
117 static void _test_not_signaled(unsigned line
, HANDLE handle
)
119 DWORD res
= WaitForSingleObject(handle
, 0);
120 ok_(__FILE__
,line
)(res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %u (%u)\n", res
, GetLastError());
123 #define test_signaled(h) _test_signaled(__LINE__,h)
124 static void _test_signaled(unsigned line
, HANDLE handle
)
126 DWORD res
= WaitForSingleObject(handle
, 0);
127 ok_(__FILE__
,line
)(res
== WAIT_OBJECT_0
, "WaitForSingleObject returned %u\n", res
);
130 #define test_pipe_info(a,b,c,d,e) _test_pipe_info(__LINE__,a,b,c,d,e)
131 static void _test_pipe_info(unsigned line
, HANDLE pipe
, DWORD ex_flags
, DWORD ex_out_buf_size
, DWORD ex_in_buf_size
, DWORD ex_max_instances
)
133 DWORD flags
= 0xdeadbeef, out_buf_size
= 0xdeadbeef, in_buf_size
= 0xdeadbeef, max_instances
= 0xdeadbeef;
136 res
= GetNamedPipeInfo(pipe
, &flags
, &out_buf_size
, &in_buf_size
, &max_instances
);
137 ok_(__FILE__
,line
)(res
, "GetNamedPipeInfo failed: %x\n", res
);
138 ok_(__FILE__
,line
)(flags
== ex_flags
, "flags = %x, expected %x\n", flags
, ex_flags
);
139 ok_(__FILE__
,line
)(out_buf_size
== ex_out_buf_size
, "out_buf_size = %x, expected %u\n", out_buf_size
, ex_out_buf_size
);
140 ok_(__FILE__
,line
)(in_buf_size
== ex_in_buf_size
, "in_buf_size = %x, expected %u\n", in_buf_size
, ex_in_buf_size
);
141 ok_(__FILE__
,line
)(max_instances
== ex_max_instances
, "max_instances = %x, expected %u\n", max_instances
, ex_max_instances
);
144 static void test_CreateNamedPipe(int pipemode
)
148 static const char obuf
[] = "Bit Bucket";
149 static const char obuf2
[] = "More bits";
150 char ibuf
[32], *pbuf
;
158 if (pipemode
== PIPE_TYPE_BYTE
)
159 trace("test_CreateNamedPipe starting in byte mode\n");
161 trace("test_CreateNamedPipe starting in message mode\n");
163 /* Wait for nonexistent pipe */
164 ret
= WaitNamedPipeA(PIPENAME
, 2000);
165 ok(ret
== 0, "WaitNamedPipe returned %d for nonexistent pipe\n", ret
);
166 ok(GetLastError() == ERROR_FILE_NOT_FOUND
, "wrong error %u\n", GetLastError());
168 /* Bad parameter checks */
169 hnp
= CreateNamedPipeA("not a named pipe", PIPE_ACCESS_DUPLEX
, pipemode
| PIPE_WAIT
,
170 /* nMaxInstances */ 1,
171 /* nOutBufSize */ 1024,
172 /* nInBufSize */ 1024,
173 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
174 /* lpSecurityAttrib */ NULL
);
175 ok(hnp
== INVALID_HANDLE_VALUE
&& GetLastError() == ERROR_INVALID_NAME
,
176 "CreateNamedPipe should fail if name doesn't start with \\\\.\\pipe\n");
178 if (pipemode
== PIPE_TYPE_BYTE
)
180 /* Bad parameter checks */
181 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_READMODE_MESSAGE
,
182 /* nMaxInstances */ 1,
183 /* nOutBufSize */ 1024,
184 /* nInBufSize */ 1024,
185 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
186 /* lpSecurityAttrib */ NULL
);
187 ok(hnp
== INVALID_HANDLE_VALUE
&& GetLastError() == ERROR_INVALID_PARAMETER
,
188 "CreateNamedPipe should fail with PIPE_TYPE_BYTE | PIPE_READMODE_MESSAGE\n");
191 hnp
= CreateNamedPipeA(NULL
,
192 PIPE_ACCESS_DUPLEX
, pipemode
| PIPE_WAIT
,
193 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
194 ok(hnp
== INVALID_HANDLE_VALUE
&& GetLastError() == ERROR_PATH_NOT_FOUND
,
195 "CreateNamedPipe should fail if name is NULL\n");
197 hFile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
198 ok(hFile
== INVALID_HANDLE_VALUE
199 && GetLastError() == ERROR_FILE_NOT_FOUND
,
200 "connecting to nonexistent named pipe should fail with ERROR_FILE_NOT_FOUND\n");
202 /* Functional checks */
204 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, pipemode
| PIPE_WAIT
,
205 /* nMaxInstances */ 1,
206 /* nOutBufSize */ 1024,
207 /* nInBufSize */ 1024,
208 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
209 /* lpSecurityAttrib */ NULL
);
210 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
213 ret
= PeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, NULL
);
215 ok(!ret
&& GetLastError() == ERROR_BAD_PIPE
, "PeekNamedPipe returned %x (%u)\n",
216 ret
, GetLastError());
218 ret
= WaitNamedPipeA(PIPENAME
, 2000);
219 ok(ret
, "WaitNamedPipe failed (%d)\n", GetLastError());
221 hFile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
222 ok(hFile
!= INVALID_HANDLE_VALUE
, "CreateFile failed (%d)\n", GetLastError());
224 ok(!WaitNamedPipeA(PIPENAME
, 100), "WaitNamedPipe succeeded\n");
226 ok(GetLastError() == ERROR_SEM_TIMEOUT
, "wrong error %u\n", GetLastError());
228 /* Test ConnectNamedPipe() in both directions */
229 ok(!ConnectNamedPipe(hnp
, NULL
), "ConnectNamedPipe(server) succeeded\n");
230 ok(GetLastError() == ERROR_PIPE_CONNECTED
, "expected ERROR_PIPE_CONNECTED, got %u\n", GetLastError());
231 ok(!ConnectNamedPipe(hFile
, NULL
), "ConnectNamedPipe(client) succeeded\n");
232 ok(GetLastError() == ERROR_INVALID_FUNCTION
, "expected ERROR_INVALID_FUNCTION, got %u\n", GetLastError());
234 /* don't try to do i/o if one side couldn't be opened, as it hangs */
235 if (hFile
!= INVALID_HANDLE_VALUE
) {
238 /* Make sure we can read and write a few bytes in both directions */
239 memset(ibuf
, 0, sizeof(ibuf
));
240 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile\n");
241 ok(written
== sizeof(obuf
), "write file len\n");
242 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
243 ok(readden
== sizeof(obuf
), "read got %d bytes\n", readden
);
244 ok(memcmp(obuf
, ibuf
, written
) == 0, "content check\n");
246 memset(ibuf
, 0, sizeof(ibuf
));
247 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile\n");
248 ok(written
== sizeof(obuf2
), "write file len\n");
249 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
250 ok(readden
== sizeof(obuf2
), "read got %d bytes\n", readden
);
251 ok(memcmp(obuf2
, ibuf
, written
) == 0, "content check\n");
253 /* Now the same again, but with an additional call to PeekNamedPipe */
254 memset(ibuf
, 0, sizeof(ibuf
));
255 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile\n");
256 ok(written
== sizeof(obuf
), "write file len 1\n");
257 ok(PeekNamedPipe(hFile
, NULL
, 0, NULL
, &avail
, &left
), "Peek\n");
258 ok(avail
== sizeof(obuf
), "peek 1 got %d bytes\n", avail
);
259 if (pipemode
== PIPE_TYPE_BYTE
)
260 ok(left
== 0, "peek 1 got %d bytes left\n", left
);
262 ok(left
== sizeof(obuf
), "peek 1 got %d bytes left\n", left
);
263 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
264 ok(readden
== sizeof(obuf
), "read 1 got %d bytes\n", readden
);
265 ok(memcmp(obuf
, ibuf
, written
) == 0, "content 1 check\n");
267 memset(ibuf
, 0, sizeof(ibuf
));
268 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile\n");
269 ok(written
== sizeof(obuf2
), "write file len 2\n");
270 ok(PeekNamedPipe(hnp
, NULL
, 0, NULL
, &avail
, &left
), "Peek\n");
271 ok(avail
== sizeof(obuf2
), "peek 2 got %d bytes\n", avail
);
272 if (pipemode
== PIPE_TYPE_BYTE
)
273 ok(left
== 0, "peek 2 got %d bytes left\n", left
);
275 ok(left
== sizeof(obuf2
), "peek 2 got %d bytes left\n", left
);
276 ok(PeekNamedPipe(hnp
, (LPVOID
)1, 0, NULL
, &avail
, &left
), "Peek\n");
277 ok(avail
== sizeof(obuf2
), "peek 2 got %d bytes\n", avail
);
278 if (pipemode
== PIPE_TYPE_BYTE
)
279 ok(left
== 0, "peek 2 got %d bytes left\n", left
);
281 ok(left
== sizeof(obuf2
), "peek 2 got %d bytes left\n", left
);
282 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
283 ok(readden
== sizeof(obuf2
), "read 2 got %d bytes\n", readden
);
284 ok(memcmp(obuf2
, ibuf
, written
) == 0, "content 2 check\n");
286 /* Test how ReadFile behaves when the buffer is not big enough for the whole message */
287 memset(ibuf
, 0, sizeof(ibuf
));
288 ok(WriteFile(hnp
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile\n");
289 ok(written
== sizeof(obuf2
), "write file len\n");
290 ok(PeekNamedPipe(hFile
, ibuf
, 4, &readden
, &avail
, &left
), "Peek\n");
291 ok(readden
== 4, "peek got %d bytes\n", readden
);
292 ok(avail
== sizeof(obuf2
), "peek got %d bytes available\n", avail
);
293 if (pipemode
== PIPE_TYPE_BYTE
)
294 ok(left
== -4, "peek got %d bytes left\n", left
);
296 ok(left
== sizeof(obuf2
)-4, "peek got %d bytes left\n", left
);
297 ok(ReadFile(hFile
, ibuf
, 4, &readden
, NULL
), "ReadFile\n");
298 ok(readden
== 4, "read got %d bytes\n", readden
);
299 ok(ReadFile(hFile
, ibuf
+ 4, sizeof(ibuf
) - 4, &readden
, NULL
), "ReadFile\n");
300 ok(readden
== sizeof(obuf2
) - 4, "read got %d bytes\n", readden
);
301 ok(memcmp(obuf2
, ibuf
, written
) == 0, "content check\n");
303 memset(ibuf
, 0, sizeof(ibuf
));
304 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile\n");
305 ok(written
== sizeof(obuf
), "write file len\n");
306 ok(PeekNamedPipe(hnp
, ibuf
, 4, &readden
, &avail
, &left
), "Peek\n");
307 ok(readden
== 4, "peek got %d bytes\n", readden
);
308 ok(avail
== sizeof(obuf
), "peek got %d bytes available\n", avail
);
309 if (pipemode
== PIPE_TYPE_BYTE
)
311 ok(left
== -4, "peek got %d bytes left\n", left
);
312 ok(ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile\n");
316 ok(left
== sizeof(obuf
)-4, "peek got %d bytes left\n", left
);
317 SetLastError(0xdeadbeef);
318 ok(!ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile\n");
319 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error\n");
321 ok(readden
== 4, "read got %d bytes\n", readden
);
322 ok(ReadFile(hnp
, ibuf
+ 4, sizeof(ibuf
) - 4, &readden
, NULL
), "ReadFile\n");
323 ok(readden
== sizeof(obuf
) - 4, "read got %d bytes\n", readden
);
324 ok(memcmp(obuf
, ibuf
, written
) == 0, "content check\n");
326 /* Similar to above, but use a read buffer size small enough to read in three parts */
327 memset(ibuf
, 0, sizeof(ibuf
));
328 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile\n");
329 ok(written
== sizeof(obuf2
), "write file len\n");
330 if (pipemode
== PIPE_TYPE_BYTE
)
332 ok(ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile\n");
333 ok(readden
== 4, "read got %d bytes\n", readden
);
334 ok(ReadFile(hnp
, ibuf
+ 4, 4, &readden
, NULL
), "ReadFile\n");
338 SetLastError(0xdeadbeef);
339 ok(!ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile\n");
340 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error\n");
341 ok(readden
== 4, "read got %d bytes\n", readden
);
342 SetLastError(0xdeadbeef);
343 ok(!ReadFile(hnp
, ibuf
+ 4, 4, &readden
, NULL
), "ReadFile\n");
344 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error\n");
346 ok(readden
== 4, "read got %d bytes\n", readden
);
347 ok(ReadFile(hnp
, ibuf
+ 8, sizeof(ibuf
) - 8, &readden
, NULL
), "ReadFile\n");
348 ok(readden
== sizeof(obuf2
) - 8, "read got %d bytes\n", readden
);
349 ok(memcmp(obuf2
, ibuf
, written
) == 0, "content check\n");
351 /* Test reading of multiple writes */
352 memset(ibuf
, 0, sizeof(ibuf
));
353 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile3a\n");
354 ok(written
== sizeof(obuf
), "write file len 3a\n");
355 ok(WriteFile(hnp
, obuf2
, sizeof(obuf2
), &written
, NULL
), " WriteFile3b\n");
356 ok(written
== sizeof(obuf2
), "write file len 3b\n");
357 ok(PeekNamedPipe(hFile
, ibuf
, 4, &readden
, &avail
, &left
), "Peek3\n");
358 ok(readden
== 4, "peek3 got %d bytes\n", readden
);
359 if (pipemode
== PIPE_TYPE_BYTE
)
360 ok(left
== -4, "peek3 got %d bytes left\n", left
);
362 ok(left
== sizeof(obuf
)-4, "peek3 got %d bytes left\n", left
);
363 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek3 got %d bytes available\n", avail
);
364 ok(PeekNamedPipe(hFile
, ibuf
, sizeof(ibuf
), &readden
, &avail
, &left
), "Peek3\n");
365 if (pipemode
== PIPE_TYPE_BYTE
) {
366 ok(readden
== sizeof(obuf
) + sizeof(obuf2
), "peek3 got %d bytes\n", readden
);
367 ok(left
== (DWORD
) -(sizeof(obuf
) + sizeof(obuf2
)), "peek3 got %d bytes left\n", left
);
371 ok(readden
== sizeof(obuf
), "peek3 got %d bytes\n", readden
);
372 ok(left
== 0, "peek3 got %d bytes left\n", left
);
374 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek3 got %d bytes available\n", avail
);
376 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "pipe content 3a check\n");
377 if (pipemode
== PIPE_TYPE_BYTE
&& readden
>= sizeof(obuf
)+sizeof(obuf2
)) {
378 pbuf
+= sizeof(obuf
);
379 ok(memcmp(obuf2
, pbuf
, sizeof(obuf2
)) == 0, "pipe content 3b check\n");
381 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
382 ok(readden
== sizeof(obuf
) + sizeof(obuf2
), "read 3 got %d bytes\n", readden
);
384 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 3a check\n");
385 pbuf
+= sizeof(obuf
);
386 ok(memcmp(obuf2
, pbuf
, sizeof(obuf2
)) == 0, "content 3b check\n");
388 /* Multiple writes in the reverse direction */
389 memset(ibuf
, 0, sizeof(ibuf
));
390 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile4a\n");
391 ok(written
== sizeof(obuf
), "write file len 4a\n");
392 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), " WriteFile4b\n");
393 ok(written
== sizeof(obuf2
), "write file len 4b\n");
394 ok(PeekNamedPipe(hnp
, ibuf
, 4, &readden
, &avail
, &left
), "Peek3\n");
395 ok(readden
== 4, "peek3 got %d bytes\n", readden
);
396 if (pipemode
== PIPE_TYPE_BYTE
)
397 ok(left
== -4, "peek3 got %d bytes left\n", left
);
399 ok(left
== sizeof(obuf
)-4, "peek3 got %d bytes left\n", left
);
400 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek3 got %d bytes available\n", avail
);
401 ok(PeekNamedPipe(hnp
, ibuf
, sizeof(ibuf
), &readden
, &avail
, &left
), "Peek4\n");
402 if (pipemode
== PIPE_TYPE_BYTE
) {
403 ok(readden
== sizeof(obuf
) + sizeof(obuf2
), "peek4 got %d bytes\n", readden
);
404 ok(left
== (DWORD
) -(sizeof(obuf
) + sizeof(obuf2
)), "peek4 got %d bytes left\n", left
);
408 ok(readden
== sizeof(obuf
), "peek4 got %d bytes\n", readden
);
409 ok(left
== 0, "peek4 got %d bytes left\n", left
);
411 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek4 got %d bytes available\n", avail
);
413 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "pipe content 4a check\n");
414 if (pipemode
== PIPE_TYPE_BYTE
&& readden
>= sizeof(obuf
)+sizeof(obuf2
)) {
415 pbuf
+= sizeof(obuf
);
416 ok(memcmp(obuf2
, pbuf
, sizeof(obuf2
)) == 0, "pipe content 4b check\n");
418 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
419 if (pipemode
== PIPE_TYPE_BYTE
) {
420 ok(readden
== sizeof(obuf
) + sizeof(obuf2
), "read 4 got %d bytes\n", readden
);
423 ok(readden
== sizeof(obuf
), "read 4 got %d bytes\n", readden
);
426 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 4a check\n");
427 if (pipemode
== PIPE_TYPE_BYTE
) {
428 pbuf
+= sizeof(obuf
);
429 ok(memcmp(obuf2
, pbuf
, sizeof(obuf2
)) == 0, "content 4b check\n");
432 /* Test reading of multiple writes after a mode change
433 (CreateFile always creates a byte mode pipe) */
434 lpmode
= PIPE_READMODE_MESSAGE
;
435 if (pipemode
== PIPE_TYPE_BYTE
) {
436 /* trying to change the client end of a byte pipe to message mode should fail */
437 ok(!SetNamedPipeHandleState(hFile
, &lpmode
, NULL
, NULL
), "Change mode\n");
440 ok(SetNamedPipeHandleState(hFile
, &lpmode
, NULL
, NULL
), "Change mode\n");
442 memset(ibuf
, 0, sizeof(ibuf
));
443 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile5a\n");
444 ok(written
== sizeof(obuf
), "write file len 3a\n");
445 ok(WriteFile(hnp
, obuf2
, sizeof(obuf2
), &written
, NULL
), " WriteFile5b\n");
446 ok(written
== sizeof(obuf2
), "write file len 3b\n");
447 ok(PeekNamedPipe(hFile
, ibuf
, sizeof(ibuf
), &readden
, &avail
, &left
), "Peek5\n");
448 ok(readden
== sizeof(obuf
), "peek5 got %d bytes\n", readden
);
449 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek5 got %d bytes available\n", avail
);
450 ok(left
== 0, "peek5 got %d bytes left\n", left
);
452 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 5a check\n");
453 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
454 ok(readden
== sizeof(obuf
), "read 5 got %d bytes\n", readden
);
456 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 5a check\n");
457 if (readden
<= sizeof(obuf
))
458 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
460 /* Multiple writes in the reverse direction */
461 /* the write of obuf2 from write4 should still be in the buffer */
462 ok(PeekNamedPipe(hnp
, ibuf
, sizeof(ibuf
), &readden
, &avail
, NULL
), "Peek6a\n");
463 ok(readden
== sizeof(obuf2
), "peek6a got %d bytes\n", readden
);
464 ok(avail
== sizeof(obuf2
), "peek6a got %d bytes available\n", avail
);
466 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
467 ok(readden
== sizeof(obuf2
), "read 6a got %d bytes\n", readden
);
469 ok(memcmp(obuf2
, pbuf
, sizeof(obuf2
)) == 0, "content 6a check\n");
471 memset(ibuf
, 0, sizeof(ibuf
));
472 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile6a\n");
473 ok(written
== sizeof(obuf
), "write file len 6a\n");
474 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), " WriteFile6b\n");
475 ok(written
== sizeof(obuf2
), "write file len 6b\n");
476 ok(PeekNamedPipe(hnp
, ibuf
, sizeof(ibuf
), &readden
, &avail
, NULL
), "Peek6\n");
477 ok(readden
== sizeof(obuf
), "peek6 got %d bytes\n", readden
);
479 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek6b got %d bytes available\n", avail
);
481 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 6a check\n");
482 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
483 ok(readden
== sizeof(obuf
), "read 6b got %d bytes\n", readden
);
485 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 6a check\n");
486 if (readden
<= sizeof(obuf
))
487 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
489 /* Test how ReadFile behaves when the buffer is not big enough for the whole message */
490 memset(ibuf
, 0, sizeof(ibuf
));
491 ok(WriteFile(hnp
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile 7\n");
492 ok(written
== sizeof(obuf2
), "write file len 7\n");
493 SetLastError(0xdeadbeef);
494 ok(!ReadFile(hFile
, ibuf
, 4, &readden
, NULL
), "ReadFile 7\n");
495 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 7\n");
496 ok(readden
== 4, "read got %d bytes 7\n", readden
);
497 ok(ReadFile(hFile
, ibuf
+ 4, sizeof(ibuf
) - 4, &readden
, NULL
), "ReadFile 7\n");
498 ok(readden
== sizeof(obuf2
) - 4, "read got %d bytes 7\n", readden
);
499 ok(memcmp(obuf2
, ibuf
, written
) == 0, "content check 7\n");
501 memset(ibuf
, 0, sizeof(ibuf
));
502 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile 8\n");
503 ok(written
== sizeof(obuf
), "write file len 8\n");
504 SetLastError(0xdeadbeef);
505 ok(!ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile 8\n");
506 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 8\n");
507 ok(readden
== 4, "read got %d bytes 8\n", readden
);
508 ok(ReadFile(hnp
, ibuf
+ 4, sizeof(ibuf
) - 4, &readden
, NULL
), "ReadFile 8\n");
509 ok(readden
== sizeof(obuf
) - 4, "read got %d bytes 8\n", readden
);
510 ok(memcmp(obuf
, ibuf
, written
) == 0, "content check 8\n");
512 /* The following test shows that when doing a partial read of a message, the rest
513 * is still in the pipe, and can be received from a second thread. This shows
514 * especially that the content is _not_ stored in thread-local-storage until it is
515 * completely transmitted. The same method works even across multiple processes. */
516 memset(ibuf
, 0, sizeof(ibuf
));
517 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile 9\n");
518 ok(written
== sizeof(obuf
), "write file len 9\n");
519 ok(WriteFile(hnp
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile 9\n");
520 ok(written
== sizeof(obuf2
), "write file len 9\n");
521 SetLastError(0xdeadbeef);
522 ok(!ReadFile(hFile
, ibuf
, 4, &readden
, NULL
), "ReadFile 9\n");
523 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 9\n");
524 ok(readden
== 4, "read got %d bytes 9\n", readden
);
525 SetLastError(0xdeadbeef);
526 ret
= RpcReadFile(hFile
, ibuf
+ 4, 4, &readden
, NULL
);
527 ok(!ret
, "RpcReadFile 9\n");
528 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 9\n");
529 ok(readden
== 4, "read got %d bytes 9\n", readden
);
530 ret
= RpcReadFile(hFile
, ibuf
+ 8, sizeof(ibuf
), &readden
, NULL
);
531 ok(ret
, "RpcReadFile 9\n");
532 ok(readden
== sizeof(obuf
) - 8, "read got %d bytes 9\n", readden
);
533 ok(memcmp(obuf
, ibuf
, sizeof(obuf
)) == 0, "content check 9\n");
534 if (readden
<= sizeof(obuf
) - 8) /* blocks forever if second part was already received */
536 memset(ibuf
, 0, sizeof(ibuf
));
537 SetLastError(0xdeadbeef);
538 ret
= RpcReadFile(hFile
, ibuf
, 4, &readden
, NULL
);
539 ok(!ret
, "RpcReadFile 9\n");
540 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 9\n");
541 ok(readden
== 4, "read got %d bytes 9\n", readden
);
542 SetLastError(0xdeadbeef);
543 ok(!ReadFile(hFile
, ibuf
+ 4, 4, &readden
, NULL
), "ReadFile 9\n");
544 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 9\n");
545 ok(readden
== 4, "read got %d bytes 9\n", readden
);
546 ret
= RpcReadFile(hFile
, ibuf
+ 8, sizeof(ibuf
), &readden
, NULL
);
547 ok(ret
, "RpcReadFile 9\n");
548 ok(readden
== sizeof(obuf2
) - 8, "read got %d bytes 9\n", readden
);
549 ok(memcmp(obuf2
, ibuf
, sizeof(obuf2
)) == 0, "content check 9\n");
552 /* Now the reverse direction */
553 memset(ibuf
, 0, sizeof(ibuf
));
554 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile 10\n");
555 ok(written
== sizeof(obuf2
), "write file len 10\n");
556 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile 10\n");
557 ok(written
== sizeof(obuf
), "write file len 10\n");
558 SetLastError(0xdeadbeef);
559 ok(!ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile 10\n");
560 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 10\n");
561 ok(readden
== 4, "read got %d bytes 10\n", readden
);
562 SetLastError(0xdeadbeef);
563 ret
= RpcReadFile(hnp
, ibuf
+ 4, 4, &readden
, NULL
);
564 ok(!ret
, "RpcReadFile 10\n");
565 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 10\n");
566 ok(readden
== 4, "read got %d bytes 10\n", readden
);
567 ret
= RpcReadFile(hnp
, ibuf
+ 8, sizeof(ibuf
), &readden
, NULL
);
568 ok(ret
, "RpcReadFile 10\n");
569 ok(readden
== sizeof(obuf2
) - 8, "read got %d bytes 10\n", readden
);
570 ok(memcmp(obuf2
, ibuf
, sizeof(obuf2
)) == 0, "content check 10\n");
571 if (readden
<= sizeof(obuf2
) - 8) /* blocks forever if second part was already received */
573 memset(ibuf
, 0, sizeof(ibuf
));
574 SetLastError(0xdeadbeef);
575 ret
= RpcReadFile(hnp
, ibuf
, 4, &readden
, NULL
);
576 ok(!ret
, "RpcReadFile 10\n");
577 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 10\n");
578 ok(readden
== 4, "read got %d bytes 10\n", readden
);
579 SetLastError(0xdeadbeef);
580 ok(!ReadFile(hnp
, ibuf
+ 4, 4, &readden
, NULL
), "ReadFile 10\n");
581 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 10\n");
582 ok(readden
== 4, "read got %d bytes 10\n", readden
);
583 ret
= RpcReadFile(hnp
, ibuf
+ 8, sizeof(ibuf
), &readden
, NULL
);
584 ok(ret
, "RpcReadFile 10\n");
585 ok(readden
== sizeof(obuf
) - 8, "read got %d bytes 10\n", readden
);
586 ok(memcmp(obuf
, ibuf
, sizeof(obuf
)) == 0, "content check 10\n");
591 /* Picky conformance tests */
593 /* Verify that you can't connect to pipe again
594 * until server calls DisconnectNamedPipe+ConnectNamedPipe
595 * or creates a new pipe
596 * case 1: other client not yet closed
598 hFile2
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
599 ok(hFile2
== INVALID_HANDLE_VALUE
,
600 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n");
601 ok(GetLastError() == ERROR_PIPE_BUSY
,
602 "connecting to named pipe before other client closes should fail with ERROR_PIPE_BUSY\n");
604 ok(CloseHandle(hFile
), "CloseHandle\n");
606 /* case 2: other client already closed */
607 hFile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
608 ok(hFile
== INVALID_HANDLE_VALUE
,
609 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n");
610 ok(GetLastError() == ERROR_PIPE_BUSY
,
611 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail with ERROR_PIPE_BUSY\n");
613 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe\n");
615 /* case 3: server has called DisconnectNamedPipe but not ConnectNamed Pipe */
616 hFile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
617 ok(hFile
== INVALID_HANDLE_VALUE
,
618 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n");
619 ok(GetLastError() == ERROR_PIPE_BUSY
,
620 "connecting to named pipe after other client closes but before ConnectNamedPipe should fail with ERROR_PIPE_BUSY\n");
622 /* to be complete, we'd call ConnectNamedPipe here and loop,
623 * but by default that's blocking, so we'd either have
624 * to turn on the uncommon nonblocking mode, or
625 * use another thread.
629 ok(CloseHandle(hnp
), "CloseHandle\n");
631 hnp
= CreateNamedPipeA(PIPENAME_SPECIAL
, PIPE_ACCESS_DUPLEX
, pipemode
| PIPE_WAIT
,
632 /* nMaxInstances */ 1,
633 /* nOutBufSize */ 1024,
634 /* nInBufSize */ 1024,
635 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
636 /* lpSecurityAttrib */ NULL
);
637 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe with special characters failed\n");
638 ok(CloseHandle(hnp
), "CloseHandle\n");
640 if (winetest_debug
> 1) trace("test_CreateNamedPipe returning\n");
643 static void test_CreateNamedPipe_instances_must_match(void)
647 /* Check no mismatch */
648 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
649 /* nMaxInstances */ 2,
650 /* nOutBufSize */ 1024,
651 /* nInBufSize */ 1024,
652 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
653 /* lpSecurityAttrib */ NULL
);
654 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
656 hnp2
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
657 /* nMaxInstances */ 2,
658 /* nOutBufSize */ 1024,
659 /* nInBufSize */ 1024,
660 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
661 /* lpSecurityAttrib */ NULL
);
662 ok(hnp2
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
664 ok(CloseHandle(hnp
), "CloseHandle\n");
665 ok(CloseHandle(hnp2
), "CloseHandle\n");
667 /* Check nMaxInstances */
668 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
669 /* nMaxInstances */ 1,
670 /* nOutBufSize */ 1024,
671 /* nInBufSize */ 1024,
672 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
673 /* lpSecurityAttrib */ NULL
);
674 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
676 hnp2
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
677 /* nMaxInstances */ 1,
678 /* nOutBufSize */ 1024,
679 /* nInBufSize */ 1024,
680 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
681 /* lpSecurityAttrib */ NULL
);
682 ok(hnp2
== INVALID_HANDLE_VALUE
683 && GetLastError() == ERROR_PIPE_BUSY
, "nMaxInstances not obeyed\n");
685 ok(CloseHandle(hnp
), "CloseHandle\n");
687 /* Check PIPE_ACCESS_* */
688 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
689 /* nMaxInstances */ 2,
690 /* nOutBufSize */ 1024,
691 /* nInBufSize */ 1024,
692 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
693 /* lpSecurityAttrib */ NULL
);
694 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
696 hnp2
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_INBOUND
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
697 /* nMaxInstances */ 2,
698 /* nOutBufSize */ 1024,
699 /* nInBufSize */ 1024,
700 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
701 /* lpSecurityAttrib */ NULL
);
702 ok(hnp2
== INVALID_HANDLE_VALUE
703 && GetLastError() == ERROR_ACCESS_DENIED
, "PIPE_ACCESS_* mismatch allowed\n");
705 ok(CloseHandle(hnp
), "CloseHandle\n");
707 /* check everything else */
708 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
709 /* nMaxInstances */ 4,
710 /* nOutBufSize */ 1024,
711 /* nInBufSize */ 1024,
712 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
713 /* lpSecurityAttrib */ NULL
);
714 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
716 hnp2
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_MESSAGE
,
717 /* nMaxInstances */ 3,
718 /* nOutBufSize */ 102,
720 /* nDefaultWait */ 1234,
721 /* lpSecurityAttrib */ NULL
);
722 ok(hnp2
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
724 ok(CloseHandle(hnp
), "CloseHandle\n");
725 ok(CloseHandle(hnp2
), "CloseHandle\n");
728 static void test_ReadFile(void)
730 HANDLE server
, client
;
731 OVERLAPPED overlapped
;
735 static char buf
[512];
737 server
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
738 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
739 1, 1024, 1024, NMPWAIT_WAIT_FOREVER
, NULL
);
740 ok(server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %u\n", GetLastError());
742 client
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
,
743 OPEN_EXISTING
, 0, 0);
744 ok(client
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %u\n", GetLastError());
746 ok(WriteFile(client
, buf
, sizeof(buf
), &size
, NULL
), "WriteFile\n");
748 res
= ReadFile(server
, buf
, 1, &size
, NULL
);
749 ok(!res
&& GetLastError() == ERROR_MORE_DATA
, "ReadFile returned %x(%u)\n", res
, GetLastError());
750 ok(size
== 1, "size = %u\n", size
);
752 /* pass both overlapped and ret read */
753 memset(&overlapped
, 0, sizeof(overlapped
));
754 res
= ReadFile(server
, buf
, 1, &size
, &overlapped
);
755 ok(!res
&& GetLastError() == ERROR_MORE_DATA
, "ReadFile returned %x(%u)\n", res
, GetLastError());
756 ok(size
== 0, "size = %u\n", size
);
757 ok((NTSTATUS
)overlapped
.Internal
== STATUS_BUFFER_OVERFLOW
, "Internal = %lx\n", overlapped
.Internal
);
758 ok(overlapped
.InternalHigh
== 1, "InternalHigh = %lx\n", overlapped
.InternalHigh
);
760 DisconnectNamedPipe(server
);
762 memset(&overlapped
, 0, sizeof(overlapped
));
763 overlapped
.InternalHigh
= 0xdeadbeef;
764 res
= ReadFile(server
, buf
, 1, &size
, &overlapped
);
765 ok(!res
&& GetLastError() == ERROR_PIPE_NOT_CONNECTED
, "ReadFile returned %x(%u)\n", res
, GetLastError());
766 ok(size
== 0, "size = %u\n", size
);
767 ok(overlapped
.Internal
== STATUS_PENDING
, "Internal = %lx\n", overlapped
.Internal
);
768 ok(overlapped
.InternalHigh
== 0xdeadbeef, "InternalHigh = %lx\n", overlapped
.InternalHigh
);
770 memset(&overlapped
, 0, sizeof(overlapped
));
771 overlapped
.InternalHigh
= 0xdeadbeef;
772 res
= WriteFile(server
, buf
, 1, &size
, &overlapped
);
773 ok(!res
&& GetLastError() == ERROR_PIPE_NOT_CONNECTED
, "ReadFile returned %x(%u)\n", res
, GetLastError());
774 ok(size
== 0, "size = %u\n", size
);
775 ok(overlapped
.Internal
== STATUS_PENDING
, "Internal = %lx\n", overlapped
.Internal
);
776 ok(overlapped
.InternalHigh
== 0xdeadbeef, "InternalHigh = %lx\n", overlapped
.InternalHigh
);
782 /** implementation of alarm() */
783 static DWORD CALLBACK
alarmThreadMain(LPVOID arg
)
785 DWORD_PTR timeout
= (DWORD_PTR
) arg
;
786 if (winetest_debug
> 1) trace("alarmThreadMain\n");
787 if (WaitForSingleObject( alarm_event
, timeout
) == WAIT_TIMEOUT
)
789 ok(FALSE
, "alarm\n");
795 static HANDLE hnp
= INVALID_HANDLE_VALUE
;
797 /** Trivial byte echo server - disconnects after each session */
798 static DWORD CALLBACK
serverThreadMain1(LPVOID arg
)
802 if (winetest_debug
> 1) trace("serverThreadMain1 start\n");
803 /* Set up a simple echo server */
804 hnp
= CreateNamedPipeA(PIPENAME
"serverThreadMain1", PIPE_ACCESS_DUPLEX
,
805 PIPE_TYPE_BYTE
| PIPE_WAIT
,
806 /* nMaxInstances */ 1,
807 /* nOutBufSize */ 1024,
808 /* nInBufSize */ 1024,
809 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
810 /* lpSecurityAttrib */ NULL
);
812 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
813 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
819 /* Wait for client to connect */
820 if (winetest_debug
> 1) trace("Server calling ConnectNamedPipe...\n");
821 ok(ConnectNamedPipe(hnp
, NULL
)
822 || GetLastError() == ERROR_PIPE_CONNECTED
, "ConnectNamedPipe\n");
823 if (winetest_debug
> 1) trace("ConnectNamedPipe returned.\n");
825 /* Echo bytes once */
826 memset(buf
, 0, sizeof(buf
));
828 if (winetest_debug
> 1) trace("Server reading...\n");
829 success
= ReadFile(hnp
, buf
, sizeof(buf
), &readden
, NULL
);
830 if (winetest_debug
> 1) trace("Server done reading.\n");
831 ok(success
, "ReadFile\n");
832 ok(readden
, "short read\n");
834 if (winetest_debug
> 1) trace("Server writing...\n");
835 ok(WriteFile(hnp
, buf
, readden
, &written
, NULL
), "WriteFile\n");
836 if (winetest_debug
> 1) trace("Server done writing.\n");
837 ok(written
== readden
, "write file len\n");
839 /* finish this connection, wait for next one */
840 ok(FlushFileBuffers(hnp
), "FlushFileBuffers\n");
841 if (winetest_debug
> 1) trace("Server done flushing.\n");
842 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe\n");
843 if (winetest_debug
> 1) trace("Server done disconnecting.\n");
848 /** Trivial byte echo server - closes after each connection */
849 static DWORD CALLBACK
serverThreadMain2(LPVOID arg
)
854 trace("serverThreadMain2\n");
855 /* Set up a simple echo server */
856 hnp
= CreateNamedPipeA(PIPENAME
"serverThreadMain2", PIPE_ACCESS_DUPLEX
,
857 PIPE_TYPE_BYTE
| PIPE_WAIT
,
858 /* nMaxInstances */ 2,
859 /* nOutBufSize */ 1024,
860 /* nInBufSize */ 1024,
861 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
862 /* lpSecurityAttrib */ NULL
);
863 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
865 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
873 user_apc_ran
= FALSE
;
874 if (i
== 0 && pQueueUserAPC
) {
875 if (winetest_debug
> 1) trace("Queueing an user APC\n"); /* verify the pipe is non alerable */
876 ret
= pQueueUserAPC(&user_apc
, GetCurrentThread(), 0);
877 ok(ret
, "QueueUserAPC failed: %d\n", GetLastError());
880 /* Wait for client to connect */
881 if (winetest_debug
> 1) trace("Server calling ConnectNamedPipe...\n");
882 ok(ConnectNamedPipe(hnp
, NULL
)
883 || GetLastError() == ERROR_PIPE_CONNECTED
, "ConnectNamedPipe\n");
884 if (winetest_debug
> 1) trace("ConnectNamedPipe returned.\n");
886 /* Echo bytes once */
887 memset(buf
, 0, sizeof(buf
));
889 if (winetest_debug
> 1) trace("Server reading...\n");
890 success
= ReadFile(hnp
, buf
, sizeof(buf
), &readden
, NULL
);
891 if (winetest_debug
> 1) trace("Server done reading.\n");
892 ok(success
, "ReadFile\n");
894 if (winetest_debug
> 1) trace("Server writing...\n");
895 ok(WriteFile(hnp
, buf
, readden
, &written
, NULL
), "WriteFile\n");
896 if (winetest_debug
> 1) trace("Server done writing.\n");
897 ok(written
== readden
, "write file len\n");
899 /* finish this connection, wait for next one */
900 ok(FlushFileBuffers(hnp
), "FlushFileBuffers\n");
901 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe\n");
903 ok(user_apc_ran
== FALSE
, "UserAPC ran, pipe using alertable io mode\n");
905 if (i
== 0 && pQueueUserAPC
)
906 SleepEx(0, TRUE
); /* get rid of apc */
908 /* Set up next echo server */
910 CreateNamedPipeA(PIPENAME
"serverThreadMain2", PIPE_ACCESS_DUPLEX
,
911 PIPE_TYPE_BYTE
| PIPE_WAIT
,
912 /* nMaxInstances */ 2,
913 /* nOutBufSize */ 1024,
914 /* nInBufSize */ 1024,
915 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
916 /* lpSecurityAttrib */ NULL
);
918 ok(hnpNext
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
920 ok(CloseHandle(hnp
), "CloseHandle\n");
926 /** Trivial byte echo server - uses overlapped named pipe calls */
927 static DWORD CALLBACK
serverThreadMain3(LPVOID arg
)
932 if (winetest_debug
> 1) trace("serverThreadMain3\n");
933 /* Set up a simple echo server */
934 hnp
= CreateNamedPipeA(PIPENAME
"serverThreadMain3", PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
935 PIPE_TYPE_BYTE
| PIPE_WAIT
,
936 /* nMaxInstances */ 1,
937 /* nOutBufSize */ 1024,
938 /* nInBufSize */ 1024,
939 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
940 /* lpSecurityAttrib */ NULL
);
941 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
943 hEvent
= CreateEventW(NULL
, /* security attribute */
944 TRUE
, /* manual reset event */
945 FALSE
, /* initial state */
947 ok(hEvent
!= NULL
, "CreateEvent\n");
949 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
956 int letWFSOEwait
= (i
& 2);
957 int letGORwait
= (i
& 1);
960 memset(&oOverlap
, 0, sizeof(oOverlap
));
961 oOverlap
.hEvent
= hEvent
;
963 /* Wait for client to connect */
965 if (winetest_debug
> 1) trace("Server calling non-overlapped ConnectNamedPipe on overlapped pipe...\n");
966 success
= ConnectNamedPipe(hnp
, NULL
);
967 err
= GetLastError();
968 ok(success
|| (err
== ERROR_PIPE_CONNECTED
), "ConnectNamedPipe failed: %d\n", err
);
969 if (winetest_debug
> 1) trace("ConnectNamedPipe operation complete.\n");
971 if (winetest_debug
> 1) trace("Server calling overlapped ConnectNamedPipe...\n");
972 success
= ConnectNamedPipe(hnp
, &oOverlap
);
973 err
= GetLastError();
974 ok(!success
&& (err
== ERROR_IO_PENDING
|| err
== ERROR_PIPE_CONNECTED
), "overlapped ConnectNamedPipe\n");
975 if (winetest_debug
> 1) trace("overlapped ConnectNamedPipe returned.\n");
976 if (!success
&& (err
== ERROR_IO_PENDING
)) {
981 ret
= WaitForSingleObjectEx(hEvent
, INFINITE
, TRUE
);
982 } while (ret
== WAIT_IO_COMPLETION
);
983 ok(ret
== 0, "wait ConnectNamedPipe returned %x\n", ret
);
985 success
= GetOverlappedResult(hnp
, &oOverlap
, &dummy
, letGORwait
);
986 if (!letGORwait
&& !letWFSOEwait
&& !success
) {
987 ok(GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult\n");
988 success
= GetOverlappedResult(hnp
, &oOverlap
, &dummy
, TRUE
);
991 ok(success
|| (err
== ERROR_PIPE_CONNECTED
), "GetOverlappedResult ConnectNamedPipe\n");
992 if (winetest_debug
> 1) trace("overlapped ConnectNamedPipe operation complete.\n");
995 /* Echo bytes once */
996 memset(buf
, 0, sizeof(buf
));
998 if (winetest_debug
> 1) trace("Server reading...\n");
999 success
= ReadFile(hnp
, buf
, sizeof(buf
), &readden
, &oOverlap
);
1000 if (winetest_debug
> 1) trace("Server ReadFile returned...\n");
1001 err
= GetLastError();
1002 ok(success
|| err
== ERROR_IO_PENDING
, "overlapped ReadFile\n");
1003 if (winetest_debug
> 1) trace("overlapped ReadFile returned.\n");
1004 if (!success
&& (err
== ERROR_IO_PENDING
)) {
1009 ret
= WaitForSingleObjectEx(hEvent
, INFINITE
, TRUE
);
1010 } while (ret
== WAIT_IO_COMPLETION
);
1011 ok(ret
== 0, "wait ReadFile returned %x\n", ret
);
1013 success
= GetOverlappedResult(hnp
, &oOverlap
, &readden
, letGORwait
);
1014 if (!letGORwait
&& !letWFSOEwait
&& !success
) {
1015 ok(GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult\n");
1016 success
= GetOverlappedResult(hnp
, &oOverlap
, &readden
, TRUE
);
1019 if (winetest_debug
> 1) trace("Server done reading.\n");
1020 ok(success
, "overlapped ReadFile\n");
1022 if (winetest_debug
> 1) trace("Server writing...\n");
1023 success
= WriteFile(hnp
, buf
, readden
, &written
, &oOverlap
);
1024 if (winetest_debug
> 1) trace("Server WriteFile returned...\n");
1025 err
= GetLastError();
1026 ok(success
|| err
== ERROR_IO_PENDING
, "overlapped WriteFile\n");
1027 if (winetest_debug
> 1) trace("overlapped WriteFile returned.\n");
1028 if (!success
&& (err
== ERROR_IO_PENDING
)) {
1033 ret
= WaitForSingleObjectEx(hEvent
, INFINITE
, TRUE
);
1034 } while (ret
== WAIT_IO_COMPLETION
);
1035 ok(ret
== 0, "wait WriteFile returned %x\n", ret
);
1037 success
= GetOverlappedResult(hnp
, &oOverlap
, &written
, letGORwait
);
1038 if (!letGORwait
&& !letWFSOEwait
&& !success
) {
1039 ok(GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult\n");
1040 success
= GetOverlappedResult(hnp
, &oOverlap
, &written
, TRUE
);
1043 if (winetest_debug
> 1) trace("Server done writing.\n");
1044 ok(success
, "overlapped WriteFile\n");
1045 ok(written
== readden
, "write file len\n");
1047 /* finish this connection, wait for next one */
1048 ok(FlushFileBuffers(hnp
), "FlushFileBuffers\n");
1049 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe\n");
1054 /** Trivial byte echo server - uses i/o completion ports */
1055 static DWORD CALLBACK
serverThreadMain4(LPVOID arg
)
1061 if (winetest_debug
> 1) trace("serverThreadMain4\n");
1062 /* Set up a simple echo server */
1063 hnp
= CreateNamedPipeA(PIPENAME
"serverThreadMain4", PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
1064 PIPE_TYPE_BYTE
| PIPE_WAIT
,
1065 /* nMaxInstances */ 1,
1066 /* nOutBufSize */ 1024,
1067 /* nInBufSize */ 1024,
1068 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1069 /* lpSecurityAttrib */ NULL
);
1070 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
1072 hcompletion
= CreateIoCompletionPort(hnp
, NULL
, 12345, 1);
1073 ok(hcompletion
!= NULL
, "CreateIoCompletionPort failed, error=%i\n", GetLastError());
1075 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
1081 OVERLAPPED oConnect
;
1084 OVERLAPPED
*oResult
;
1088 memset(&oConnect
, 0, sizeof(oConnect
));
1089 memset(&oRead
, 0, sizeof(oRead
));
1090 memset(&oWrite
, 0, sizeof(oWrite
));
1092 /* Wait for client to connect */
1093 if (winetest_debug
> 1) trace("Server calling overlapped ConnectNamedPipe...\n");
1094 success
= ConnectNamedPipe(hnp
, &oConnect
);
1095 err
= GetLastError();
1096 ok(!success
&& (err
== ERROR_IO_PENDING
|| err
== ERROR_PIPE_CONNECTED
),
1097 "overlapped ConnectNamedPipe got %u err %u\n", success
, err
);
1098 if (!success
&& err
== ERROR_IO_PENDING
) {
1099 if (winetest_debug
> 1) trace("ConnectNamedPipe GetQueuedCompletionStatus\n");
1100 success
= GetQueuedCompletionStatus(hcompletion
, &dummy
, &compkey
, &oResult
, 0);
1103 ok( GetLastError() == WAIT_TIMEOUT
,
1104 "ConnectNamedPipe GetQueuedCompletionStatus wrong error %u\n", GetLastError());
1105 success
= GetQueuedCompletionStatus(hcompletion
, &dummy
, &compkey
, &oResult
, 10000);
1107 ok(success
, "ConnectNamedPipe GetQueuedCompletionStatus failed, errno=%i\n", GetLastError());
1110 ok(compkey
== 12345, "got completion key %i instead of 12345\n", (int)compkey
);
1111 ok(oResult
== &oConnect
, "got overlapped pointer %p instead of %p\n", oResult
, &oConnect
);
1114 if (winetest_debug
> 1) trace("overlapped ConnectNamedPipe operation complete.\n");
1116 /* Echo bytes once */
1117 memset(buf
, 0, sizeof(buf
));
1119 if (winetest_debug
> 1) trace("Server reading...\n");
1120 success
= ReadFile(hnp
, buf
, sizeof(buf
), &readden
, &oRead
);
1121 if (winetest_debug
> 1) trace("Server ReadFile returned...\n");
1122 err
= GetLastError();
1123 ok(success
|| err
== ERROR_IO_PENDING
, "overlapped ReadFile, err=%i\n", err
);
1124 success
= GetQueuedCompletionStatus(hcompletion
, &readden
, &compkey
,
1126 ok(success
, "ReadFile GetQueuedCompletionStatus failed, errno=%i\n", GetLastError());
1129 ok(compkey
== 12345, "got completion key %i instead of 12345\n", (int)compkey
);
1130 ok(oResult
== &oRead
, "got overlapped pointer %p instead of %p\n", oResult
, &oRead
);
1132 if (winetest_debug
> 1) trace("Server done reading.\n");
1134 if (winetest_debug
> 1) trace("Server writing...\n");
1135 success
= WriteFile(hnp
, buf
, readden
, &written
, &oWrite
);
1136 if (winetest_debug
> 1) trace("Server WriteFile returned...\n");
1137 err
= GetLastError();
1138 ok(success
|| err
== ERROR_IO_PENDING
, "overlapped WriteFile failed, err=%u\n", err
);
1139 success
= GetQueuedCompletionStatus(hcompletion
, &written
, &compkey
,
1141 ok(success
, "WriteFile GetQueuedCompletionStatus failed, errno=%i\n", GetLastError());
1144 ok(compkey
== 12345, "got completion key %i instead of 12345\n", (int)compkey
);
1145 ok(oResult
== &oWrite
, "got overlapped pointer %p instead of %p\n", oResult
, &oWrite
);
1146 ok(written
== readden
, "write file len\n");
1148 if (winetest_debug
> 1) trace("Server done writing.\n");
1150 /* Client will finish this connection, the following ops will trigger broken pipe errors. */
1152 /* Wait for the pipe to break. */
1153 while (PeekNamedPipe(hnp
, NULL
, 0, NULL
, &written
, &written
));
1155 if (winetest_debug
> 1) trace("Server writing on disconnected pipe...\n");
1156 SetLastError(ERROR_SUCCESS
);
1157 success
= WriteFile(hnp
, buf
, readden
, &written
, &oWrite
);
1158 err
= GetLastError();
1159 todo_wine_if (!success
&& err
== ERROR_PIPE_NOT_CONNECTED
) ok(!success
&& err
== ERROR_NO_DATA
,
1160 "overlapped WriteFile on disconnected pipe returned %u, err=%i\n", success
, err
);
1162 /* No completion status is queued on immediate error. */
1163 SetLastError(ERROR_SUCCESS
);
1164 oResult
= (OVERLAPPED
*)0xdeadbeef;
1165 success
= GetQueuedCompletionStatus(hcompletion
, &written
, &compkey
,
1167 err
= GetLastError();
1168 ok(!success
&& err
== WAIT_TIMEOUT
&& !oResult
,
1169 "WriteFile GetQueuedCompletionStatus returned %u, err=%i, oResult %p\n",
1170 success
, err
, oResult
);
1172 if (winetest_debug
> 1) trace("Server reading from disconnected pipe...\n");
1173 SetLastError(ERROR_SUCCESS
);
1174 success
= ReadFile(hnp
, buf
, sizeof(buf
), &readden
, &oRead
);
1175 if (winetest_debug
> 1) trace("Server ReadFile from disconnected pipe returned...\n");
1176 err
= GetLastError();
1177 ok(!success
&& err
== ERROR_BROKEN_PIPE
,
1178 "overlapped ReadFile on disconnected pipe returned %u, err=%i\n", success
, err
);
1180 SetLastError(ERROR_SUCCESS
);
1181 oResult
= (OVERLAPPED
*)0xdeadbeef;
1182 success
= GetQueuedCompletionStatus(hcompletion
, &readden
, &compkey
,
1184 err
= GetLastError();
1185 ok(!success
&& err
== WAIT_TIMEOUT
&& !oResult
,
1186 "ReadFile GetQueuedCompletionStatus returned %u, err=%i, oResult %p\n",
1187 success
, err
, oResult
);
1189 /* finish this connection, wait for next one */
1190 ok(FlushFileBuffers(hnp
), "FlushFileBuffers\n");
1191 success
= DisconnectNamedPipe(hnp
);
1192 ok(success
, "DisconnectNamedPipe failed, err %u\n", GetLastError());
1195 ret
= CloseHandle(hnp
);
1196 ok(ret
, "CloseHandle named pipe failed, err=%i\n", GetLastError());
1197 ret
= CloseHandle(hcompletion
);
1198 ok(ret
, "CloseHandle completion failed, err=%i\n", GetLastError());
1203 static int completion_called
;
1204 static DWORD completion_errorcode
;
1205 static DWORD completion_num_bytes
;
1206 static LPOVERLAPPED completion_lpoverlapped
;
1208 static VOID WINAPI
completion_routine(DWORD errorcode
, DWORD num_bytes
, LPOVERLAPPED lpoverlapped
)
1210 completion_called
++;
1211 completion_errorcode
= errorcode
;
1212 completion_num_bytes
= num_bytes
;
1213 completion_lpoverlapped
= lpoverlapped
;
1214 SetEvent(lpoverlapped
->hEvent
);
1217 /** Trivial byte echo server - uses ReadFileEx/WriteFileEx */
1218 static DWORD CALLBACK
serverThreadMain5(LPVOID arg
)
1223 if (winetest_debug
> 1) trace("serverThreadMain5\n");
1224 /* Set up a simple echo server */
1225 hnp
= CreateNamedPipeA(PIPENAME
"serverThreadMain5", PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
1226 PIPE_TYPE_BYTE
| PIPE_WAIT
,
1227 /* nMaxInstances */ 1,
1228 /* nOutBufSize */ 1024,
1229 /* nInBufSize */ 1024,
1230 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1231 /* lpSecurityAttrib */ NULL
);
1232 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
1234 hEvent
= CreateEventW(NULL
, /* security attribute */
1235 TRUE
, /* manual reset event */
1236 FALSE
, /* initial state */
1238 ok(hEvent
!= NULL
, "CreateEvent\n");
1240 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
1244 OVERLAPPED oOverlap
;
1247 memset(&oOverlap
, 0, sizeof(oOverlap
));
1248 oOverlap
.hEvent
= hEvent
;
1250 /* Wait for client to connect */
1251 if (winetest_debug
> 1) trace("Server calling ConnectNamedPipe...\n");
1252 success
= ConnectNamedPipe(hnp
, NULL
);
1253 err
= GetLastError();
1254 ok(success
|| (err
== ERROR_PIPE_CONNECTED
), "ConnectNamedPipe failed: %d\n", err
);
1255 if (winetest_debug
> 1) trace("ConnectNamedPipe operation complete.\n");
1257 /* Echo bytes once */
1258 memset(buf
, 0, sizeof(buf
));
1260 if (winetest_debug
> 1) trace("Server reading...\n");
1261 completion_called
= 0;
1263 success
= ReadFileEx(hnp
, buf
, sizeof(buf
), &oOverlap
, completion_routine
);
1264 if (winetest_debug
> 1) trace("Server ReadFileEx returned...\n");
1265 ok(success
, "ReadFileEx failed, err=%i\n", GetLastError());
1266 ok(completion_called
== 0, "completion routine called before ReadFileEx return\n");
1267 if (winetest_debug
> 1) trace("ReadFileEx returned.\n");
1271 ret
= WaitForSingleObjectEx(hEvent
, INFINITE
, TRUE
);
1272 } while (ret
== WAIT_IO_COMPLETION
);
1273 ok(ret
== 0, "wait ReadFileEx returned %x\n", ret
);
1275 ok(completion_called
== 1, "completion routine called %i times\n", completion_called
);
1276 ok(completion_errorcode
== ERROR_SUCCESS
, "completion routine got error %d\n", completion_errorcode
);
1277 ok(completion_num_bytes
!= 0, "read 0 bytes\n");
1278 ok(completion_lpoverlapped
== &oOverlap
, "got wrong overlapped pointer %p\n", completion_lpoverlapped
);
1279 readden
= completion_num_bytes
;
1280 if (winetest_debug
> 1) trace("Server done reading.\n");
1282 if (winetest_debug
> 1) trace("Server writing...\n");
1283 completion_called
= 0;
1285 success
= WriteFileEx(hnp
, buf
, readden
, &oOverlap
, completion_routine
);
1286 if (winetest_debug
> 1) trace("Server WriteFileEx returned...\n");
1287 ok(success
, "WriteFileEx failed, err=%i\n", GetLastError());
1288 ok(completion_called
== 0, "completion routine called before ReadFileEx return\n");
1289 if (winetest_debug
> 1) trace("overlapped WriteFile returned.\n");
1293 ret
= WaitForSingleObjectEx(hEvent
, INFINITE
, TRUE
);
1294 } while (ret
== WAIT_IO_COMPLETION
);
1295 ok(ret
== 0, "wait WriteFileEx returned %x\n", ret
);
1297 if (winetest_debug
> 1) trace("Server done writing.\n");
1298 ok(completion_called
== 1, "completion routine called %i times\n", completion_called
);
1299 ok(completion_errorcode
== ERROR_SUCCESS
, "completion routine got error %d\n", completion_errorcode
);
1300 ok(completion_num_bytes
== readden
, "read %i bytes wrote %i\n", readden
, completion_num_bytes
);
1301 ok(completion_lpoverlapped
== &oOverlap
, "got wrong overlapped pointer %p\n", completion_lpoverlapped
);
1303 /* finish this connection, wait for next one */
1304 ok(FlushFileBuffers(hnp
), "FlushFileBuffers\n");
1305 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe\n");
1310 static void exercizeServer(const char *pipename
, HANDLE serverThread
)
1314 if (winetest_debug
> 1) trace("exercizeServer starting\n");
1315 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
1316 HANDLE hFile
=INVALID_HANDLE_VALUE
;
1317 static const char obuf
[] = "Bit Bucket";
1323 for (loop
= 0; loop
< 3; loop
++) {
1325 if (winetest_debug
> 1) trace("Client connecting...\n");
1326 /* Connect to the server */
1327 hFile
= CreateFileA(pipename
, GENERIC_READ
| GENERIC_WRITE
, 0,
1328 NULL
, OPEN_EXISTING
, 0, 0);
1329 if (hFile
!= INVALID_HANDLE_VALUE
)
1331 err
= GetLastError();
1333 ok(err
== ERROR_PIPE_BUSY
|| err
== ERROR_FILE_NOT_FOUND
, "connecting to pipe\n");
1335 ok(err
== ERROR_PIPE_BUSY
, "connecting to pipe\n");
1336 if (winetest_debug
> 1) trace("connect failed, retrying\n");
1339 ok(hFile
!= INVALID_HANDLE_VALUE
, "client opening named pipe\n");
1341 /* Make sure it can echo */
1342 memset(ibuf
, 0, sizeof(ibuf
));
1343 if (winetest_debug
> 1) trace("Client writing...\n");
1344 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile to client end of pipe\n");
1345 ok(written
== sizeof(obuf
), "write file len\n");
1346 if (winetest_debug
> 1) trace("Client reading...\n");
1347 ok(ReadFile(hFile
, ibuf
, sizeof(obuf
), &readden
, NULL
), "ReadFile from client end of pipe\n");
1348 ok(readden
== sizeof(obuf
), "read file len\n");
1349 ok(memcmp(obuf
, ibuf
, written
) == 0, "content check\n");
1351 if (winetest_debug
> 1) trace("Client closing...\n");
1352 ok(CloseHandle(hFile
), "CloseHandle\n");
1355 ok(WaitForSingleObject(serverThread
,INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject\n");
1357 if (winetest_debug
> 1) trace("exercizeServer returning\n");
1360 static void test_NamedPipe_2(void)
1362 HANDLE serverThread
;
1363 DWORD serverThreadId
;
1365 DWORD alarmThreadId
;
1367 trace("test_NamedPipe_2 starting\n");
1368 /* Set up a twenty second timeout */
1369 alarm_event
= CreateEventW( NULL
, TRUE
, FALSE
, NULL
);
1370 SetLastError(0xdeadbeef);
1371 alarmThread
= CreateThread(NULL
, 0, alarmThreadMain
, (void *) 20000, 0, &alarmThreadId
);
1372 ok(alarmThread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1374 /* The servers we're about to exercise do try to clean up carefully,
1375 * but to reduce the chance of a test failure due to a pipe handle
1376 * leak in the test code, we'll use a different pipe name for each server.
1380 SetLastError(0xdeadbeef);
1381 serverThread
= CreateThread(NULL
, 0, serverThreadMain1
, (void *)8, 0, &serverThreadId
);
1382 ok(serverThread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1383 exercizeServer(PIPENAME
"serverThreadMain1", serverThread
);
1386 SetLastError(0xdeadbeef);
1387 serverThread
= CreateThread(NULL
, 0, serverThreadMain2
, 0, 0, &serverThreadId
);
1388 ok(serverThread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1389 exercizeServer(PIPENAME
"serverThreadMain2", serverThread
);
1392 SetLastError(0xdeadbeef);
1393 serverThread
= CreateThread(NULL
, 0, serverThreadMain3
, 0, 0, &serverThreadId
);
1394 ok(serverThread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1395 exercizeServer(PIPENAME
"serverThreadMain3", serverThread
);
1398 SetLastError(0xdeadbeef);
1399 serverThread
= CreateThread(NULL
, 0, serverThreadMain4
, 0, 0, &serverThreadId
);
1400 ok(serverThread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1401 exercizeServer(PIPENAME
"serverThreadMain4", serverThread
);
1404 SetLastError(0xdeadbeef);
1405 serverThread
= CreateThread(NULL
, 0, serverThreadMain5
, 0, 0, &serverThreadId
);
1406 ok(serverThread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1407 exercizeServer(PIPENAME
"serverThreadMain5", serverThread
);
1409 ok(SetEvent( alarm_event
), "SetEvent\n");
1410 CloseHandle( alarm_event
);
1411 if (winetest_debug
> 1) trace("test_NamedPipe_2 returning\n");
1414 static int test_DisconnectNamedPipe(void)
1418 static const char obuf
[] = "Bit Bucket";
1424 SetLastError(0xdeadbeef);
1425 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
1426 /* nMaxInstances */ 1,
1427 /* nOutBufSize */ 1024,
1428 /* nInBufSize */ 1024,
1429 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1430 /* lpSecurityAttrib */ NULL
);
1431 if ((hnp
== INVALID_HANDLE_VALUE
/* Win98 */ || !hnp
/* Win95 */)
1432 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
) {
1434 win_skip("Named pipes are not implemented\n");
1438 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
) == 0
1439 && GetLastError() == ERROR_PIPE_LISTENING
, "WriteFile to not-yet-connected pipe\n");
1440 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
) == 0
1441 && GetLastError() == ERROR_PIPE_LISTENING
, "ReadFile from not-yet-connected pipe\n");
1443 hFile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1444 ok(hFile
!= INVALID_HANDLE_VALUE
, "CreateFile failed\n");
1446 /* don't try to do i/o if one side couldn't be opened, as it hangs */
1447 if (hFile
!= INVALID_HANDLE_VALUE
) {
1449 /* see what happens if server calls DisconnectNamedPipe
1450 * when there are bytes in the pipe
1453 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile\n");
1454 ok(written
== sizeof(obuf
), "write file len\n");
1455 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe while messages waiting\n");
1456 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
) == 0
1457 && GetLastError() == ERROR_PIPE_NOT_CONNECTED
, "WriteFile to disconnected pipe\n");
1458 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
) == 0
1459 && GetLastError() == ERROR_PIPE_NOT_CONNECTED
,
1460 "ReadFile from disconnected pipe with bytes waiting\n");
1462 ok(!DisconnectNamedPipe(hnp
) && GetLastError() == ERROR_PIPE_NOT_CONNECTED
,
1463 "DisconnectNamedPipe worked twice\n");
1464 ret
= WaitForSingleObject(hFile
, 0);
1465 ok(ret
== WAIT_TIMEOUT
, "WaitForSingleObject returned %X\n", ret
);
1467 ret
= PeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, NULL
);
1469 ok(!ret
&& GetLastError() == ERROR_PIPE_NOT_CONNECTED
, "PeekNamedPipe returned %x (%u)\n",
1470 ret
, GetLastError());
1471 ret
= PeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, NULL
);
1473 ok(!ret
&& GetLastError() == ERROR_BAD_PIPE
, "PeekNamedPipe returned %x (%u)\n",
1474 ret
, GetLastError());
1475 ok(CloseHandle(hFile
), "CloseHandle\n");
1478 ok(CloseHandle(hnp
), "CloseHandle\n");
1482 static void test_CreatePipe(void)
1484 SECURITY_ATTRIBUTES pipe_attr
;
1485 HANDLE piperead
, pipewrite
;
1492 user_apc_ran
= FALSE
;
1494 ok(pQueueUserAPC(user_apc
, GetCurrentThread(), 0), "couldn't create user apc\n");
1496 pipe_attr
.nLength
= sizeof(SECURITY_ATTRIBUTES
);
1497 pipe_attr
.bInheritHandle
= TRUE
;
1498 pipe_attr
.lpSecurityDescriptor
= NULL
;
1499 ok(CreatePipe(&piperead
, &pipewrite
, &pipe_attr
, 0) != 0, "CreatePipe failed\n");
1500 test_pipe_info(piperead
, FILE_PIPE_SERVER_END
, 4096, 4096, 1);
1501 test_pipe_info(pipewrite
, 0, 4096, 4096, 1);
1503 ok(WriteFile(pipewrite
,PIPENAME
,sizeof(PIPENAME
), &written
, NULL
), "Write to anonymous pipe failed\n");
1504 ok(written
== sizeof(PIPENAME
), "Write to anonymous pipe wrote %d bytes\n", written
);
1505 ok(ReadFile(piperead
,readbuf
,sizeof(readbuf
),&read
, NULL
), "Read from non empty pipe failed\n");
1506 ok(read
== sizeof(PIPENAME
), "Read from anonymous pipe got %d bytes\n", read
);
1507 ok(CloseHandle(pipewrite
), "CloseHandle for the write pipe failed\n");
1508 ok(CloseHandle(piperead
), "CloseHandle for the read pipe failed\n");
1510 /* Now write another chunk*/
1511 ok(CreatePipe(&piperead
, &pipewrite
, &pipe_attr
, 0) != 0, "CreatePipe failed\n");
1512 ok(WriteFile(pipewrite
,PIPENAME
,sizeof(PIPENAME
), &written
, NULL
), "Write to anonymous pipe failed\n");
1513 ok(written
== sizeof(PIPENAME
), "Write to anonymous pipe wrote %d bytes\n", written
);
1514 /* and close the write end, read should still succeed*/
1515 ok(CloseHandle(pipewrite
), "CloseHandle for the Write Pipe failed\n");
1516 ok(ReadFile(piperead
,readbuf
,sizeof(readbuf
),&read
, NULL
), "Read from broken pipe with pending data failed\n");
1517 ok(read
== sizeof(PIPENAME
), "Read from anonymous pipe got %d bytes\n", read
);
1518 /* But now we need to get informed that the pipe is closed */
1519 ok(ReadFile(piperead
,readbuf
,sizeof(readbuf
),&read
, NULL
) == 0, "Broken pipe not detected\n");
1520 ok(CloseHandle(piperead
), "CloseHandle for the read pipe failed\n");
1522 /* Try bigger chunks */
1524 buffer
= HeapAlloc( GetProcessHeap(), 0, size
);
1525 for (i
= 0; i
< size
; i
++) buffer
[i
] = i
;
1526 ok(CreatePipe(&piperead
, &pipewrite
, &pipe_attr
, (size
+ 24)) != 0, "CreatePipe failed\n");
1527 ok(WriteFile(pipewrite
, buffer
, size
, &written
, NULL
), "Write to anonymous pipe failed\n");
1528 ok(written
== size
, "Write to anonymous pipe wrote %d bytes\n", written
);
1529 /* and close the write end, read should still succeed*/
1530 ok(CloseHandle(pipewrite
), "CloseHandle for the Write Pipe failed\n");
1531 memset( buffer
, 0, size
);
1532 ok(ReadFile(piperead
, buffer
, size
, &read
, NULL
), "Read from broken pipe with pending data failed\n");
1533 ok(read
== size
, "Read from anonymous pipe got %d bytes\n", read
);
1534 for (i
= 0; i
< size
; i
++) ok( buffer
[i
] == (BYTE
)i
, "invalid data %x at %x\n", buffer
[i
], i
);
1535 /* But now we need to get informed that the pipe is closed */
1536 ok(ReadFile(piperead
,readbuf
,sizeof(readbuf
),&read
, NULL
) == 0, "Broken pipe not detected\n");
1537 ok(CloseHandle(piperead
), "CloseHandle for the read pipe failed\n");
1538 HeapFree(GetProcessHeap(), 0, buffer
);
1540 ok(user_apc_ran
== FALSE
, "user apc ran, pipe using alertable io mode\n");
1541 SleepEx(0, TRUE
); /* get rid of apc */
1543 ok(CreatePipe(&piperead
, &pipewrite
, &pipe_attr
, 1) != 0, "CreatePipe failed\n");
1544 test_pipe_info(piperead
, FILE_PIPE_SERVER_END
, 1, 1, 1);
1545 test_pipe_info(pipewrite
, 0, 1, 1, 1);
1546 ok(CloseHandle(pipewrite
), "CloseHandle for the Write Pipe failed\n");
1547 ok(CloseHandle(piperead
), "CloseHandle for the read pipe failed\n");
1550 static void test_CloseHandle(void)
1552 static const char testdata
[] = "Hello World";
1553 DWORD state
, numbytes
;
1554 HANDLE hpipe
, hfile
;
1558 hpipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
1559 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1560 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1561 ok(hpipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %u\n", GetLastError());
1563 hfile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1564 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %u\n", GetLastError());
1566 numbytes
= 0xdeadbeef;
1567 ret
= WriteFile(hpipe
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1568 ok(ret
, "WriteFile failed with %u\n", GetLastError());
1569 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1571 numbytes
= 0xdeadbeef;
1572 ret
= PeekNamedPipe(hfile
, NULL
, 0, NULL
, &numbytes
, NULL
);
1573 ok(ret
, "PeekNamedPipe failed with %u\n", GetLastError());
1574 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1576 ret
= CloseHandle(hpipe
);
1577 ok(ret
, "CloseHandle failed with %u\n", GetLastError());
1579 numbytes
= 0xdeadbeef;
1580 memset(buffer
, 0, sizeof(buffer
));
1581 ret
= ReadFile(hfile
, buffer
, 0, &numbytes
, NULL
);
1582 ok(ret
, "ReadFile failed with %u\n", GetLastError());
1583 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
1585 numbytes
= 0xdeadbeef;
1586 ret
= PeekNamedPipe(hfile
, NULL
, 0, NULL
, &numbytes
, NULL
);
1587 ok(ret
, "PeekNamedPipe failed with %u\n", GetLastError());
1588 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1590 numbytes
= 0xdeadbeef;
1591 memset(buffer
, 0, sizeof(buffer
));
1592 ret
= ReadFile(hfile
, buffer
, sizeof(buffer
), &numbytes
, NULL
);
1593 ok(ret
, "ReadFile failed with %u\n", GetLastError());
1594 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1596 ret
= GetNamedPipeHandleStateA(hfile
, &state
, NULL
, NULL
, NULL
, NULL
, 0);
1597 ok(ret
, "GetNamedPipeHandleState failed with %u\n", GetLastError());
1598 state
= PIPE_READMODE_MESSAGE
| PIPE_WAIT
;
1599 ret
= SetNamedPipeHandleState(hfile
, &state
, NULL
, NULL
);
1600 ok(ret
, "SetNamedPipeHandleState failed with %u\n", GetLastError());
1602 SetLastError(0xdeadbeef);
1603 ret
= ReadFile(hfile
, buffer
, 0, &numbytes
, NULL
);
1604 ok(!ret
, "ReadFile unexpectedly succeeded\n");
1605 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1607 numbytes
= 0xdeadbeef;
1608 ret
= PeekNamedPipe(hfile
, NULL
, 0, NULL
, &numbytes
, NULL
);
1609 ok(!ret
&& GetLastError() == ERROR_BROKEN_PIPE
, "PeekNamedPipe returned %x (%u)\n",
1610 ret
, GetLastError());
1611 ok(numbytes
== 0xdeadbeef, "numbytes = %u\n", numbytes
);
1613 SetLastError(0xdeadbeef);
1614 ret
= WriteFile(hfile
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1615 ok(!ret
, "WriteFile unexpectedly succeeded\n");
1616 todo_wine
ok(GetLastError() == ERROR_NO_DATA
, "expected ERROR_NO_DATA, got %u\n", GetLastError());
1620 hpipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
1621 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1622 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1623 ok(hpipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %u\n", GetLastError());
1625 hfile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1626 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %u\n", GetLastError());
1628 numbytes
= 0xdeadbeef;
1629 ret
= WriteFile(hpipe
, testdata
, 0, &numbytes
, NULL
);
1630 ok(ret
, "WriteFile failed with %u\n", GetLastError());
1631 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
1633 ret
= CloseHandle(hpipe
);
1634 ok(ret
, "CloseHandle failed with %u\n", GetLastError());
1636 numbytes
= 0xdeadbeef;
1637 memset(buffer
, 0, sizeof(buffer
));
1638 ret
= ReadFile(hfile
, buffer
, sizeof(buffer
), &numbytes
, NULL
);
1639 ok(ret
, "ReadFile failed with %u\n", GetLastError());
1640 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
1642 SetLastError(0xdeadbeef);
1643 ret
= ReadFile(hfile
, buffer
, 0, &numbytes
, NULL
);
1644 ok(!ret
, "ReadFile unexpectedly succeeded\n");
1645 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1647 ret
= GetNamedPipeHandleStateA(hfile
, &state
, NULL
, NULL
, NULL
, NULL
, 0);
1648 ok(ret
, "GetNamedPipeHandleState failed with %u\n", GetLastError());
1649 state
= PIPE_READMODE_MESSAGE
| PIPE_WAIT
;
1650 ret
= SetNamedPipeHandleState(hfile
, &state
, NULL
, NULL
);
1651 ok(ret
, "SetNamedPipeHandleState failed with %u\n", GetLastError());
1653 SetLastError(0xdeadbeef);
1654 ret
= ReadFile(hfile
, buffer
, 0, &numbytes
, NULL
);
1655 ok(!ret
, "ReadFile unexpectedly succeeded\n");
1656 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1658 SetLastError(0xdeadbeef);
1659 ret
= WriteFile(hfile
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1660 ok(!ret
, "WriteFile unexpectedly succeeded\n");
1661 todo_wine
ok(GetLastError() == ERROR_NO_DATA
, "expected ERROR_NO_DATA, got %u\n", GetLastError());
1665 /* repeat test with hpipe <-> hfile swapped */
1667 hpipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
1668 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1669 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1670 ok(hpipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %u\n", GetLastError());
1672 hfile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1673 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %u\n", GetLastError());
1675 numbytes
= 0xdeadbeef;
1676 ret
= WriteFile(hfile
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1677 ok(ret
, "WriteFile failed with %u\n", GetLastError());
1678 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1680 numbytes
= 0xdeadbeef;
1681 ret
= PeekNamedPipe(hpipe
, NULL
, 0, NULL
, &numbytes
, NULL
);
1682 ok(ret
, "PeekNamedPipe failed with %u\n", GetLastError());
1683 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1685 ret
= CloseHandle(hfile
);
1686 ok(ret
, "CloseHandle failed with %u\n", GetLastError());
1688 numbytes
= 0xdeadbeef;
1689 memset(buffer
, 0, sizeof(buffer
));
1690 ret
= ReadFile(hpipe
, buffer
, 0, &numbytes
, NULL
);
1691 ok(ret
|| GetLastError() == ERROR_MORE_DATA
/* >= Win 8 */,
1692 "ReadFile failed with %u\n", GetLastError());
1693 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
1695 numbytes
= 0xdeadbeef;
1696 ret
= PeekNamedPipe(hpipe
, NULL
, 0, NULL
, &numbytes
, NULL
);
1697 ok(ret
, "PeekNamedPipe failed with %u\n", GetLastError());
1698 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1700 numbytes
= 0xdeadbeef;
1701 memset(buffer
, 0, sizeof(buffer
));
1702 ret
= ReadFile(hpipe
, buffer
, sizeof(buffer
), &numbytes
, NULL
);
1703 ok(ret
, "ReadFile failed with %u\n", GetLastError());
1704 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1706 ret
= GetNamedPipeHandleStateA(hpipe
, &state
, NULL
, NULL
, NULL
, NULL
, 0);
1707 ok(ret
, "GetNamedPipeHandleState failed with %u\n", GetLastError());
1708 state
= PIPE_READMODE_MESSAGE
| PIPE_WAIT
;
1709 ret
= SetNamedPipeHandleState(hpipe
, &state
, NULL
, NULL
);
1710 ok(ret
, "SetNamedPipeHandleState failed with %u\n", GetLastError());
1712 SetLastError(0xdeadbeef);
1713 ret
= ReadFile(hpipe
, buffer
, 0, &numbytes
, NULL
);
1714 ok(!ret
, "ReadFile unexpectedly succeeded\n");
1715 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1717 numbytes
= 0xdeadbeef;
1718 ret
= PeekNamedPipe(hpipe
, NULL
, 0, NULL
, &numbytes
, NULL
);
1719 ok(!ret
&& GetLastError() == ERROR_BROKEN_PIPE
, "PeekNamedPipe returned %x (%u)\n",
1720 ret
, GetLastError());
1721 ok(numbytes
== 0xdeadbeef, "numbytes = %u\n", numbytes
);
1723 SetLastError(0xdeadbeef);
1724 ret
= WriteFile(hpipe
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1725 ok(!ret
, "WriteFile unexpectedly succeeded\n");
1726 todo_wine
ok(GetLastError() == ERROR_NO_DATA
, "expected ERROR_NO_DATA, got %u\n", GetLastError());
1730 hpipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
1731 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1732 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1733 ok(hpipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %u\n", GetLastError());
1735 hfile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1736 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %u\n", GetLastError());
1738 numbytes
= 0xdeadbeef;
1739 ret
= WriteFile(hfile
, testdata
, 0, &numbytes
, NULL
);
1740 ok(ret
, "WriteFile failed with %u\n", GetLastError());
1741 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
1743 ret
= CloseHandle(hfile
);
1744 ok(ret
, "CloseHandle failed with %u\n", GetLastError());
1746 numbytes
= 0xdeadbeef;
1747 memset(buffer
, 0, sizeof(buffer
));
1748 ret
= ReadFile(hpipe
, buffer
, sizeof(buffer
), &numbytes
, NULL
);
1749 ok(ret
, "ReadFile failed with %u\n", GetLastError());
1750 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
1752 SetLastError(0xdeadbeef);
1753 ret
= ReadFile(hpipe
, buffer
, 0, &numbytes
, NULL
);
1754 ok(!ret
, "ReadFile unexpectedly succeeded\n");
1755 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1757 ret
= GetNamedPipeHandleStateA(hpipe
, &state
, NULL
, NULL
, NULL
, NULL
, 0);
1758 ok(ret
, "GetNamedPipeHandleState failed with %u\n", GetLastError());
1759 state
= PIPE_READMODE_MESSAGE
| PIPE_WAIT
;
1760 ret
= SetNamedPipeHandleState(hpipe
, &state
, NULL
, NULL
);
1761 ok(ret
, "SetNamedPipeHandleState failed with %u\n", GetLastError());
1763 SetLastError(0xdeadbeef);
1764 ret
= ReadFile(hpipe
, buffer
, 0, &numbytes
, NULL
);
1765 ok(!ret
, "ReadFile unexpectedly succeeded\n");
1766 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1768 SetLastError(0xdeadbeef);
1769 ret
= WriteFile(hpipe
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1770 ok(!ret
, "WriteFile unexpectedly succeeded\n");
1771 todo_wine
ok(GetLastError() == ERROR_NO_DATA
, "expected ERROR_NO_DATA, got %u\n", GetLastError());
1776 struct named_pipe_client_params
1778 DWORD security_flags
;
1783 #define PIPE_NAME "\\\\.\\pipe\\named_pipe_test"
1785 static DWORD CALLBACK
named_pipe_client_func(LPVOID p
)
1787 struct named_pipe_client_params
*params
= p
;
1790 const char message
[] = "Test";
1791 DWORD bytes_read
, bytes_written
;
1793 TOKEN_PRIVILEGES
*Privileges
= NULL
;
1799 /* modify the token so we can tell if the pipe impersonation
1800 * token reverts to the process token */
1801 ret
= AdjustTokenPrivileges(params
->token
, TRUE
, NULL
, 0, NULL
, NULL
);
1802 ok(ret
, "AdjustTokenPrivileges failed with error %d\n", GetLastError());
1804 ret
= SetThreadToken(NULL
, params
->token
);
1805 ok(ret
, "SetThreadToken failed with error %d\n", GetLastError());
1810 HANDLE process_token
;
1812 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
|TOKEN_ADJUST_PRIVILEGES
, &process_token
);
1813 ok(ret
, "OpenProcessToken failed with error %d\n", GetLastError());
1815 ret
= GetTokenInformation(process_token
, TokenPrivileges
, NULL
, 0, &Size
);
1816 ok(!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "GetTokenInformation(TokenPrivileges) failed with %d\n", GetLastError());
1817 Privileges
= HeapAlloc(GetProcessHeap(), 0, Size
);
1818 ret
= GetTokenInformation(process_token
, TokenPrivileges
, Privileges
, Size
, &Size
);
1819 ok(ret
, "GetTokenInformation(TokenPrivileges) failed with %d\n", GetLastError());
1821 ret
= AdjustTokenPrivileges(process_token
, TRUE
, NULL
, 0, NULL
, NULL
);
1822 ok(ret
, "AdjustTokenPrivileges failed with error %d\n", GetLastError());
1824 CloseHandle(process_token
);
1827 pipe
= CreateFileA(PIPE_NAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, params
->security_flags
, NULL
);
1828 ok(pipe
!= INVALID_HANDLE_VALUE
, "CreateFile for pipe failed with error %d\n", GetLastError());
1830 ret
= WriteFile(pipe
, message
, sizeof(message
), &bytes_written
, NULL
);
1831 ok(ret
, "WriteFile failed with error %d\n", GetLastError());
1833 ret
= ReadFile(pipe
, &dummy
, sizeof(dummy
), &bytes_read
, NULL
);
1834 ok(ret
, "ReadFile failed with error %d\n", GetLastError());
1840 ret
= RevertToSelf();
1841 ok(ret
, "RevertToSelf failed with error %d\n", GetLastError());
1845 ret
= AdjustTokenPrivileges(params
->token
, TRUE
, NULL
, 0, NULL
, NULL
);
1846 ok(ret
, "AdjustTokenPrivileges failed with error %d\n", GetLastError());
1851 HANDLE process_token
;
1853 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES
, &process_token
);
1854 ok(ret
, "OpenProcessToken failed with error %d\n", GetLastError());
1856 ret
= AdjustTokenPrivileges(process_token
, FALSE
, Privileges
, 0, NULL
, NULL
);
1857 ok(ret
, "AdjustTokenPrivileges failed with error %d\n", GetLastError());
1859 HeapFree(GetProcessHeap(), 0, Privileges
);
1861 CloseHandle(process_token
);
1864 ret
= WriteFile(pipe
, message
, sizeof(message
), &bytes_written
, NULL
);
1865 ok(ret
, "WriteFile failed with error %d\n", GetLastError());
1867 ret
= ReadFile(pipe
, &dummy
, sizeof(dummy
), &bytes_read
, NULL
);
1868 ok(ret
, "ReadFile failed with error %d\n", GetLastError());
1875 static HANDLE
make_impersonation_token(DWORD Access
, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
1877 HANDLE ProcessToken
;
1878 HANDLE Token
= NULL
;
1881 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE
, &ProcessToken
);
1882 ok(ret
, "OpenProcessToken failed with error %d\n", GetLastError());
1884 ret
= pDuplicateTokenEx(ProcessToken
, Access
, NULL
, ImpersonationLevel
, TokenImpersonation
, &Token
);
1885 ok(ret
, "DuplicateToken failed with error %d\n", GetLastError());
1887 CloseHandle(ProcessToken
);
1892 static void test_ImpersonateNamedPipeClient(HANDLE hClientToken
, DWORD security_flags
, BOOL revert
, void (*test_func
)(int, HANDLE
))
1901 struct named_pipe_client_params params
;
1903 DWORD dwBytesWritten
;
1904 HANDLE hToken
= NULL
;
1905 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
;
1908 hPipeServer
= CreateNamedPipeA(PIPE_NAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_READMODE_BYTE
| PIPE_WAIT
, 1, 100, 100, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1909 ok(hPipeServer
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with error %d\n", GetLastError());
1911 params
.security_flags
= security_flags
;
1912 params
.token
= hClientToken
;
1913 params
.revert
= revert
;
1914 hThread
= CreateThread(NULL
, 0, named_pipe_client_func
, ¶ms
, 0, &dwTid
);
1915 ok(hThread
!= NULL
, "CreateThread failed with error %d\n", GetLastError());
1917 SetLastError(0xdeadbeef);
1918 ret
= ImpersonateNamedPipeClient(hPipeServer
);
1919 error
= GetLastError();
1920 ok(ret
/* win2k3 */ || (error
== ERROR_CANNOT_IMPERSONATE
),
1921 "ImpersonateNamedPipeClient should have failed with ERROR_CANNOT_IMPERSONATE instead of %d\n", GetLastError());
1923 ret
= ConnectNamedPipe(hPipeServer
, NULL
);
1924 ok(ret
|| (GetLastError() == ERROR_PIPE_CONNECTED
), "ConnectNamedPipe failed with error %d\n", GetLastError());
1926 ret
= ReadFile(hPipeServer
, buffer
, sizeof(buffer
), &dwBytesRead
, NULL
);
1927 ok(ret
, "ReadFile failed with error %d\n", GetLastError());
1929 ret
= ImpersonateNamedPipeClient(hPipeServer
);
1930 ok(ret
, "ImpersonateNamedPipeClient failed with error %d\n", GetLastError());
1932 ret
= OpenThreadToken(GetCurrentThread(), TOKEN_QUERY
, FALSE
, &hToken
);
1933 ok(ret
, "OpenThreadToken failed with error %d\n", GetLastError());
1935 (*test_func
)(0, hToken
);
1937 ImpersonationLevel
= 0xdeadbeef; /* to avoid false positives */
1938 ret
= GetTokenInformation(hToken
, TokenImpersonationLevel
, &ImpersonationLevel
, sizeof(ImpersonationLevel
), &size
);
1939 ok(ret
, "GetTokenInformation(TokenImpersonationLevel) failed with error %d\n", GetLastError());
1940 ok(ImpersonationLevel
== SecurityImpersonation
, "ImpersonationLevel should have been SecurityImpersonation(%d) instead of %d\n", SecurityImpersonation
, ImpersonationLevel
);
1942 CloseHandle(hToken
);
1946 ret
= WriteFile(hPipeServer
, &dummy
, sizeof(dummy
), &dwBytesWritten
, NULL
);
1947 ok(ret
, "WriteFile failed with error %d\n", GetLastError());
1949 ret
= ReadFile(hPipeServer
, buffer
, sizeof(buffer
), &dwBytesRead
, NULL
);
1950 ok(ret
, "ReadFile failed with error %d\n", GetLastError());
1952 ret
= ImpersonateNamedPipeClient(hPipeServer
);
1953 ok(ret
, "ImpersonateNamedPipeClient failed with error %d\n", GetLastError());
1955 ret
= OpenThreadToken(GetCurrentThread(), TOKEN_QUERY
, FALSE
, &hToken
);
1956 ok(ret
, "OpenThreadToken failed with error %d\n", GetLastError());
1958 (*test_func
)(1, hToken
);
1960 CloseHandle(hToken
);
1964 ret
= WriteFile(hPipeServer
, &dummy
, sizeof(dummy
), &dwBytesWritten
, NULL
);
1965 ok(ret
, "WriteFile failed with error %d\n", GetLastError());
1967 WaitForSingleObject(hThread
, INFINITE
);
1969 ret
= ImpersonateNamedPipeClient(hPipeServer
);
1970 ok(ret
, "ImpersonateNamedPipeClient failed with error %d\n", GetLastError());
1974 CloseHandle(hThread
);
1975 CloseHandle(hPipeServer
);
1978 static BOOL
are_all_privileges_disabled(HANDLE hToken
)
1981 TOKEN_PRIVILEGES
*Privileges
= NULL
;
1983 BOOL all_privs_disabled
= TRUE
;
1986 ret
= GetTokenInformation(hToken
, TokenPrivileges
, NULL
, 0, &Size
);
1987 if (!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
1989 Privileges
= HeapAlloc(GetProcessHeap(), 0, Size
);
1990 ret
= GetTokenInformation(hToken
, TokenPrivileges
, Privileges
, Size
, &Size
);
1993 HeapFree(GetProcessHeap(), 0, Privileges
);
2000 for (i
= 0; i
< Privileges
->PrivilegeCount
; i
++)
2002 if (Privileges
->Privileges
[i
].Attributes
& SE_PRIVILEGE_ENABLED
)
2004 all_privs_disabled
= FALSE
;
2009 HeapFree(GetProcessHeap(), 0, Privileges
);
2011 return all_privs_disabled
;
2014 static DWORD
get_privilege_count(HANDLE hToken
)
2016 TOKEN_STATISTICS Statistics
;
2017 DWORD Size
= sizeof(Statistics
);
2020 ret
= GetTokenInformation(hToken
, TokenStatistics
, &Statistics
, Size
, &Size
);
2021 ok(ret
, "GetTokenInformation(TokenStatistics)\n");
2022 if (!ret
) return -1;
2024 return Statistics
.PrivilegeCount
;
2027 static void test_no_sqos_no_token(int call_index
, HANDLE hToken
)
2034 priv_count
= get_privilege_count(hToken
);
2036 ok(priv_count
== 0, "privilege count should have been 0 instead of %d\n", priv_count
);
2039 priv_count
= get_privilege_count(hToken
);
2040 ok(priv_count
> 0, "privilege count should now be > 0 instead of 0\n");
2041 ok(!are_all_privileges_disabled(hToken
), "impersonated token should not have been modified\n");
2044 ok(0, "shouldn't happen\n");
2048 static void test_no_sqos(int call_index
, HANDLE hToken
)
2053 ok(!are_all_privileges_disabled(hToken
), "token should be a copy of the process one\n");
2057 ok(are_all_privileges_disabled(hToken
), "impersonated token should have been modified\n");
2060 ok(0, "shouldn't happen\n");
2064 static void test_static_context(int call_index
, HANDLE hToken
)
2069 ok(!are_all_privileges_disabled(hToken
), "token should be a copy of the process one\n");
2072 ok(!are_all_privileges_disabled(hToken
), "impersonated token should not have been modified\n");
2075 ok(0, "shouldn't happen\n");
2079 static void test_dynamic_context(int call_index
, HANDLE hToken
)
2084 ok(!are_all_privileges_disabled(hToken
), "token should be a copy of the process one\n");
2088 ok(are_all_privileges_disabled(hToken
), "impersonated token should have been modified\n");
2091 ok(0, "shouldn't happen\n");
2095 static void test_dynamic_context_no_token(int call_index
, HANDLE hToken
)
2100 ok(are_all_privileges_disabled(hToken
), "token should be a copy of the process one\n");
2103 ok(!are_all_privileges_disabled(hToken
), "process token modification should have been detected and impersonation token updated\n");
2106 ok(0, "shouldn't happen\n");
2110 static void test_no_sqos_revert(int call_index
, HANDLE hToken
)
2116 priv_count
= get_privilege_count(hToken
);
2118 ok(priv_count
== 0, "privilege count should have been 0 instead of %d\n", priv_count
);
2121 priv_count
= get_privilege_count(hToken
);
2122 ok(priv_count
> 0, "privilege count should now be > 0 instead of 0\n");
2123 ok(!are_all_privileges_disabled(hToken
), "impersonated token should not have been modified\n");
2126 ok(0, "shouldn't happen\n");
2130 static void test_static_context_revert(int call_index
, HANDLE hToken
)
2136 ok(are_all_privileges_disabled(hToken
), "privileges should have been disabled\n");
2140 ok(are_all_privileges_disabled(hToken
), "impersonated token should not have been modified\n");
2143 ok(0, "shouldn't happen\n");
2147 static void test_dynamic_context_revert(int call_index
, HANDLE hToken
)
2153 ok(are_all_privileges_disabled(hToken
), "privileges should have been disabled\n");
2156 ok(!are_all_privileges_disabled(hToken
), "impersonated token should now be process token\n");
2159 ok(0, "shouldn't happen\n");
2163 static void test_impersonation(void)
2165 HANDLE hClientToken
;
2166 HANDLE hProcessToken
;
2169 if( !pDuplicateTokenEx
) {
2170 skip("DuplicateTokenEx not found\n");
2174 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
, &hProcessToken
);
2177 skip("couldn't open process token, skipping impersonation tests\n");
2181 if (!get_privilege_count(hProcessToken
) || are_all_privileges_disabled(hProcessToken
))
2183 skip("token didn't have any privileges or they were all disabled. token not suitable for impersonation tests\n");
2184 CloseHandle(hProcessToken
);
2187 CloseHandle(hProcessToken
);
2189 test_ImpersonateNamedPipeClient(NULL
, 0, FALSE
, test_no_sqos_no_token
);
2190 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2191 test_ImpersonateNamedPipeClient(hClientToken
, 0, FALSE
, test_no_sqos
);
2192 CloseHandle(hClientToken
);
2193 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2194 test_ImpersonateNamedPipeClient(hClientToken
,
2195 SECURITY_SQOS_PRESENT
| SECURITY_IMPERSONATION
, FALSE
,
2196 test_static_context
);
2197 CloseHandle(hClientToken
);
2198 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2199 test_ImpersonateNamedPipeClient(hClientToken
,
2200 SECURITY_SQOS_PRESENT
| SECURITY_CONTEXT_TRACKING
| SECURITY_IMPERSONATION
,
2201 FALSE
, test_dynamic_context
);
2202 CloseHandle(hClientToken
);
2203 test_ImpersonateNamedPipeClient(NULL
,
2204 SECURITY_SQOS_PRESENT
| SECURITY_CONTEXT_TRACKING
| SECURITY_IMPERSONATION
,
2205 FALSE
, test_dynamic_context_no_token
);
2207 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2208 test_ImpersonateNamedPipeClient(hClientToken
, 0, TRUE
, test_no_sqos_revert
);
2209 CloseHandle(hClientToken
);
2210 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2211 test_ImpersonateNamedPipeClient(hClientToken
,
2212 SECURITY_SQOS_PRESENT
| SECURITY_IMPERSONATION
, TRUE
,
2213 test_static_context_revert
);
2214 CloseHandle(hClientToken
);
2215 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2216 test_ImpersonateNamedPipeClient(hClientToken
,
2217 SECURITY_SQOS_PRESENT
| SECURITY_CONTEXT_TRACKING
| SECURITY_IMPERSONATION
,
2218 TRUE
, test_dynamic_context_revert
);
2219 CloseHandle(hClientToken
);
2222 struct overlapped_server_args
2224 HANDLE pipe_created
;
2227 static DWORD CALLBACK
overlapped_server(LPVOID arg
)
2232 struct overlapped_server_args
*a
= arg
;
2236 pipe
= CreateNamedPipeA("\\\\.\\pipe\\my pipe", FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
, PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
, 1, 0, 0, 100000, NULL
);
2237 ok(pipe
!= NULL
, "pipe NULL\n");
2239 ol
.hEvent
= CreateEventA(0, 1, 0, 0);
2240 ok(ol
.hEvent
!= NULL
, "event NULL\n");
2241 ret
= ConnectNamedPipe(pipe
, &ol
);
2242 err
= GetLastError();
2243 ok(ret
== 0, "ret %d\n", ret
);
2244 ok(err
== ERROR_IO_PENDING
, "gle %d\n", err
);
2245 SetEvent(a
->pipe_created
);
2247 ret
= WaitForSingleObjectEx(ol
.hEvent
, INFINITE
, 1);
2248 ok(ret
== WAIT_OBJECT_0
, "ret %x\n", ret
);
2250 ret
= GetOverlappedResult(pipe
, &ol
, &num
, 1);
2251 ok(ret
== 1, "ret %d\n", ret
);
2253 /* This should block */
2254 ret
= ReadFile(pipe
, buf
, sizeof(buf
), &num
, NULL
);
2255 ok(ret
== 1, "ret %d\n", ret
);
2257 DisconnectNamedPipe(pipe
);
2259 ret
= ConnectNamedPipe(pipe
, &ol
);
2260 err
= GetLastError();
2261 ok(ret
== 0, "ret %d\n", ret
);
2262 ok(err
== ERROR_IO_PENDING
, "gle %d\n", err
);
2264 ret
= WaitForSingleObjectEx(ol
.hEvent
, INFINITE
, 1);
2265 ok(ret
== WAIT_OBJECT_0
, "ret %x\n", ret
);
2267 ret
= GetOverlappedResult(pipe
, &ol
, &num
, 1);
2268 err
= GetLastError();
2269 ok(ret
== 0, "ret %d\n", ret
);
2270 ok(err
== ERROR_OPERATION_ABORTED
, "gle %d\n", err
);
2272 CloseHandle(ol
.hEvent
);
2277 static void test_overlapped(void)
2280 HANDLE thread
, pipe
;
2282 struct overlapped_server_args args
;
2284 args
.pipe_created
= CreateEventA(0, 1, 0, 0);
2285 thread
= CreateThread(NULL
, 0, overlapped_server
, &args
, 0, &tid
);
2287 WaitForSingleObject(args
.pipe_created
, INFINITE
);
2288 pipe
= CreateFileA("\\\\.\\pipe\\my pipe", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
2289 ok(pipe
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2291 /* Sleep to try to get the ReadFile in the server to occur before the following WriteFile */
2294 ret
= WriteFile(pipe
, "x", 1, &num
, NULL
);
2295 ok(ret
, "WriteFile failed with error %d\n", GetLastError());
2297 WaitForSingleObject(thread
, INFINITE
);
2299 CloseHandle(args
.pipe_created
);
2300 CloseHandle(thread
);
2303 static void test_overlapped_error(void)
2305 HANDLE pipe
, file
, event
;
2306 DWORD err
, numbytes
;
2307 OVERLAPPED overlapped
;
2310 event
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
2311 ok(event
!= NULL
, "CreateEventA failed with %u\n", GetLastError());
2313 pipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
2314 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
2315 1, 1024, 1024, NMPWAIT_WAIT_FOREVER
, NULL
);
2316 ok(pipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %u\n", GetLastError());
2318 memset(&overlapped
, 0, sizeof(overlapped
));
2319 overlapped
.hEvent
= event
;
2320 ret
= ConnectNamedPipe(pipe
, &overlapped
);
2321 err
= GetLastError();
2322 ok(ret
== FALSE
, "ConnectNamedPipe succeeded\n");
2323 ok(err
== ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %u\n", err
);
2325 file
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
,
2326 OPEN_EXISTING
, FILE_FLAG_OVERLAPPED
, 0);
2327 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %u\n", GetLastError());
2329 numbytes
= 0xdeadbeef;
2330 ret
= GetOverlappedResult(pipe
, &overlapped
, &numbytes
, TRUE
);
2331 ok(ret
== TRUE
, "GetOverlappedResult failed\n");
2332 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
2333 ok(overlapped
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08lx\n", overlapped
.Internal
);
2338 pipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
2339 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
2340 1, 1024, 1024, NMPWAIT_WAIT_FOREVER
, NULL
);
2341 ok(pipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %u\n", GetLastError());
2343 file
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
,
2344 OPEN_EXISTING
, FILE_FLAG_OVERLAPPED
, 0);
2345 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %u\n", GetLastError());
2347 memset(&overlapped
, 0, sizeof(overlapped
));
2348 overlapped
.hEvent
= event
;
2349 ret
= ConnectNamedPipe(pipe
, &overlapped
);
2350 err
= GetLastError();
2351 ok(ret
== FALSE
, "ConnectNamedPipe succeeded\n");
2352 ok(err
== ERROR_PIPE_CONNECTED
, "expected ERROR_PIPE_CONNECTED, got %u\n", err
);
2353 ok(overlapped
.Internal
== STATUS_PENDING
, "expected STATUS_PENDING, got %08lx\n", overlapped
.Internal
);
2361 static void test_NamedPipeHandleState(void)
2363 HANDLE server
, client
;
2365 DWORD state
, instances
, maxCollectionCount
, collectDataTimeout
;
2366 char userName
[MAX_PATH
];
2368 server
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
2369 /* dwOpenMode */ PIPE_TYPE_BYTE
| PIPE_WAIT
,
2370 /* nMaxInstances */ 1,
2371 /* nOutBufSize */ 1024,
2372 /* nInBufSize */ 1024,
2373 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2374 /* lpSecurityAttrib */ NULL
);
2375 ok(server
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2376 ret
= GetNamedPipeHandleStateA(server
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
2377 ok(ret
, "GetNamedPipeHandleState failed: %d\n", GetLastError());
2378 ret
= GetNamedPipeHandleStateA(server
, &state
, &instances
, NULL
, NULL
, NULL
,
2380 ok(ret
, "GetNamedPipeHandleState failed: %d\n", GetLastError());
2383 ok(state
== 0, "unexpected state %08x\n", state
);
2384 ok(instances
== 1, "expected 1 instances, got %d\n", instances
);
2386 /* Some parameters have no meaning, and therefore can't be retrieved,
2389 SetLastError(0xdeadbeef);
2390 ret
= GetNamedPipeHandleStateA(server
, &state
, &instances
,
2391 &maxCollectionCount
, &collectDataTimeout
, userName
,
2392 sizeof(userName
) / sizeof(userName
[0]));
2394 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2395 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2396 /* A byte-mode pipe server can't be changed to message mode. */
2397 state
= PIPE_READMODE_MESSAGE
;
2398 SetLastError(0xdeadbeef);
2399 ret
= SetNamedPipeHandleState(server
, &state
, NULL
, NULL
);
2400 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2401 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2403 client
= CreateFileA(PIPENAME
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
2404 OPEN_EXISTING
, 0, NULL
);
2405 ok(client
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2407 state
= PIPE_READMODE_BYTE
;
2408 ret
= SetNamedPipeHandleState(client
, &state
, NULL
, NULL
);
2409 ok(ret
, "SetNamedPipeHandleState failed: %d\n", GetLastError());
2410 /* A byte-mode pipe client can't be changed to message mode, either. */
2411 state
= PIPE_READMODE_MESSAGE
;
2412 SetLastError(0xdeadbeef);
2413 ret
= SetNamedPipeHandleState(server
, &state
, NULL
, NULL
);
2414 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2415 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2417 CloseHandle(client
);
2418 CloseHandle(server
);
2420 server
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
2421 /* dwOpenMode */ PIPE_TYPE_MESSAGE
| PIPE_WAIT
,
2422 /* nMaxInstances */ 1,
2423 /* nOutBufSize */ 1024,
2424 /* nInBufSize */ 1024,
2425 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2426 /* lpSecurityAttrib */ NULL
);
2427 ok(server
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2428 ret
= GetNamedPipeHandleStateA(server
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
2429 ok(ret
, "GetNamedPipeHandleState failed: %d\n", GetLastError());
2430 ret
= GetNamedPipeHandleStateA(server
, &state
, &instances
, NULL
, NULL
, NULL
,
2432 ok(ret
, "GetNamedPipeHandleState failed: %d\n", GetLastError());
2435 ok(state
== 0, "unexpected state %08x\n", state
);
2436 ok(instances
== 1, "expected 1 instances, got %d\n", instances
);
2438 /* In contrast to byte-mode pipes, a message-mode pipe server can be
2439 * changed to byte mode.
2441 state
= PIPE_READMODE_BYTE
;
2442 ret
= SetNamedPipeHandleState(server
, &state
, NULL
, NULL
);
2443 ok(ret
, "SetNamedPipeHandleState failed: %d\n", GetLastError());
2445 client
= CreateFileA(PIPENAME
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
2446 OPEN_EXISTING
, 0, NULL
);
2447 ok(client
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2449 state
= PIPE_READMODE_MESSAGE
;
2450 ret
= SetNamedPipeHandleState(client
, &state
, NULL
, NULL
);
2451 ok(ret
, "SetNamedPipeHandleState failed: %d\n", GetLastError());
2452 /* A message-mode pipe client can also be changed to byte mode.
2454 state
= PIPE_READMODE_BYTE
;
2455 ret
= SetNamedPipeHandleState(client
, &state
, NULL
, NULL
);
2456 ok(ret
, "SetNamedPipeHandleState failed: %d\n", GetLastError());
2458 CloseHandle(client
);
2459 CloseHandle(server
);
2462 static void test_GetNamedPipeInfo(void)
2466 server
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
2467 /* dwOpenMode */ PIPE_TYPE_BYTE
| PIPE_WAIT
,
2468 /* nMaxInstances */ 1,
2469 /* nOutBufSize */ 1024,
2470 /* nInBufSize */ 1024,
2471 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2472 /* lpSecurityAttrib */ NULL
);
2473 ok(server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
2475 test_pipe_info(server
, PIPE_SERVER_END
| PIPE_TYPE_BYTE
, 1024, 1024, 1);
2477 CloseHandle(server
);
2479 server
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
2480 /* dwOpenMode */ PIPE_TYPE_MESSAGE
| PIPE_NOWAIT
,
2481 /* nMaxInstances */ 3,
2482 /* nOutBufSize */ 1024,
2483 /* nInBufSize */ 1024,
2484 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2485 /* lpSecurityAttrib */ NULL
);
2486 ok(server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
2488 test_pipe_info(server
, PIPE_SERVER_END
| PIPE_TYPE_MESSAGE
, 1024, 1024, 3);
2490 CloseHandle(server
);
2492 server
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
,
2493 /* dwOpenMode */ PIPE_TYPE_MESSAGE
| PIPE_WAIT
,
2494 /* nMaxInstances */ 1,
2495 /* nOutBufSize */ 0,
2497 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2498 /* lpSecurityAttrib */ NULL
);
2499 ok(server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
2501 test_pipe_info(server
, PIPE_SERVER_END
| PIPE_TYPE_MESSAGE
, 0, 0, 1);
2503 CloseHandle(server
);
2505 server
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
,
2506 /* dwOpenMode */ PIPE_TYPE_MESSAGE
| PIPE_WAIT
,
2507 /* nMaxInstances */ 1,
2508 /* nOutBufSize */ 0xf000,
2509 /* nInBufSize */ 0xf000,
2510 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2511 /* lpSecurityAttrib */ NULL
);
2512 ok(server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
2514 test_pipe_info(server
, PIPE_SERVER_END
| PIPE_TYPE_MESSAGE
, 0xf000, 0xf000, 1);
2516 CloseHandle(server
);
2519 static void test_readfileex_pending(void)
2521 HANDLE server
, client
, event
;
2523 DWORD err
, wait
, num_bytes
;
2524 OVERLAPPED overlapped
;
2525 char read_buf
[1024];
2526 char write_buf
[1024];
2527 const char test_string
[] = "test";
2530 server
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
,
2531 /* dwOpenMode */ PIPE_TYPE_BYTE
| PIPE_WAIT
,
2532 /* nMaxInstances */ 1,
2533 /* nOutBufSize */ 1024,
2534 /* nInBufSize */ 1024,
2535 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2536 /* lpSecurityAttrib */ NULL
);
2537 ok(server
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2539 event
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
2540 ok(event
!= NULL
, "CreateEventA failed\n");
2542 memset(&overlapped
, 0, sizeof(overlapped
));
2543 overlapped
.hEvent
= event
;
2545 ret
= ConnectNamedPipe(server
, &overlapped
);
2546 err
= GetLastError();
2547 ok(ret
== FALSE
, "ConnectNamedPipe succeeded\n");
2548 ok(err
== ERROR_IO_PENDING
, "ConnectNamedPipe set error %i\n", err
);
2550 wait
= WaitForSingleObject(event
, 0);
2551 ok(wait
== WAIT_TIMEOUT
, "WaitForSingleObject returned %x\n", wait
);
2553 client
= CreateFileA(PIPENAME
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
2554 OPEN_EXISTING
, 0, NULL
);
2555 ok(client
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2557 wait
= WaitForSingleObject(event
, 0);
2558 ok(wait
== WAIT_OBJECT_0
, "WaitForSingleObject returned %x\n", wait
);
2560 /* Start a read that can't complete immediately. */
2561 completion_called
= 0;
2563 ret
= ReadFileEx(server
, read_buf
, sizeof(read_buf
), &overlapped
, completion_routine
);
2564 ok(ret
== TRUE
, "ReadFileEx failed, err=%i\n", GetLastError());
2565 ok(completion_called
== 0, "completion routine called before ReadFileEx returned\n");
2567 ret
= WriteFile(client
, test_string
, strlen(test_string
), &num_bytes
, NULL
);
2568 ok(ret
== TRUE
, "WriteFile failed\n");
2569 ok(num_bytes
== strlen(test_string
), "only %i bytes written\n", num_bytes
);
2571 ok(completion_called
== 0, "completion routine called during WriteFile\n");
2573 wait
= WaitForSingleObjectEx(event
, 0, TRUE
);
2574 ok(wait
== WAIT_IO_COMPLETION
|| wait
== WAIT_OBJECT_0
, "WaitForSingleObjectEx returned %x\n", wait
);
2576 ok(completion_called
== 1, "completion not called after writing pipe\n");
2577 ok(completion_errorcode
== 0, "completion called with error %x\n", completion_errorcode
);
2578 ok(completion_num_bytes
== strlen(test_string
), "ReadFileEx returned only %d bytes\n", completion_num_bytes
);
2579 ok(completion_lpoverlapped
== &overlapped
, "completion called with wrong overlapped pointer\n");
2580 ok(!memcmp(test_string
, read_buf
, strlen(test_string
)), "ReadFileEx read wrong bytes\n");
2582 /* Make writes until the pipe is full and the write fails */
2583 memset(write_buf
, 0xaa, sizeof(write_buf
));
2584 for (i
=0; i
<256; i
++)
2586 completion_called
= 0;
2588 ret
= WriteFileEx(server
, write_buf
, sizeof(write_buf
), &overlapped
, completion_routine
);
2589 err
= GetLastError();
2591 ok(completion_called
== 0, "completion routine called during WriteFileEx\n");
2593 wait
= WaitForSingleObjectEx(event
, 0, TRUE
);
2595 if (wait
== WAIT_TIMEOUT
)
2596 /* write couldn't complete immediately, presumably the pipe is full */
2599 ok(wait
== WAIT_IO_COMPLETION
|| wait
== WAIT_OBJECT_0
, "WaitForSingleObject returned %x\n", wait
);
2601 ok(ret
== TRUE
, "WriteFileEx failed, err=%i\n", err
);
2602 ok(completion_errorcode
== 0, "completion called with error %x\n", completion_errorcode
);
2603 ok(completion_lpoverlapped
== &overlapped
, "completion called with wrong overlapped pointer\n");
2606 ok(ret
== TRUE
, "WriteFileEx failed, err=%i\n", err
);
2607 ok(completion_called
== 0, "completion routine called but wait timed out\n");
2608 ok(completion_errorcode
== 0, "completion called with error %x\n", completion_errorcode
);
2609 ok(completion_lpoverlapped
== &overlapped
, "completion called with wrong overlapped pointer\n");
2611 /* free up some space in the pipe */
2612 for (i
=0; i
<256; i
++)
2614 ret
= ReadFile(client
, read_buf
, sizeof(read_buf
), &num_bytes
, NULL
);
2615 ok(ret
== TRUE
, "ReadFile failed\n");
2617 ok(completion_called
== 0, "completion routine called during ReadFile\n");
2619 wait
= WaitForSingleObjectEx(event
, 0, TRUE
);
2620 ok(wait
== WAIT_IO_COMPLETION
|| wait
== WAIT_OBJECT_0
|| wait
== WAIT_TIMEOUT
,
2621 "WaitForSingleObject returned %x\n", wait
);
2622 if (wait
!= WAIT_TIMEOUT
) break;
2625 ok(completion_called
== 1, "completion routine not called\n");
2626 ok(completion_errorcode
== 0, "completion called with error %x\n", completion_errorcode
);
2627 ok(completion_lpoverlapped
== &overlapped
, "completion called with wrong overlapped pointer\n");
2629 num_bytes
= 0xdeadbeef;
2630 SetLastError(0xdeadbeef);
2631 ret
= ReadFile(INVALID_HANDLE_VALUE
, read_buf
, 0, &num_bytes
, NULL
);
2632 ok(!ret
, "ReadFile should fail\n");
2633 ok(GetLastError() == ERROR_INVALID_HANDLE
, "wrong error %u\n", GetLastError());
2634 ok(num_bytes
== 0, "expected 0, got %u\n", num_bytes
);
2636 S(U(overlapped
)).Offset
= 0;
2637 S(U(overlapped
)).OffsetHigh
= 0;
2638 overlapped
.Internal
= -1;
2639 overlapped
.InternalHigh
= -1;
2640 overlapped
.hEvent
= event
;
2641 num_bytes
= 0xdeadbeef;
2642 SetLastError(0xdeadbeef);
2643 ret
= ReadFile(server
, read_buf
, 0, &num_bytes
, &overlapped
);
2644 ok(!ret
, "ReadFile should fail\n");
2645 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
2646 ok(num_bytes
== 0, "bytes %u\n", num_bytes
);
2647 ok((NTSTATUS
)overlapped
.Internal
== STATUS_PENDING
, "expected STATUS_PENDING, got %#lx\n", overlapped
.Internal
);
2648 ok(overlapped
.InternalHigh
== -1, "expected -1, got %lu\n", overlapped
.InternalHigh
);
2650 wait
= WaitForSingleObject(event
, 100);
2651 ok(wait
== WAIT_TIMEOUT
, "WaitForSingleObject returned %x\n", wait
);
2653 num_bytes
= 0xdeadbeef;
2654 ret
= WriteFile(client
, test_string
, 1, &num_bytes
, NULL
);
2655 ok(ret
, "WriteFile failed\n");
2656 ok(num_bytes
== 1, "bytes %u\n", num_bytes
);
2658 wait
= WaitForSingleObject(event
, 100);
2659 ok(wait
== WAIT_OBJECT_0
, "WaitForSingleObject returned %x\n", wait
);
2661 ok(num_bytes
== 1, "bytes %u\n", num_bytes
);
2662 ok((NTSTATUS
)overlapped
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", overlapped
.Internal
);
2663 ok(overlapped
.InternalHigh
== 0, "expected 0, got %lu\n", overlapped
.InternalHigh
);
2665 /* read the pending byte and clear the pipe */
2666 num_bytes
= 0xdeadbeef;
2667 ret
= ReadFile(server
, read_buf
, 1, &num_bytes
, &overlapped
);
2668 ok(ret
, "ReadFile failed\n");
2669 ok(num_bytes
== 1, "bytes %u\n", num_bytes
);
2671 CloseHandle(client
);
2672 CloseHandle(server
);
2676 #define test_peek_pipe(a,b,c,d) _test_peek_pipe(__LINE__,a,b,c,d)
2677 static void _test_peek_pipe(unsigned line
, HANDLE pipe
, DWORD expected_read
, DWORD expected_avail
, DWORD expected_message_length
)
2679 DWORD bytes_read
= 0xdeadbeed, avail
= 0xdeadbeef, left
= 0xdeadbeed;
2681 FILE_PIPE_PEEK_BUFFER
*peek_buf
= (void*)buf
;
2686 r
= PeekNamedPipe(pipe
, buf
, sizeof(buf
), &bytes_read
, &avail
, &left
);
2687 ok_(__FILE__
,line
)(r
, "PeekNamedPipe failed: %u\n", GetLastError());
2688 ok_(__FILE__
,line
)(bytes_read
== expected_read
, "bytes_read = %u, expected %u\n", bytes_read
, expected_read
);
2689 ok_(__FILE__
,line
)(avail
== expected_avail
, "avail = %u, expected %u\n", avail
, expected_avail
);
2690 ok_(__FILE__
,line
)(left
== expected_message_length
- expected_read
, "left = %d, expected %d\n",
2691 left
, expected_message_length
- expected_read
);
2693 status
= NtFsControlFile(pipe
, 0, NULL
, NULL
, &io
, FSCTL_PIPE_PEEK
, NULL
, 0, buf
, sizeof(buf
));
2694 ok_(__FILE__
,line
)(!status
|| status
== STATUS_PENDING
, "NtFsControlFile(FSCTL_PIPE_PEEK) failed: %x\n", status
);
2695 ok_(__FILE__
,line
)(io
.Information
== FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER
, Data
[expected_read
]),
2696 "io.Information = %lu\n", io
.Information
);
2697 ok_(__FILE__
,line
)(peek_buf
->ReadDataAvailable
== expected_avail
, "ReadDataAvailable = %u, expected %u\n",
2698 peek_buf
->ReadDataAvailable
, expected_avail
);
2699 ok_(__FILE__
,line
)(peek_buf
->MessageLength
== expected_message_length
, "MessageLength = %u, expected %u\n",
2700 peek_buf
->MessageLength
, expected_message_length
);
2704 r
= PeekNamedPipe(pipe
, buf
, 1, &bytes_read
, &avail
, &left
);
2705 ok_(__FILE__
,line
)(r
, "PeekNamedPipe failed: %u\n", GetLastError());
2706 ok_(__FILE__
,line
)(bytes_read
== 1, "bytes_read = %u, expected %u\n", bytes_read
, expected_read
);
2707 ok_(__FILE__
,line
)(avail
== expected_avail
, "avail = %u, expected %u\n", avail
, expected_avail
);
2708 ok_(__FILE__
,line
)(left
== expected_message_length
-1, "left = %d, expected %d\n", left
, expected_message_length
-1);
2712 #define overlapped_read_sync(a,b,c,d,e) _overlapped_read_sync(__LINE__,a,b,c,d,e)
2713 static void _overlapped_read_sync(unsigned line
, HANDLE reader
, void *buf
, DWORD buf_size
, DWORD expected_result
, BOOL partial_read
)
2715 DWORD read_bytes
= 0xdeadbeef;
2716 OVERLAPPED overlapped
;
2719 memset(&overlapped
, 0, sizeof(overlapped
));
2720 overlapped
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
2721 res
= ReadFile(reader
, buf
, buf_size
, &read_bytes
, &overlapped
);
2723 ok_(__FILE__
,line
)(!res
&& GetLastError() == ERROR_MORE_DATA
, "ReadFile returned: %x (%u)\n", res
, GetLastError());
2725 ok_(__FILE__
,line
)(res
, "ReadFile failed: %u\n", GetLastError());
2727 ok_(__FILE__
,line
)(!read_bytes
, "read_bytes %u expected 0\n", read_bytes
);
2729 ok_(__FILE__
,line
)(read_bytes
== expected_result
, "read_bytes %u expected %u\n", read_bytes
, expected_result
);
2731 read_bytes
= 0xdeadbeef;
2732 res
= GetOverlappedResult(reader
, &overlapped
, &read_bytes
, FALSE
);
2734 ok_(__FILE__
,line
)(!res
&& GetLastError() == ERROR_MORE_DATA
,
2735 "GetOverlappedResult returned: %x (%u)\n", res
, GetLastError());
2737 ok_(__FILE__
,line
)(res
, "GetOverlappedResult failed: %u\n", GetLastError());
2738 ok_(__FILE__
,line
)(read_bytes
== expected_result
, "read_bytes %u expected %u\n", read_bytes
, expected_result
);
2739 CloseHandle(overlapped
.hEvent
);
2742 #define overlapped_read_async(a,b,c,d) _overlapped_read_async(__LINE__,a,b,c,d)
2743 static void _overlapped_read_async(unsigned line
, HANDLE reader
, void *buf
, DWORD buf_size
, OVERLAPPED
*overlapped
)
2745 DWORD read_bytes
= 0xdeadbeef;
2748 memset(overlapped
, 0, sizeof(*overlapped
));
2749 overlapped
->hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
2750 res
= ReadFile(reader
, buf
, buf_size
, &read_bytes
, overlapped
);
2751 ok_(__FILE__
,line
)(!res
&& GetLastError() == ERROR_IO_PENDING
, "ReadFile returned %x(%u)\n", res
, GetLastError());
2752 ok_(__FILE__
,line
)(!read_bytes
, "read_bytes %u expected 0\n", read_bytes
);
2754 _test_not_signaled(line
, overlapped
->hEvent
);
2757 #define overlapped_write_sync(a,b,c) _overlapped_write_sync(__LINE__,a,b,c)
2758 static void _overlapped_write_sync(unsigned line
, HANDLE writer
, void *buf
, DWORD size
)
2760 DWORD written_bytes
= 0xdeadbeef;
2761 OVERLAPPED overlapped
;
2764 memset(&overlapped
, 0, sizeof(overlapped
));
2765 overlapped
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
2766 res
= WriteFile(writer
, buf
, size
, &written_bytes
, &overlapped
);
2767 ok_(__FILE__
,line
)(res
, "WriteFile returned %x(%u)\n", res
, GetLastError());
2768 ok_(__FILE__
,line
)(written_bytes
== size
, "WriteFile returned written_bytes = %u\n", written_bytes
);
2770 written_bytes
= 0xdeadbeef;
2771 res
= GetOverlappedResult(writer
, &overlapped
, &written_bytes
, FALSE
);
2772 ok_(__FILE__
,line
)(res
, "GetOverlappedResult failed: %u\n", GetLastError());
2773 ok_(__FILE__
,line
)(written_bytes
== size
, "GetOverlappedResult returned written_bytes %u expected %u\n", written_bytes
, size
);
2775 CloseHandle(overlapped
.hEvent
);
2778 #define overlapped_write_async(a,b,c,d) _overlapped_write_async(__LINE__,a,b,c,d)
2779 static void _overlapped_write_async(unsigned line
, HANDLE writer
, void *buf
, DWORD size
, OVERLAPPED
*overlapped
)
2781 DWORD written_bytes
= 0xdeadbeef;
2784 memset(overlapped
, 0, sizeof(*overlapped
));
2785 overlapped
->hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
2786 res
= WriteFile(writer
, buf
, size
, &written_bytes
, overlapped
);
2787 ok_(__FILE__
,line
)(!res
&& GetLastError() == ERROR_IO_PENDING
, "WriteFile returned %x(%u)\n", res
, GetLastError());
2788 ok_(__FILE__
,line
)(!written_bytes
, "written_bytes = %u\n", written_bytes
);
2790 _test_not_signaled(line
, overlapped
->hEvent
);
2793 #define test_flush_sync(a) _test_flush_sync(__LINE__,a)
2794 static void _test_flush_sync(unsigned line
, HANDLE pipe
)
2798 res
= FlushFileBuffers(pipe
);
2799 ok_(__FILE__
,line
)(res
, "FlushFileBuffers failed: %u\n", GetLastError());
2802 static DWORD expected_flush_error
;
2804 static DWORD CALLBACK
flush_proc(HANDLE pipe
)
2808 res
= FlushFileBuffers(pipe
);
2809 if (expected_flush_error
== ERROR_SUCCESS
)
2810 ok(res
, "FlushFileBuffers failed: %u\n", GetLastError());
2812 todo_wine
ok(!res
&& GetLastError() == expected_flush_error
, "FlushFileBuffers failed: %u\n", GetLastError());
2816 #define test_flush_async(a,b) _test_flush_async(__LINE__,a,b)
2817 static HANDLE
_test_flush_async(unsigned line
, HANDLE pipe
, DWORD error
)
2822 expected_flush_error
= error
;
2823 thread
= CreateThread(NULL
, 0, flush_proc
, pipe
, 0, &tid
);
2824 ok_(__FILE__
,line
)(thread
!= NULL
, "CreateThread failed: %u\n", GetLastError());
2827 _test_not_signaled(line
, thread
);
2831 #define test_flush_done(a) _test_flush_done(__LINE__,a)
2832 static void _test_flush_done(unsigned line
, HANDLE thread
)
2834 DWORD res
= WaitForSingleObject(thread
, 1000);
2835 ok_(__FILE__
,line
)(res
== WAIT_OBJECT_0
, "WaitForSingleObject returned %u (%u)\n", res
, GetLastError());
2836 CloseHandle(thread
);
2839 #define test_overlapped_result(a,b,c,d) _test_overlapped_result(__LINE__,a,b,c,d)
2840 static void _test_overlapped_result(unsigned line
, HANDLE handle
, OVERLAPPED
*overlapped
, DWORD expected_result
, BOOL partial_read
)
2842 DWORD result
= 0xdeadbeef;
2845 _test_signaled(line
, overlapped
->hEvent
);
2847 res
= GetOverlappedResult(handle
, overlapped
, &result
, FALSE
);
2849 ok_(__FILE__
,line
)(!res
&& GetLastError() == ERROR_MORE_DATA
, "GetOverlappedResult returned: %x (%u)\n", res
, GetLastError());
2851 ok_(__FILE__
,line
)(res
, "GetOverlappedResult failed: %u\n", GetLastError());
2852 ok_(__FILE__
,line
)(result
== expected_result
, "read_bytes = %u, expected %u\n", result
, expected_result
);
2853 CloseHandle(overlapped
->hEvent
);
2856 #define test_overlapped_failure(a,b,c) _test_overlapped_failure(__LINE__,a,b,c)
2857 static void _test_overlapped_failure(unsigned line
, HANDLE handle
, OVERLAPPED
*overlapped
, DWORD error
)
2862 _test_signaled(line
, overlapped
->hEvent
);
2864 res
= GetOverlappedResult(handle
, overlapped
, &result
, FALSE
);
2865 ok_(__FILE__
,line
)(!res
&& GetLastError() == error
, "GetOverlappedResult returned: %x (%u), expected error %u\n",
2866 res
, GetLastError(), error
);
2867 ok_(__FILE__
,line
)(!result
, "result = %u\n", result
);
2868 CloseHandle(overlapped
->hEvent
);
2871 #define cancel_overlapped(a,b) _cancel_overlapped(__LINE__,a,b)
2872 static void _cancel_overlapped(unsigned line
, HANDLE handle
, OVERLAPPED
*overlapped
)
2876 res
= pCancelIoEx(handle
, overlapped
);
2877 ok_(__FILE__
,line
)(res
, "CancelIoEx failed: %u\n", GetLastError());
2879 _test_overlapped_failure(line
, handle
, overlapped
, ERROR_OPERATION_ABORTED
);
2882 static void test_blocking_rw(HANDLE writer
, HANDLE reader
, DWORD buf_size
, BOOL msg_mode
, BOOL msg_read
)
2884 OVERLAPPED read_overlapped
, read_overlapped2
, write_overlapped
, write_overlapped2
;
2885 char buf
[10000], read_buf
[10000];
2886 HANDLE flush_thread
;
2888 memset(buf
, 0xaa, sizeof(buf
));
2890 /* test pending read with overlapped event */
2891 overlapped_read_async(reader
, read_buf
, 1000, &read_overlapped
);
2892 test_flush_sync(writer
);
2893 test_peek_pipe(reader
, 0, 0, 0);
2895 /* write more data than needed for read */
2896 overlapped_write_sync(writer
, buf
, 4000);
2897 test_overlapped_result(reader
, &read_overlapped
, 1000, msg_read
);
2899 /* test pending write with overlapped event */
2900 overlapped_write_async(writer
, buf
, buf_size
, &write_overlapped
);
2902 /* write one more byte */
2903 overlapped_write_async(writer
, buf
, 1, &write_overlapped2
);
2904 flush_thread
= test_flush_async(writer
, ERROR_SUCCESS
);
2905 test_not_signaled(write_overlapped
.hEvent
);
2907 /* empty write will not block */
2908 overlapped_write_sync(writer
, buf
, 0);
2909 test_not_signaled(write_overlapped
.hEvent
);
2910 test_not_signaled(write_overlapped2
.hEvent
);
2912 /* read remaining data from the first write */
2913 overlapped_read_sync(reader
, read_buf
, 3000, 3000, FALSE
);
2914 test_overlapped_result(writer
, &write_overlapped
, buf_size
, FALSE
);
2915 test_not_signaled(write_overlapped2
.hEvent
);
2916 test_not_signaled(flush_thread
);
2918 /* read one byte so that the next write fits the buffer */
2919 overlapped_read_sync(reader
, read_buf
, 1, 1, msg_read
);
2920 test_overlapped_result(writer
, &write_overlapped2
, 1, FALSE
);
2922 /* read the whole buffer */
2923 overlapped_read_sync(reader
, read_buf
, buf_size
, buf_size
-msg_read
, FALSE
);
2926 overlapped_read_sync(reader
, read_buf
, 1000, 1, FALSE
);
2929 /* we still have an empty message in queue */
2930 overlapped_read_sync(reader
, read_buf
, 1000, 0, FALSE
);
2932 test_flush_done(flush_thread
);
2934 /* pipe is empty, the next read will block */
2935 overlapped_read_async(reader
, read_buf
, 0, &read_overlapped
);
2936 overlapped_read_async(reader
, read_buf
, 1000, &read_overlapped2
);
2938 /* write one byte */
2939 overlapped_write_sync(writer
, buf
, 1);
2940 test_overlapped_result(reader
, &read_overlapped
, 0, msg_read
);
2941 test_overlapped_result(reader
, &read_overlapped2
, 1, FALSE
);
2943 /* write a message larger than buffer */
2944 overlapped_write_async(writer
, buf
, buf_size
+2000, &write_overlapped
);
2946 /* read so that pending write is still larger than the buffer */
2947 overlapped_read_sync(reader
, read_buf
, 1999, 1999, msg_read
);
2948 test_not_signaled(write_overlapped
.hEvent
);
2950 /* read one more byte */
2951 overlapped_read_sync(reader
, read_buf
, 1, 1, msg_read
);
2952 test_overlapped_result(writer
, &write_overlapped
, buf_size
+2000, FALSE
);
2954 /* read remaining data */
2955 overlapped_read_sync(reader
, read_buf
, buf_size
+1, buf_size
, FALSE
);
2957 /* simple pass of empty message */
2958 overlapped_write_sync(writer
, buf
, 0);
2960 overlapped_read_sync(reader
, read_buf
, 1, 0, FALSE
);
2962 /* pipe is empty, the next read will block */
2963 test_flush_sync(writer
);
2964 overlapped_read_async(reader
, read_buf
, 0, &read_overlapped
);
2965 overlapped_read_async(reader
, read_buf
, 1, &read_overlapped2
);
2967 /* 0 length write wakes one read in msg mode */
2968 overlapped_write_sync(writer
, buf
, 0);
2970 test_overlapped_result(reader
, &read_overlapped
, 0, FALSE
);
2972 test_not_signaled(read_overlapped
.hEvent
);
2973 test_not_signaled(read_overlapped2
.hEvent
);
2974 overlapped_write_sync(writer
, buf
, 1);
2975 test_overlapped_result(reader
, &read_overlapped2
, 1, FALSE
);
2977 overlapped_write_sync(writer
, buf
, 20);
2978 test_peek_pipe(reader
, 20, 20, msg_mode
? 20 : 0);
2979 overlapped_write_sync(writer
, buf
, 15);
2980 test_peek_pipe(reader
, msg_mode
? 20 : 35, 35, msg_mode
? 20 : 0);
2981 overlapped_read_sync(reader
, read_buf
, 10, 10, msg_read
);
2982 test_peek_pipe(reader
, msg_mode
? 10 : 25, 25, msg_mode
? 10 : 0);
2983 overlapped_read_sync(reader
, read_buf
, 10, 10, FALSE
);
2984 test_peek_pipe(reader
, 15, 15, msg_mode
? 15 : 0);
2985 overlapped_read_sync(reader
, read_buf
, 15, 15, FALSE
);
2988 win_skip("CancelIoEx not available\n");
2992 /* add one more pending read, then cancel the first one */
2993 overlapped_read_async(reader
, read_buf
, 1, &read_overlapped
);
2994 overlapped_read_async(reader
, read_buf
, 1, &read_overlapped2
);
2995 cancel_overlapped(reader
, &read_overlapped2
);
2996 test_not_signaled(read_overlapped
.hEvent
);
2997 overlapped_write_sync(writer
, buf
, 1);
2998 test_overlapped_result(reader
, &read_overlapped
, 1, FALSE
);
3000 /* make two async writes, cancel the first one and make sure that we read from the second one */
3001 overlapped_write_async(writer
, buf
, buf_size
+2000, &write_overlapped
);
3002 overlapped_write_async(writer
, buf
, 1, &write_overlapped2
);
3003 cancel_overlapped(writer
, &write_overlapped
);
3004 overlapped_read_sync(reader
, read_buf
, 1000, 1, FALSE
);
3005 test_overlapped_result(writer
, &write_overlapped2
, 1, FALSE
);
3007 /* same as above, but parially read written data before canceling */
3008 overlapped_write_async(writer
, buf
, buf_size
+2000, &write_overlapped
);
3009 overlapped_write_async(writer
, buf
, 1, &write_overlapped2
);
3010 overlapped_read_sync(reader
, read_buf
, 10, 10, msg_read
);
3011 test_not_signaled(write_overlapped
.hEvent
);
3012 cancel_overlapped(writer
, &write_overlapped
);
3013 overlapped_read_sync(reader
, read_buf
, 1000, 1, FALSE
);
3014 test_overlapped_result(writer
, &write_overlapped2
, 1, FALSE
);
3016 /* empty queue by canceling write and make sure that flush is signaled */
3017 overlapped_write_async(writer
, buf
, buf_size
+2000, &write_overlapped
);
3018 flush_thread
= test_flush_async(writer
, ERROR_SUCCESS
);
3019 test_not_signaled(flush_thread
);
3020 cancel_overlapped(writer
, &write_overlapped
);
3021 test_flush_done(flush_thread
);
3024 static void child_process_write_pipe(HANDLE pipe
)
3026 OVERLAPPED overlapped
;
3029 memset(buf
, 'x', sizeof(buf
));
3030 overlapped_write_async(pipe
, buf
, sizeof(buf
), &overlapped
);
3032 /* sleep until parent process terminates this process */
3036 static HANDLE
create_writepipe_process(HANDLE pipe
)
3038 STARTUPINFOA si
= { sizeof(si
) };
3039 PROCESS_INFORMATION info
;
3040 char **argv
, buf
[MAX_PATH
];
3043 winetest_get_mainargs(&argv
);
3044 sprintf(buf
, "\"%s\" pipe writepipe %lx", argv
[0], (UINT_PTR
)pipe
);
3045 res
= CreateProcessA(NULL
, buf
, NULL
, NULL
, TRUE
, 0L, NULL
, NULL
, &si
, &info
);
3046 ok(res
, "CreateProcess failed: %u\n", GetLastError());
3047 CloseHandle(info
.hThread
);
3049 return info
.hProcess
;
3052 static void create_overlapped_pipe(DWORD mode
, HANDLE
*client
, HANDLE
*server
)
3054 SECURITY_ATTRIBUTES sec_attr
= { sizeof(sec_attr
), NULL
, TRUE
};
3055 DWORD read_mode
= mode
& (PIPE_READMODE_BYTE
| PIPE_READMODE_MESSAGE
);
3056 OVERLAPPED overlapped
;
3059 *server
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
,
3060 PIPE_WAIT
| mode
, 1, 5000, 6000, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
3061 ok(&server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed: %u\n", GetLastError());
3062 test_signaled(*server
);
3064 memset(&overlapped
, 0, sizeof(overlapped
));
3065 overlapped
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
3066 res
= ConnectNamedPipe(*server
, &overlapped
);
3067 ok(!res
&& GetLastError() == ERROR_IO_PENDING
, "WriteFile returned %x(%u)\n", res
, GetLastError());
3068 test_not_signaled(*server
);
3069 test_not_signaled(overlapped
.hEvent
);
3071 *client
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, &sec_attr
, OPEN_EXISTING
, FILE_FLAG_OVERLAPPED
, NULL
);
3072 ok(*server
!= INVALID_HANDLE_VALUE
, "CreateFile failed: %u\n", GetLastError());
3074 res
= SetNamedPipeHandleState(*client
, &read_mode
, NULL
, NULL
);
3075 ok(res
, "SetNamedPipeHandleState failed: %u\n", GetLastError());
3077 test_signaled(*client
);
3078 test_not_signaled(*server
);
3079 test_overlapped_result(*server
, &overlapped
, 0, FALSE
);
3082 static void test_overlapped_transport(BOOL msg_mode
, BOOL msg_read_mode
)
3084 OVERLAPPED overlapped
, overlapped2
;
3085 HANDLE server
, client
, flush
;
3091 DWORD create_flags
=
3092 (msg_mode
? PIPE_TYPE_MESSAGE
: PIPE_TYPE_BYTE
) |
3093 (msg_read_mode
? PIPE_READMODE_MESSAGE
: PIPE_READMODE_BYTE
);
3095 create_overlapped_pipe(create_flags
, &client
, &server
);
3097 trace("testing %s, %s server->client writes...\n",
3098 msg_mode
? "message mode" : "byte mode", msg_read_mode
? "message read" : "byte read");
3099 test_blocking_rw(server
, client
, 5000, msg_mode
, msg_read_mode
);
3100 trace("testing %s, %s client->server writes...\n",
3101 msg_mode
? "message mode" : "byte mode", msg_read_mode
? "message read" : "byte read");
3102 test_blocking_rw(client
, server
, 6000, msg_mode
, msg_read_mode
);
3104 CloseHandle(client
);
3105 CloseHandle(server
);
3107 /* close client with pending writes */
3108 create_overlapped_pipe(create_flags
, &client
, &server
);
3109 overlapped_write_async(server
, buf
, 7000, &overlapped
);
3110 flush
= test_flush_async(server
, ERROR_BROKEN_PIPE
);
3111 CloseHandle(client
);
3112 test_overlapped_failure(server
, &overlapped
, ERROR_BROKEN_PIPE
);
3113 test_flush_done(flush
);
3114 CloseHandle(server
);
3116 /* close server with pending writes */
3117 create_overlapped_pipe(create_flags
, &client
, &server
);
3118 overlapped_write_async(client
, buf
, 7000, &overlapped
);
3119 flush
= test_flush_async(client
, ERROR_BROKEN_PIPE
);
3120 CloseHandle(server
);
3121 test_overlapped_failure(client
, &overlapped
, ERROR_BROKEN_PIPE
);
3122 test_flush_done(flush
);
3123 CloseHandle(client
);
3125 /* disconnect with pending writes */
3126 create_overlapped_pipe(create_flags
, &client
, &server
);
3127 overlapped_write_async(client
, buf
, 7000, &overlapped
);
3128 overlapped_write_async(server
, buf
, 7000, &overlapped2
);
3129 flush
= test_flush_async(client
, ERROR_PIPE_NOT_CONNECTED
);
3130 res
= DisconnectNamedPipe(server
);
3131 ok(res
, "DisconnectNamedPipe failed: %u\n", GetLastError());
3132 test_overlapped_failure(client
, &overlapped
, ERROR_PIPE_NOT_CONNECTED
);
3133 test_overlapped_failure(client
, &overlapped2
, ERROR_PIPE_NOT_CONNECTED
);
3134 test_flush_done(flush
);
3135 CloseHandle(server
);
3136 CloseHandle(client
);
3138 /* terminate process with pending write */
3139 create_overlapped_pipe(create_flags
, &client
, &server
);
3140 process
= create_writepipe_process(client
);
3141 /* successfully read part of write that is pending in child process */
3142 res
= ReadFile(server
, buf
, 10, &read_bytes
, NULL
);
3144 ok(res
, "ReadFile failed: %u\n", GetLastError());
3146 ok(!res
&& GetLastError() == ERROR_MORE_DATA
, "ReadFile returned: %x %u\n", res
, GetLastError());
3147 ok(read_bytes
== 10, "read_bytes = %u\n", read_bytes
);
3148 TerminateProcess(process
, 0);
3149 winetest_wait_child_process(process
);
3150 /* after terminating process, there is no pending write and pipe buffer is empty */
3151 overlapped_read_async(server
, buf
, 10, &overlapped
);
3152 overlapped_write_sync(client
, buf
, 1);
3153 test_overlapped_result(server
, &overlapped
, 1, FALSE
);
3154 CloseHandle(process
);
3155 CloseHandle(server
);
3156 CloseHandle(client
);
3165 hmod
= GetModuleHandleA("advapi32.dll");
3166 pDuplicateTokenEx
= (void *) GetProcAddress(hmod
, "DuplicateTokenEx");
3167 hmod
= GetModuleHandleA("kernel32.dll");
3168 pQueueUserAPC
= (void *) GetProcAddress(hmod
, "QueueUserAPC");
3169 pCancelIoEx
= (void *) GetProcAddress(hmod
, "CancelIoEx");
3171 argc
= winetest_get_mainargs(&argv
);
3173 if (argc
> 3 && !strcmp(argv
[2], "writepipe"))
3176 sscanf(argv
[3], "%lx", &handle
);
3177 child_process_write_pipe((HANDLE
)handle
);
3181 if (test_DisconnectNamedPipe())
3183 test_CreateNamedPipe_instances_must_match();
3185 test_CreateNamedPipe(PIPE_TYPE_BYTE
);
3186 test_CreateNamedPipe(PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
);
3190 test_impersonation();
3192 test_overlapped_error();
3193 test_NamedPipeHandleState();
3194 test_GetNamedPipeInfo();
3195 test_readfileex_pending();
3196 test_overlapped_transport(TRUE
, FALSE
);
3197 test_overlapped_transport(TRUE
, TRUE
);
3198 test_overlapped_transport(FALSE
, FALSE
);