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"
34 #define NB_SERVER_LOOPS 8
36 static HANDLE alarm_event
;
37 static BOOL (WINAPI
*pDuplicateTokenEx
)(HANDLE
,DWORD
,LPSECURITY_ATTRIBUTES
,
38 SECURITY_IMPERSONATION_LEVEL
,TOKEN_TYPE
,PHANDLE
);
39 static DWORD (WINAPI
*pQueueUserAPC
)(PAPCFUNC pfnAPC
, HANDLE hThread
, ULONG_PTR dwData
);
40 static BOOL (WINAPI
*pCancelIoEx
)(HANDLE handle
, LPOVERLAPPED lpOverlapped
);
42 static BOOL user_apc_ran
;
43 static void CALLBACK
user_apc(ULONG_PTR param
)
56 ULONG_PTR returnValue
;
62 static DWORD CALLBACK
rpcThreadMain(LPVOID arg
)
64 struct rpcThreadArgs
*rpcargs
= (struct rpcThreadArgs
*)arg
;
65 if (winetest_debug
> 1) trace("rpcThreadMain starting\n");
66 SetLastError( rpcargs
->lastError
);
71 rpcargs
->returnValue
= (ULONG_PTR
)ReadFile( (HANDLE
)rpcargs
->args
[0], /* hFile */
72 (LPVOID
)rpcargs
->args
[1], /* buffer */
73 (DWORD
)rpcargs
->args
[2], /* bytesToRead */
74 (LPDWORD
)rpcargs
->args
[3], /* bytesRead */
75 (LPOVERLAPPED
)rpcargs
->args
[4] ); /* overlapped */
79 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
80 rpcargs
->returnValue
= 0;
84 rpcargs
->lastError
= GetLastError();
85 if (winetest_debug
> 1) trace("rpcThreadMain returning\n");
89 /* Runs ReadFile(...) from a different thread */
90 static BOOL
RpcReadFile(HANDLE hFile
, LPVOID buffer
, DWORD bytesToRead
, LPDWORD bytesRead
, LPOVERLAPPED overlapped
)
92 struct rpcThreadArgs rpcargs
;
96 rpcargs
.returnValue
= 0;
97 rpcargs
.lastError
= GetLastError();
98 rpcargs
.op
= RPC_READFILE
;
99 rpcargs
.args
[0] = (ULONG_PTR
)hFile
;
100 rpcargs
.args
[1] = (ULONG_PTR
)buffer
;
101 rpcargs
.args
[2] = (ULONG_PTR
)bytesToRead
;
102 rpcargs
.args
[3] = (ULONG_PTR
)bytesRead
;
103 rpcargs
.args
[4] = (ULONG_PTR
)overlapped
;
105 thread
= CreateThread(NULL
, 0, rpcThreadMain
, (void *)&rpcargs
, 0, &threadId
);
106 ok(thread
!= NULL
, "CreateThread failed. %d\n", GetLastError());
107 ret
= WaitForSingleObject(thread
, INFINITE
);
108 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject failed with %d.\n", GetLastError());
111 SetLastError(rpcargs
.lastError
);
112 return (BOOL
)rpcargs
.returnValue
;
115 #define test_not_signaled(h) _test_not_signaled(__LINE__,h)
116 static void _test_not_signaled(unsigned line
, HANDLE handle
)
118 DWORD res
= WaitForSingleObject(handle
, 0);
119 ok_(__FILE__
,line
)(res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %u (%u)\n", res
, GetLastError());
122 #define test_signaled(h) _test_signaled(__LINE__,h)
123 static void _test_signaled(unsigned line
, HANDLE handle
)
125 DWORD res
= WaitForSingleObject(handle
, 0);
126 ok_(__FILE__
,line
)(res
== WAIT_OBJECT_0
, "WaitForSingleObject returned %u\n", res
);
129 #define test_pipe_info(a,b,c,d,e) _test_pipe_info(__LINE__,a,b,c,d,e)
130 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
)
132 DWORD flags
= 0xdeadbeef, out_buf_size
= 0xdeadbeef, in_buf_size
= 0xdeadbeef, max_instances
= 0xdeadbeef;
135 res
= GetNamedPipeInfo(pipe
, &flags
, &out_buf_size
, &in_buf_size
, &max_instances
);
136 ok_(__FILE__
,line
)(res
, "GetNamedPipeInfo failed: %x\n", res
);
137 ok_(__FILE__
,line
)(flags
== ex_flags
, "flags = %x, expected %x\n", flags
, ex_flags
);
138 ok_(__FILE__
,line
)(out_buf_size
== ex_out_buf_size
, "out_buf_size = %x, expected %u\n", out_buf_size
, ex_out_buf_size
);
139 ok_(__FILE__
,line
)(in_buf_size
== ex_in_buf_size
, "in_buf_size = %x, expected %u\n", in_buf_size
, ex_in_buf_size
);
140 ok_(__FILE__
,line
)(max_instances
== ex_max_instances
, "max_instances = %x, expected %u\n", max_instances
, ex_max_instances
);
143 static void test_CreateNamedPipe(int pipemode
)
147 static const char obuf
[] = "Bit Bucket";
148 static const char obuf2
[] = "More bits";
149 char ibuf
[32], *pbuf
;
157 if (pipemode
== PIPE_TYPE_BYTE
)
158 trace("test_CreateNamedPipe starting in byte mode\n");
160 trace("test_CreateNamedPipe starting in message mode\n");
162 /* Wait for nonexistent pipe */
163 ret
= WaitNamedPipeA(PIPENAME
, 2000);
164 ok(ret
== 0, "WaitNamedPipe returned %d for nonexistent pipe\n", ret
);
165 ok(GetLastError() == ERROR_FILE_NOT_FOUND
, "wrong error %u\n", GetLastError());
167 /* Bad parameter checks */
168 hnp
= CreateNamedPipeA("not a named pipe", PIPE_ACCESS_DUPLEX
, pipemode
| PIPE_WAIT
,
169 /* nMaxInstances */ 1,
170 /* nOutBufSize */ 1024,
171 /* nInBufSize */ 1024,
172 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
173 /* lpSecurityAttrib */ NULL
);
174 ok(hnp
== INVALID_HANDLE_VALUE
&& GetLastError() == ERROR_INVALID_NAME
,
175 "CreateNamedPipe should fail if name doesn't start with \\\\.\\pipe\n");
177 if (pipemode
== PIPE_TYPE_BYTE
)
179 /* Bad parameter checks */
180 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_READMODE_MESSAGE
,
181 /* nMaxInstances */ 1,
182 /* nOutBufSize */ 1024,
183 /* nInBufSize */ 1024,
184 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
185 /* lpSecurityAttrib */ NULL
);
186 ok(hnp
== INVALID_HANDLE_VALUE
&& GetLastError() == ERROR_INVALID_PARAMETER
,
187 "CreateNamedPipe should fail with PIPE_TYPE_BYTE | PIPE_READMODE_MESSAGE\n");
190 hnp
= CreateNamedPipeA(NULL
,
191 PIPE_ACCESS_DUPLEX
, pipemode
| PIPE_WAIT
,
192 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
193 ok(hnp
== INVALID_HANDLE_VALUE
&& GetLastError() == ERROR_PATH_NOT_FOUND
,
194 "CreateNamedPipe should fail if name is NULL\n");
196 hFile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
197 ok(hFile
== INVALID_HANDLE_VALUE
198 && GetLastError() == ERROR_FILE_NOT_FOUND
,
199 "connecting to nonexistent named pipe should fail with ERROR_FILE_NOT_FOUND\n");
201 /* Functional checks */
203 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, pipemode
| PIPE_WAIT
,
204 /* nMaxInstances */ 1,
205 /* nOutBufSize */ 1024,
206 /* nInBufSize */ 1024,
207 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
208 /* lpSecurityAttrib */ NULL
);
209 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
212 ret
= PeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, NULL
);
214 ok(!ret
&& GetLastError() == ERROR_BAD_PIPE
, "PeekNamedPipe returned %x (%u)\n",
215 ret
, GetLastError());
217 ret
= WaitNamedPipeA(PIPENAME
, 2000);
218 ok(ret
, "WaitNamedPipe failed (%d)\n", GetLastError());
220 hFile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
221 ok(hFile
!= INVALID_HANDLE_VALUE
, "CreateFile failed (%d)\n", GetLastError());
223 ok(!WaitNamedPipeA(PIPENAME
, 100), "WaitNamedPipe succeeded\n");
225 ok(GetLastError() == ERROR_SEM_TIMEOUT
, "wrong error %u\n", GetLastError());
227 /* Test ConnectNamedPipe() in both directions */
228 ok(!ConnectNamedPipe(hnp
, NULL
), "ConnectNamedPipe(server) succeeded\n");
229 ok(GetLastError() == ERROR_PIPE_CONNECTED
, "expected ERROR_PIPE_CONNECTED, got %u\n", GetLastError());
230 ok(!ConnectNamedPipe(hFile
, NULL
), "ConnectNamedPipe(client) succeeded\n");
231 ok(GetLastError() == ERROR_INVALID_FUNCTION
, "expected ERROR_INVALID_FUNCTION, got %u\n", GetLastError());
233 /* don't try to do i/o if one side couldn't be opened, as it hangs */
234 if (hFile
!= INVALID_HANDLE_VALUE
) {
237 /* Make sure we can read and write a few bytes in both directions */
238 memset(ibuf
, 0, sizeof(ibuf
));
239 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile\n");
240 ok(written
== sizeof(obuf
), "write file len\n");
241 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
242 ok(readden
== sizeof(obuf
), "read got %d bytes\n", readden
);
243 ok(memcmp(obuf
, ibuf
, written
) == 0, "content check\n");
245 memset(ibuf
, 0, sizeof(ibuf
));
246 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile\n");
247 ok(written
== sizeof(obuf2
), "write file len\n");
248 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
249 ok(readden
== sizeof(obuf2
), "read got %d bytes\n", readden
);
250 ok(memcmp(obuf2
, ibuf
, written
) == 0, "content check\n");
252 /* Now the same again, but with an additional call to PeekNamedPipe */
253 memset(ibuf
, 0, sizeof(ibuf
));
254 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile\n");
255 ok(written
== sizeof(obuf
), "write file len 1\n");
256 ok(PeekNamedPipe(hFile
, NULL
, 0, NULL
, &avail
, &left
), "Peek\n");
257 ok(avail
== sizeof(obuf
), "peek 1 got %d bytes\n", avail
);
258 if (pipemode
== PIPE_TYPE_BYTE
)
259 ok(left
== 0, "peek 1 got %d bytes left\n", left
);
261 ok(left
== sizeof(obuf
), "peek 1 got %d bytes left\n", left
);
262 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
263 ok(readden
== sizeof(obuf
), "read 1 got %d bytes\n", readden
);
264 ok(memcmp(obuf
, ibuf
, written
) == 0, "content 1 check\n");
266 memset(ibuf
, 0, sizeof(ibuf
));
267 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile\n");
268 ok(written
== sizeof(obuf2
), "write file len 2\n");
269 ok(PeekNamedPipe(hnp
, NULL
, 0, NULL
, &avail
, &left
), "Peek\n");
270 ok(avail
== sizeof(obuf2
), "peek 2 got %d bytes\n", avail
);
271 if (pipemode
== PIPE_TYPE_BYTE
)
272 ok(left
== 0, "peek 2 got %d bytes left\n", left
);
274 ok(left
== sizeof(obuf2
), "peek 2 got %d bytes left\n", left
);
275 ok(PeekNamedPipe(hnp
, (LPVOID
)1, 0, NULL
, &avail
, &left
), "Peek\n");
276 ok(avail
== sizeof(obuf2
), "peek 2 got %d bytes\n", avail
);
277 if (pipemode
== PIPE_TYPE_BYTE
)
278 ok(left
== 0, "peek 2 got %d bytes left\n", left
);
280 ok(left
== sizeof(obuf2
), "peek 2 got %d bytes left\n", left
);
281 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
282 ok(readden
== sizeof(obuf2
), "read 2 got %d bytes\n", readden
);
283 ok(memcmp(obuf2
, ibuf
, written
) == 0, "content 2 check\n");
285 /* Test how ReadFile behaves when the buffer is not big enough for the whole message */
286 memset(ibuf
, 0, sizeof(ibuf
));
287 ok(WriteFile(hnp
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile\n");
288 ok(written
== sizeof(obuf2
), "write file len\n");
289 ok(PeekNamedPipe(hFile
, ibuf
, 4, &readden
, &avail
, &left
), "Peek\n");
290 ok(readden
== 4, "peek got %d bytes\n", readden
);
291 ok(avail
== sizeof(obuf2
), "peek got %d bytes available\n", avail
);
292 if (pipemode
== PIPE_TYPE_BYTE
)
293 ok(left
== -4, "peek got %d bytes left\n", left
);
295 ok(left
== sizeof(obuf2
)-4, "peek got %d bytes left\n", left
);
296 ok(ReadFile(hFile
, ibuf
, 4, &readden
, NULL
), "ReadFile\n");
297 ok(readden
== 4, "read got %d bytes\n", readden
);
298 ok(ReadFile(hFile
, ibuf
+ 4, sizeof(ibuf
) - 4, &readden
, NULL
), "ReadFile\n");
299 ok(readden
== sizeof(obuf2
) - 4, "read got %d bytes\n", readden
);
300 ok(memcmp(obuf2
, ibuf
, written
) == 0, "content check\n");
302 memset(ibuf
, 0, sizeof(ibuf
));
303 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile\n");
304 ok(written
== sizeof(obuf
), "write file len\n");
305 ok(PeekNamedPipe(hnp
, ibuf
, 4, &readden
, &avail
, &left
), "Peek\n");
306 ok(readden
== 4, "peek got %d bytes\n", readden
);
307 ok(avail
== sizeof(obuf
), "peek got %d bytes available\n", avail
);
308 if (pipemode
== PIPE_TYPE_BYTE
)
310 ok(left
== -4, "peek got %d bytes left\n", left
);
311 ok(ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile\n");
315 ok(left
== sizeof(obuf
)-4, "peek got %d bytes left\n", left
);
316 SetLastError(0xdeadbeef);
317 ok(!ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile\n");
318 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error\n");
320 ok(readden
== 4, "read got %d bytes\n", readden
);
321 ok(ReadFile(hnp
, ibuf
+ 4, sizeof(ibuf
) - 4, &readden
, NULL
), "ReadFile\n");
322 ok(readden
== sizeof(obuf
) - 4, "read got %d bytes\n", readden
);
323 ok(memcmp(obuf
, ibuf
, written
) == 0, "content check\n");
325 /* Similar to above, but use a read buffer size small enough to read in three parts */
326 memset(ibuf
, 0, sizeof(ibuf
));
327 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile\n");
328 ok(written
== sizeof(obuf2
), "write file len\n");
329 if (pipemode
== PIPE_TYPE_BYTE
)
331 ok(ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile\n");
332 ok(readden
== 4, "read got %d bytes\n", readden
);
333 ok(ReadFile(hnp
, ibuf
+ 4, 4, &readden
, NULL
), "ReadFile\n");
337 SetLastError(0xdeadbeef);
338 ok(!ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile\n");
339 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error\n");
340 ok(readden
== 4, "read got %d bytes\n", readden
);
341 SetLastError(0xdeadbeef);
342 ok(!ReadFile(hnp
, ibuf
+ 4, 4, &readden
, NULL
), "ReadFile\n");
343 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error\n");
345 ok(readden
== 4, "read got %d bytes\n", readden
);
346 ok(ReadFile(hnp
, ibuf
+ 8, sizeof(ibuf
) - 8, &readden
, NULL
), "ReadFile\n");
347 ok(readden
== sizeof(obuf2
) - 8, "read got %d bytes\n", readden
);
348 ok(memcmp(obuf2
, ibuf
, written
) == 0, "content check\n");
350 /* Test reading of multiple writes */
351 memset(ibuf
, 0, sizeof(ibuf
));
352 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile3a\n");
353 ok(written
== sizeof(obuf
), "write file len 3a\n");
354 ok(WriteFile(hnp
, obuf2
, sizeof(obuf2
), &written
, NULL
), " WriteFile3b\n");
355 ok(written
== sizeof(obuf2
), "write file len 3b\n");
356 ok(PeekNamedPipe(hFile
, ibuf
, 4, &readden
, &avail
, &left
), "Peek3\n");
357 ok(readden
== 4, "peek3 got %d bytes\n", readden
);
358 if (pipemode
== PIPE_TYPE_BYTE
)
359 ok(left
== -4, "peek3 got %d bytes left\n", left
);
361 ok(left
== sizeof(obuf
)-4, "peek3 got %d bytes left\n", left
);
362 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek3 got %d bytes available\n", avail
);
363 ok(PeekNamedPipe(hFile
, ibuf
, sizeof(ibuf
), &readden
, &avail
, &left
), "Peek3\n");
364 if (pipemode
== PIPE_TYPE_BYTE
) {
365 ok(readden
== sizeof(obuf
) + sizeof(obuf2
), "peek3 got %d bytes\n", readden
);
366 ok(left
== (DWORD
) -(sizeof(obuf
) + sizeof(obuf2
)), "peek3 got %d bytes left\n", left
);
370 ok(readden
== sizeof(obuf
), "peek3 got %d bytes\n", readden
);
371 ok(left
== 0, "peek3 got %d bytes left\n", left
);
373 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek3 got %d bytes available\n", avail
);
375 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "pipe content 3a check\n");
376 if (pipemode
== PIPE_TYPE_BYTE
&& readden
>= sizeof(obuf
)+sizeof(obuf2
)) {
377 pbuf
+= sizeof(obuf
);
378 ok(memcmp(obuf2
, pbuf
, sizeof(obuf2
)) == 0, "pipe content 3b check\n");
380 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
381 ok(readden
== sizeof(obuf
) + sizeof(obuf2
), "read 3 got %d bytes\n", readden
);
383 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 3a check\n");
384 pbuf
+= sizeof(obuf
);
385 ok(memcmp(obuf2
, pbuf
, sizeof(obuf2
)) == 0, "content 3b check\n");
387 /* Multiple writes in the reverse direction */
388 memset(ibuf
, 0, sizeof(ibuf
));
389 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile4a\n");
390 ok(written
== sizeof(obuf
), "write file len 4a\n");
391 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), " WriteFile4b\n");
392 ok(written
== sizeof(obuf2
), "write file len 4b\n");
393 ok(PeekNamedPipe(hnp
, ibuf
, 4, &readden
, &avail
, &left
), "Peek3\n");
394 ok(readden
== 4, "peek3 got %d bytes\n", readden
);
395 if (pipemode
== PIPE_TYPE_BYTE
)
396 ok(left
== -4, "peek3 got %d bytes left\n", left
);
398 ok(left
== sizeof(obuf
)-4, "peek3 got %d bytes left\n", left
);
399 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek3 got %d bytes available\n", avail
);
400 ok(PeekNamedPipe(hnp
, ibuf
, sizeof(ibuf
), &readden
, &avail
, &left
), "Peek4\n");
401 if (pipemode
== PIPE_TYPE_BYTE
) {
402 ok(readden
== sizeof(obuf
) + sizeof(obuf2
), "peek4 got %d bytes\n", readden
);
403 ok(left
== (DWORD
) -(sizeof(obuf
) + sizeof(obuf2
)), "peek4 got %d bytes left\n", left
);
407 ok(readden
== sizeof(obuf
), "peek4 got %d bytes\n", readden
);
408 ok(left
== 0, "peek4 got %d bytes left\n", left
);
410 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek4 got %d bytes available\n", avail
);
412 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "pipe content 4a check\n");
413 if (pipemode
== PIPE_TYPE_BYTE
&& readden
>= sizeof(obuf
)+sizeof(obuf2
)) {
414 pbuf
+= sizeof(obuf
);
415 ok(memcmp(obuf2
, pbuf
, sizeof(obuf2
)) == 0, "pipe content 4b check\n");
417 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
418 if (pipemode
== PIPE_TYPE_BYTE
) {
419 ok(readden
== sizeof(obuf
) + sizeof(obuf2
), "read 4 got %d bytes\n", readden
);
422 ok(readden
== sizeof(obuf
), "read 4 got %d bytes\n", readden
);
425 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 4a check\n");
426 if (pipemode
== PIPE_TYPE_BYTE
) {
427 pbuf
+= sizeof(obuf
);
428 ok(memcmp(obuf2
, pbuf
, sizeof(obuf2
)) == 0, "content 4b check\n");
431 /* Test reading of multiple writes after a mode change
432 (CreateFile always creates a byte mode pipe) */
433 lpmode
= PIPE_READMODE_MESSAGE
;
434 if (pipemode
== PIPE_TYPE_BYTE
) {
435 /* trying to change the client end of a byte pipe to message mode should fail */
436 ok(!SetNamedPipeHandleState(hFile
, &lpmode
, NULL
, NULL
), "Change mode\n");
439 ok(SetNamedPipeHandleState(hFile
, &lpmode
, NULL
, NULL
), "Change mode\n");
441 memset(ibuf
, 0, sizeof(ibuf
));
442 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile5a\n");
443 ok(written
== sizeof(obuf
), "write file len 3a\n");
444 ok(WriteFile(hnp
, obuf2
, sizeof(obuf2
), &written
, NULL
), " WriteFile5b\n");
445 ok(written
== sizeof(obuf2
), "write file len 3b\n");
446 ok(PeekNamedPipe(hFile
, ibuf
, sizeof(ibuf
), &readden
, &avail
, &left
), "Peek5\n");
447 ok(readden
== sizeof(obuf
), "peek5 got %d bytes\n", readden
);
448 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek5 got %d bytes available\n", avail
);
449 ok(left
== 0, "peek5 got %d bytes left\n", left
);
451 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 5a check\n");
452 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
453 ok(readden
== sizeof(obuf
), "read 5 got %d bytes\n", readden
);
455 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 5a check\n");
456 if (readden
<= sizeof(obuf
))
457 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
459 /* Multiple writes in the reverse direction */
460 /* the write of obuf2 from write4 should still be in the buffer */
461 ok(PeekNamedPipe(hnp
, ibuf
, sizeof(ibuf
), &readden
, &avail
, NULL
), "Peek6a\n");
462 ok(readden
== sizeof(obuf2
), "peek6a got %d bytes\n", readden
);
463 ok(avail
== sizeof(obuf2
), "peek6a got %d bytes available\n", avail
);
465 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
466 ok(readden
== sizeof(obuf2
), "read 6a got %d bytes\n", readden
);
468 ok(memcmp(obuf2
, pbuf
, sizeof(obuf2
)) == 0, "content 6a check\n");
470 memset(ibuf
, 0, sizeof(ibuf
));
471 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile6a\n");
472 ok(written
== sizeof(obuf
), "write file len 6a\n");
473 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), " WriteFile6b\n");
474 ok(written
== sizeof(obuf2
), "write file len 6b\n");
475 ok(PeekNamedPipe(hnp
, ibuf
, sizeof(ibuf
), &readden
, &avail
, NULL
), "Peek6\n");
476 ok(readden
== sizeof(obuf
), "peek6 got %d bytes\n", readden
);
478 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek6b got %d bytes available\n", avail
);
480 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 6a check\n");
481 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
482 ok(readden
== sizeof(obuf
), "read 6b got %d bytes\n", readden
);
484 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 6a check\n");
485 if (readden
<= sizeof(obuf
))
486 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
488 /* Test how ReadFile behaves when the buffer is not big enough for the whole message */
489 memset(ibuf
, 0, sizeof(ibuf
));
490 ok(WriteFile(hnp
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile 7\n");
491 ok(written
== sizeof(obuf2
), "write file len 7\n");
492 SetLastError(0xdeadbeef);
493 ok(!ReadFile(hFile
, ibuf
, 4, &readden
, NULL
), "ReadFile 7\n");
494 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 7\n");
495 ok(readden
== 4, "read got %d bytes 7\n", readden
);
496 ok(ReadFile(hFile
, ibuf
+ 4, sizeof(ibuf
) - 4, &readden
, NULL
), "ReadFile 7\n");
497 ok(readden
== sizeof(obuf2
) - 4, "read got %d bytes 7\n", readden
);
498 ok(memcmp(obuf2
, ibuf
, written
) == 0, "content check 7\n");
500 memset(ibuf
, 0, sizeof(ibuf
));
501 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile 8\n");
502 ok(written
== sizeof(obuf
), "write file len 8\n");
503 SetLastError(0xdeadbeef);
504 ok(!ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile 8\n");
505 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 8\n");
506 ok(readden
== 4, "read got %d bytes 8\n", readden
);
507 ok(ReadFile(hnp
, ibuf
+ 4, sizeof(ibuf
) - 4, &readden
, NULL
), "ReadFile 8\n");
508 ok(readden
== sizeof(obuf
) - 4, "read got %d bytes 8\n", readden
);
509 ok(memcmp(obuf
, ibuf
, written
) == 0, "content check 8\n");
511 /* The following test shows that when doing a partial read of a message, the rest
512 * is still in the pipe, and can be received from a second thread. This shows
513 * especially that the content is _not_ stored in thread-local-storage until it is
514 * completely transmitted. The same method works even across multiple processes. */
515 memset(ibuf
, 0, sizeof(ibuf
));
516 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile 9\n");
517 ok(written
== sizeof(obuf
), "write file len 9\n");
518 ok(WriteFile(hnp
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile 9\n");
519 ok(written
== sizeof(obuf2
), "write file len 9\n");
520 SetLastError(0xdeadbeef);
521 ok(!ReadFile(hFile
, ibuf
, 4, &readden
, NULL
), "ReadFile 9\n");
522 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 9\n");
523 ok(readden
== 4, "read got %d bytes 9\n", readden
);
524 SetLastError(0xdeadbeef);
525 ret
= RpcReadFile(hFile
, ibuf
+ 4, 4, &readden
, NULL
);
526 ok(!ret
, "RpcReadFile 9\n");
527 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 9\n");
528 ok(readden
== 4, "read got %d bytes 9\n", readden
);
529 ret
= RpcReadFile(hFile
, ibuf
+ 8, sizeof(ibuf
), &readden
, NULL
);
530 ok(ret
, "RpcReadFile 9\n");
531 ok(readden
== sizeof(obuf
) - 8, "read got %d bytes 9\n", readden
);
532 ok(memcmp(obuf
, ibuf
, sizeof(obuf
)) == 0, "content check 9\n");
533 if (readden
<= sizeof(obuf
) - 8) /* blocks forever if second part was already received */
535 memset(ibuf
, 0, sizeof(ibuf
));
536 SetLastError(0xdeadbeef);
537 ret
= RpcReadFile(hFile
, ibuf
, 4, &readden
, NULL
);
538 ok(!ret
, "RpcReadFile 9\n");
539 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 9\n");
540 ok(readden
== 4, "read got %d bytes 9\n", readden
);
541 SetLastError(0xdeadbeef);
542 ok(!ReadFile(hFile
, ibuf
+ 4, 4, &readden
, NULL
), "ReadFile 9\n");
543 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 9\n");
544 ok(readden
== 4, "read got %d bytes 9\n", readden
);
545 ret
= RpcReadFile(hFile
, ibuf
+ 8, sizeof(ibuf
), &readden
, NULL
);
546 ok(ret
, "RpcReadFile 9\n");
547 ok(readden
== sizeof(obuf2
) - 8, "read got %d bytes 9\n", readden
);
548 ok(memcmp(obuf2
, ibuf
, sizeof(obuf2
)) == 0, "content check 9\n");
551 /* Now the reverse direction */
552 memset(ibuf
, 0, sizeof(ibuf
));
553 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile 10\n");
554 ok(written
== sizeof(obuf2
), "write file len 10\n");
555 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile 10\n");
556 ok(written
== sizeof(obuf
), "write file len 10\n");
557 SetLastError(0xdeadbeef);
558 ok(!ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile 10\n");
559 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 10\n");
560 ok(readden
== 4, "read got %d bytes 10\n", readden
);
561 SetLastError(0xdeadbeef);
562 ret
= RpcReadFile(hnp
, ibuf
+ 4, 4, &readden
, NULL
);
563 ok(!ret
, "RpcReadFile 10\n");
564 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 10\n");
565 ok(readden
== 4, "read got %d bytes 10\n", readden
);
566 ret
= RpcReadFile(hnp
, ibuf
+ 8, sizeof(ibuf
), &readden
, NULL
);
567 ok(ret
, "RpcReadFile 10\n");
568 ok(readden
== sizeof(obuf2
) - 8, "read got %d bytes 10\n", readden
);
569 ok(memcmp(obuf2
, ibuf
, sizeof(obuf2
)) == 0, "content check 10\n");
570 if (readden
<= sizeof(obuf2
) - 8) /* blocks forever if second part was already received */
572 memset(ibuf
, 0, sizeof(ibuf
));
573 SetLastError(0xdeadbeef);
574 ret
= RpcReadFile(hnp
, ibuf
, 4, &readden
, NULL
);
575 ok(!ret
, "RpcReadFile 10\n");
576 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 10\n");
577 ok(readden
== 4, "read got %d bytes 10\n", readden
);
578 SetLastError(0xdeadbeef);
579 ok(!ReadFile(hnp
, ibuf
+ 4, 4, &readden
, NULL
), "ReadFile 10\n");
580 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 10\n");
581 ok(readden
== 4, "read got %d bytes 10\n", readden
);
582 ret
= RpcReadFile(hnp
, ibuf
+ 8, sizeof(ibuf
), &readden
, NULL
);
583 ok(ret
, "RpcReadFile 10\n");
584 ok(readden
== sizeof(obuf
) - 8, "read got %d bytes 10\n", readden
);
585 ok(memcmp(obuf
, ibuf
, sizeof(obuf
)) == 0, "content check 10\n");
590 /* Picky conformance tests */
592 /* Verify that you can't connect to pipe again
593 * until server calls DisconnectNamedPipe+ConnectNamedPipe
594 * or creates a new pipe
595 * case 1: other client not yet closed
597 hFile2
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
598 ok(hFile2
== INVALID_HANDLE_VALUE
,
599 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n");
600 ok(GetLastError() == ERROR_PIPE_BUSY
,
601 "connecting to named pipe before other client closes should fail with ERROR_PIPE_BUSY\n");
603 ok(CloseHandle(hFile
), "CloseHandle\n");
605 /* case 2: other client already closed */
606 hFile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
607 ok(hFile
== INVALID_HANDLE_VALUE
,
608 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n");
609 ok(GetLastError() == ERROR_PIPE_BUSY
,
610 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail with ERROR_PIPE_BUSY\n");
612 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe\n");
614 /* case 3: server has called DisconnectNamedPipe but not ConnectNamed Pipe */
615 hFile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
616 ok(hFile
== INVALID_HANDLE_VALUE
,
617 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n");
618 ok(GetLastError() == ERROR_PIPE_BUSY
,
619 "connecting to named pipe after other client closes but before ConnectNamedPipe should fail with ERROR_PIPE_BUSY\n");
621 /* to be complete, we'd call ConnectNamedPipe here and loop,
622 * but by default that's blocking, so we'd either have
623 * to turn on the uncommon nonblocking mode, or
624 * use another thread.
628 ok(CloseHandle(hnp
), "CloseHandle\n");
630 if (winetest_debug
> 1) trace("test_CreateNamedPipe returning\n");
633 static void test_CreateNamedPipe_instances_must_match(void)
637 /* Check no mismatch */
638 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
639 /* nMaxInstances */ 2,
640 /* nOutBufSize */ 1024,
641 /* nInBufSize */ 1024,
642 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
643 /* lpSecurityAttrib */ NULL
);
644 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
646 hnp2
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
647 /* nMaxInstances */ 2,
648 /* nOutBufSize */ 1024,
649 /* nInBufSize */ 1024,
650 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
651 /* lpSecurityAttrib */ NULL
);
652 ok(hnp2
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
654 ok(CloseHandle(hnp
), "CloseHandle\n");
655 ok(CloseHandle(hnp2
), "CloseHandle\n");
657 /* Check nMaxInstances */
658 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
659 /* nMaxInstances */ 1,
660 /* nOutBufSize */ 1024,
661 /* nInBufSize */ 1024,
662 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
663 /* lpSecurityAttrib */ NULL
);
664 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
666 hnp2
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
667 /* nMaxInstances */ 1,
668 /* nOutBufSize */ 1024,
669 /* nInBufSize */ 1024,
670 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
671 /* lpSecurityAttrib */ NULL
);
672 ok(hnp2
== INVALID_HANDLE_VALUE
673 && GetLastError() == ERROR_PIPE_BUSY
, "nMaxInstances not obeyed\n");
675 ok(CloseHandle(hnp
), "CloseHandle\n");
677 /* Check PIPE_ACCESS_* */
678 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
679 /* nMaxInstances */ 2,
680 /* nOutBufSize */ 1024,
681 /* nInBufSize */ 1024,
682 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
683 /* lpSecurityAttrib */ NULL
);
684 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
686 hnp2
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_INBOUND
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
687 /* nMaxInstances */ 2,
688 /* nOutBufSize */ 1024,
689 /* nInBufSize */ 1024,
690 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
691 /* lpSecurityAttrib */ NULL
);
692 ok(hnp2
== INVALID_HANDLE_VALUE
693 && GetLastError() == ERROR_ACCESS_DENIED
, "PIPE_ACCESS_* mismatch allowed\n");
695 ok(CloseHandle(hnp
), "CloseHandle\n");
697 /* check everything else */
698 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
699 /* nMaxInstances */ 4,
700 /* nOutBufSize */ 1024,
701 /* nInBufSize */ 1024,
702 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
703 /* lpSecurityAttrib */ NULL
);
704 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
706 hnp2
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_MESSAGE
,
707 /* nMaxInstances */ 3,
708 /* nOutBufSize */ 102,
710 /* nDefaultWait */ 1234,
711 /* lpSecurityAttrib */ NULL
);
712 ok(hnp2
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
714 ok(CloseHandle(hnp
), "CloseHandle\n");
715 ok(CloseHandle(hnp2
), "CloseHandle\n");
718 /** implementation of alarm() */
719 static DWORD CALLBACK
alarmThreadMain(LPVOID arg
)
721 DWORD_PTR timeout
= (DWORD_PTR
) arg
;
722 if (winetest_debug
> 1) trace("alarmThreadMain\n");
723 if (WaitForSingleObject( alarm_event
, timeout
) == WAIT_TIMEOUT
)
725 ok(FALSE
, "alarm\n");
731 static HANDLE hnp
= INVALID_HANDLE_VALUE
;
733 /** Trivial byte echo server - disconnects after each session */
734 static DWORD CALLBACK
serverThreadMain1(LPVOID arg
)
738 if (winetest_debug
> 1) trace("serverThreadMain1 start\n");
739 /* Set up a simple echo server */
740 hnp
= CreateNamedPipeA(PIPENAME
"serverThreadMain1", PIPE_ACCESS_DUPLEX
,
741 PIPE_TYPE_BYTE
| PIPE_WAIT
,
742 /* nMaxInstances */ 1,
743 /* nOutBufSize */ 1024,
744 /* nInBufSize */ 1024,
745 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
746 /* lpSecurityAttrib */ NULL
);
748 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
749 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
755 /* Wait for client to connect */
756 if (winetest_debug
> 1) trace("Server calling ConnectNamedPipe...\n");
757 ok(ConnectNamedPipe(hnp
, NULL
)
758 || GetLastError() == ERROR_PIPE_CONNECTED
, "ConnectNamedPipe\n");
759 if (winetest_debug
> 1) trace("ConnectNamedPipe returned.\n");
761 /* Echo bytes once */
762 memset(buf
, 0, sizeof(buf
));
764 if (winetest_debug
> 1) trace("Server reading...\n");
765 success
= ReadFile(hnp
, buf
, sizeof(buf
), &readden
, NULL
);
766 if (winetest_debug
> 1) trace("Server done reading.\n");
767 ok(success
, "ReadFile\n");
768 ok(readden
, "short read\n");
770 if (winetest_debug
> 1) trace("Server writing...\n");
771 ok(WriteFile(hnp
, buf
, readden
, &written
, NULL
), "WriteFile\n");
772 if (winetest_debug
> 1) trace("Server done writing.\n");
773 ok(written
== readden
, "write file len\n");
775 /* finish this connection, wait for next one */
776 ok(FlushFileBuffers(hnp
), "FlushFileBuffers\n");
777 if (winetest_debug
> 1) trace("Server done flushing.\n");
778 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe\n");
779 if (winetest_debug
> 1) trace("Server done disconnecting.\n");
784 /** Trivial byte echo server - closes after each connection */
785 static DWORD CALLBACK
serverThreadMain2(LPVOID arg
)
790 trace("serverThreadMain2\n");
791 /* Set up a simple echo server */
792 hnp
= CreateNamedPipeA(PIPENAME
"serverThreadMain2", PIPE_ACCESS_DUPLEX
,
793 PIPE_TYPE_BYTE
| PIPE_WAIT
,
794 /* nMaxInstances */ 2,
795 /* nOutBufSize */ 1024,
796 /* nInBufSize */ 1024,
797 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
798 /* lpSecurityAttrib */ NULL
);
799 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
801 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
809 user_apc_ran
= FALSE
;
810 if (i
== 0 && pQueueUserAPC
) {
811 if (winetest_debug
> 1) trace("Queueing an user APC\n"); /* verify the pipe is non alerable */
812 ret
= pQueueUserAPC(&user_apc
, GetCurrentThread(), 0);
813 ok(ret
, "QueueUserAPC failed: %d\n", GetLastError());
816 /* Wait for client to connect */
817 if (winetest_debug
> 1) trace("Server calling ConnectNamedPipe...\n");
818 ok(ConnectNamedPipe(hnp
, NULL
)
819 || GetLastError() == ERROR_PIPE_CONNECTED
, "ConnectNamedPipe\n");
820 if (winetest_debug
> 1) trace("ConnectNamedPipe returned.\n");
822 /* Echo bytes once */
823 memset(buf
, 0, sizeof(buf
));
825 if (winetest_debug
> 1) trace("Server reading...\n");
826 success
= ReadFile(hnp
, buf
, sizeof(buf
), &readden
, NULL
);
827 if (winetest_debug
> 1) trace("Server done reading.\n");
828 ok(success
, "ReadFile\n");
830 if (winetest_debug
> 1) trace("Server writing...\n");
831 ok(WriteFile(hnp
, buf
, readden
, &written
, NULL
), "WriteFile\n");
832 if (winetest_debug
> 1) trace("Server done writing.\n");
833 ok(written
== readden
, "write file len\n");
835 /* finish this connection, wait for next one */
836 ok(FlushFileBuffers(hnp
), "FlushFileBuffers\n");
837 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe\n");
839 ok(user_apc_ran
== FALSE
, "UserAPC ran, pipe using alertable io mode\n");
841 if (i
== 0 && pQueueUserAPC
)
842 SleepEx(0, TRUE
); /* get rid of apc */
844 /* Set up next echo server */
846 CreateNamedPipeA(PIPENAME
"serverThreadMain2", PIPE_ACCESS_DUPLEX
,
847 PIPE_TYPE_BYTE
| PIPE_WAIT
,
848 /* nMaxInstances */ 2,
849 /* nOutBufSize */ 1024,
850 /* nInBufSize */ 1024,
851 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
852 /* lpSecurityAttrib */ NULL
);
854 ok(hnpNext
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
856 ok(CloseHandle(hnp
), "CloseHandle\n");
862 /** Trivial byte echo server - uses overlapped named pipe calls */
863 static DWORD CALLBACK
serverThreadMain3(LPVOID arg
)
868 if (winetest_debug
> 1) trace("serverThreadMain3\n");
869 /* Set up a simple echo server */
870 hnp
= CreateNamedPipeA(PIPENAME
"serverThreadMain3", PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
871 PIPE_TYPE_BYTE
| PIPE_WAIT
,
872 /* nMaxInstances */ 1,
873 /* nOutBufSize */ 1024,
874 /* nInBufSize */ 1024,
875 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
876 /* lpSecurityAttrib */ NULL
);
877 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
879 hEvent
= CreateEventW(NULL
, /* security attribute */
880 TRUE
, /* manual reset event */
881 FALSE
, /* initial state */
883 ok(hEvent
!= NULL
, "CreateEvent\n");
885 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
892 int letWFSOEwait
= (i
& 2);
893 int letGORwait
= (i
& 1);
896 memset(&oOverlap
, 0, sizeof(oOverlap
));
897 oOverlap
.hEvent
= hEvent
;
899 /* Wait for client to connect */
901 if (winetest_debug
> 1) trace("Server calling non-overlapped ConnectNamedPipe on overlapped pipe...\n");
902 success
= ConnectNamedPipe(hnp
, NULL
);
903 err
= GetLastError();
904 ok(success
|| (err
== ERROR_PIPE_CONNECTED
), "ConnectNamedPipe failed: %d\n", err
);
905 if (winetest_debug
> 1) trace("ConnectNamedPipe operation complete.\n");
907 if (winetest_debug
> 1) trace("Server calling overlapped ConnectNamedPipe...\n");
908 success
= ConnectNamedPipe(hnp
, &oOverlap
);
909 err
= GetLastError();
910 ok(!success
&& (err
== ERROR_IO_PENDING
|| err
== ERROR_PIPE_CONNECTED
), "overlapped ConnectNamedPipe\n");
911 if (winetest_debug
> 1) trace("overlapped ConnectNamedPipe returned.\n");
912 if (!success
&& (err
== ERROR_IO_PENDING
)) {
917 ret
= WaitForSingleObjectEx(hEvent
, INFINITE
, TRUE
);
918 } while (ret
== WAIT_IO_COMPLETION
);
919 ok(ret
== 0, "wait ConnectNamedPipe returned %x\n", ret
);
921 success
= GetOverlappedResult(hnp
, &oOverlap
, &dummy
, letGORwait
);
922 if (!letGORwait
&& !letWFSOEwait
&& !success
) {
923 ok(GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult\n");
924 success
= GetOverlappedResult(hnp
, &oOverlap
, &dummy
, TRUE
);
927 ok(success
|| (err
== ERROR_PIPE_CONNECTED
), "GetOverlappedResult ConnectNamedPipe\n");
928 if (winetest_debug
> 1) trace("overlapped ConnectNamedPipe operation complete.\n");
931 /* Echo bytes once */
932 memset(buf
, 0, sizeof(buf
));
934 if (winetest_debug
> 1) trace("Server reading...\n");
935 success
= ReadFile(hnp
, buf
, sizeof(buf
), &readden
, &oOverlap
);
936 if (winetest_debug
> 1) trace("Server ReadFile returned...\n");
937 err
= GetLastError();
938 ok(success
|| err
== ERROR_IO_PENDING
, "overlapped ReadFile\n");
939 if (winetest_debug
> 1) trace("overlapped ReadFile returned.\n");
940 if (!success
&& (err
== ERROR_IO_PENDING
)) {
945 ret
= WaitForSingleObjectEx(hEvent
, INFINITE
, TRUE
);
946 } while (ret
== WAIT_IO_COMPLETION
);
947 ok(ret
== 0, "wait ReadFile returned %x\n", ret
);
949 success
= GetOverlappedResult(hnp
, &oOverlap
, &readden
, letGORwait
);
950 if (!letGORwait
&& !letWFSOEwait
&& !success
) {
951 ok(GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult\n");
952 success
= GetOverlappedResult(hnp
, &oOverlap
, &readden
, TRUE
);
955 if (winetest_debug
> 1) trace("Server done reading.\n");
956 ok(success
, "overlapped ReadFile\n");
958 if (winetest_debug
> 1) trace("Server writing...\n");
959 success
= WriteFile(hnp
, buf
, readden
, &written
, &oOverlap
);
960 if (winetest_debug
> 1) trace("Server WriteFile returned...\n");
961 err
= GetLastError();
962 ok(success
|| err
== ERROR_IO_PENDING
, "overlapped WriteFile\n");
963 if (winetest_debug
> 1) trace("overlapped WriteFile returned.\n");
964 if (!success
&& (err
== ERROR_IO_PENDING
)) {
969 ret
= WaitForSingleObjectEx(hEvent
, INFINITE
, TRUE
);
970 } while (ret
== WAIT_IO_COMPLETION
);
971 ok(ret
== 0, "wait WriteFile returned %x\n", ret
);
973 success
= GetOverlappedResult(hnp
, &oOverlap
, &written
, letGORwait
);
974 if (!letGORwait
&& !letWFSOEwait
&& !success
) {
975 ok(GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult\n");
976 success
= GetOverlappedResult(hnp
, &oOverlap
, &written
, TRUE
);
979 if (winetest_debug
> 1) trace("Server done writing.\n");
980 ok(success
, "overlapped WriteFile\n");
981 ok(written
== readden
, "write file len\n");
983 /* finish this connection, wait for next one */
984 ok(FlushFileBuffers(hnp
), "FlushFileBuffers\n");
985 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe\n");
990 /** Trivial byte echo server - uses i/o completion ports */
991 static DWORD CALLBACK
serverThreadMain4(LPVOID arg
)
997 if (winetest_debug
> 1) trace("serverThreadMain4\n");
998 /* Set up a simple echo server */
999 hnp
= CreateNamedPipeA(PIPENAME
"serverThreadMain4", PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
1000 PIPE_TYPE_BYTE
| PIPE_WAIT
,
1001 /* nMaxInstances */ 1,
1002 /* nOutBufSize */ 1024,
1003 /* nInBufSize */ 1024,
1004 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1005 /* lpSecurityAttrib */ NULL
);
1006 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
1008 hcompletion
= CreateIoCompletionPort(hnp
, NULL
, 12345, 1);
1009 ok(hcompletion
!= NULL
, "CreateIoCompletionPort failed, error=%i\n", GetLastError());
1011 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
1017 OVERLAPPED oConnect
;
1020 OVERLAPPED
*oResult
;
1024 memset(&oConnect
, 0, sizeof(oConnect
));
1025 memset(&oRead
, 0, sizeof(oRead
));
1026 memset(&oWrite
, 0, sizeof(oWrite
));
1028 /* Wait for client to connect */
1029 if (winetest_debug
> 1) trace("Server calling overlapped ConnectNamedPipe...\n");
1030 success
= ConnectNamedPipe(hnp
, &oConnect
);
1031 err
= GetLastError();
1032 ok(!success
&& (err
== ERROR_IO_PENDING
|| err
== ERROR_PIPE_CONNECTED
),
1033 "overlapped ConnectNamedPipe got %u err %u\n", success
, err
);
1034 if (!success
&& err
== ERROR_IO_PENDING
) {
1035 if (winetest_debug
> 1) trace("ConnectNamedPipe GetQueuedCompletionStatus\n");
1036 success
= GetQueuedCompletionStatus(hcompletion
, &dummy
, &compkey
, &oResult
, 0);
1039 ok( GetLastError() == WAIT_TIMEOUT
,
1040 "ConnectNamedPipe GetQueuedCompletionStatus wrong error %u\n", GetLastError());
1041 success
= GetQueuedCompletionStatus(hcompletion
, &dummy
, &compkey
, &oResult
, 10000);
1043 ok(success
, "ConnectNamedPipe GetQueuedCompletionStatus failed, errno=%i\n", GetLastError());
1046 ok(compkey
== 12345, "got completion key %i instead of 12345\n", (int)compkey
);
1047 ok(oResult
== &oConnect
, "got overlapped pointer %p instead of %p\n", oResult
, &oConnect
);
1050 if (winetest_debug
> 1) trace("overlapped ConnectNamedPipe operation complete.\n");
1052 /* Echo bytes once */
1053 memset(buf
, 0, sizeof(buf
));
1055 if (winetest_debug
> 1) trace("Server reading...\n");
1056 success
= ReadFile(hnp
, buf
, sizeof(buf
), &readden
, &oRead
);
1057 if (winetest_debug
> 1) trace("Server ReadFile returned...\n");
1058 err
= GetLastError();
1059 ok(success
|| err
== ERROR_IO_PENDING
, "overlapped ReadFile, err=%i\n", err
);
1060 success
= GetQueuedCompletionStatus(hcompletion
, &readden
, &compkey
,
1062 ok(success
, "ReadFile GetQueuedCompletionStatus failed, errno=%i\n", GetLastError());
1065 ok(compkey
== 12345, "got completion key %i instead of 12345\n", (int)compkey
);
1066 ok(oResult
== &oRead
, "got overlapped pointer %p instead of %p\n", oResult
, &oRead
);
1068 if (winetest_debug
> 1) trace("Server done reading.\n");
1070 if (winetest_debug
> 1) trace("Server writing...\n");
1071 success
= WriteFile(hnp
, buf
, readden
, &written
, &oWrite
);
1072 if (winetest_debug
> 1) trace("Server WriteFile returned...\n");
1073 err
= GetLastError();
1074 ok(success
|| err
== ERROR_IO_PENDING
, "overlapped WriteFile failed, err=%u\n", err
);
1075 success
= GetQueuedCompletionStatus(hcompletion
, &written
, &compkey
,
1077 ok(success
, "WriteFile GetQueuedCompletionStatus failed, errno=%i\n", GetLastError());
1080 ok(compkey
== 12345, "got completion key %i instead of 12345\n", (int)compkey
);
1081 ok(oResult
== &oWrite
, "got overlapped pointer %p instead of %p\n", oResult
, &oWrite
);
1082 ok(written
== readden
, "write file len\n");
1084 if (winetest_debug
> 1) trace("Server done writing.\n");
1086 /* Client will finish this connection, the following ops will trigger broken pipe errors. */
1088 /* Wait for the pipe to break. */
1089 while (PeekNamedPipe(hnp
, NULL
, 0, NULL
, &written
, &written
));
1091 if (winetest_debug
> 1) trace("Server writing on disconnected pipe...\n");
1092 SetLastError(ERROR_SUCCESS
);
1093 success
= WriteFile(hnp
, buf
, readden
, &written
, &oWrite
);
1094 err
= GetLastError();
1095 todo_wine_if (!success
&& err
== ERROR_PIPE_NOT_CONNECTED
) ok(!success
&& err
== ERROR_NO_DATA
,
1096 "overlapped WriteFile on disconnected pipe returned %u, err=%i\n", success
, err
);
1098 /* No completion status is queued on immediate error. */
1099 SetLastError(ERROR_SUCCESS
);
1100 oResult
= (OVERLAPPED
*)0xdeadbeef;
1101 success
= GetQueuedCompletionStatus(hcompletion
, &written
, &compkey
,
1103 err
= GetLastError();
1104 ok(!success
&& err
== WAIT_TIMEOUT
&& !oResult
,
1105 "WriteFile GetQueuedCompletionStatus returned %u, err=%i, oResult %p\n",
1106 success
, err
, oResult
);
1108 if (winetest_debug
> 1) trace("Server reading from disconnected pipe...\n");
1109 SetLastError(ERROR_SUCCESS
);
1110 success
= ReadFile(hnp
, buf
, sizeof(buf
), &readden
, &oRead
);
1111 if (winetest_debug
> 1) trace("Server ReadFile from disconnected pipe returned...\n");
1112 err
= GetLastError();
1113 ok(!success
&& err
== ERROR_BROKEN_PIPE
,
1114 "overlapped ReadFile on disconnected pipe returned %u, err=%i\n", success
, err
);
1116 SetLastError(ERROR_SUCCESS
);
1117 oResult
= (OVERLAPPED
*)0xdeadbeef;
1118 success
= GetQueuedCompletionStatus(hcompletion
, &readden
, &compkey
,
1120 err
= GetLastError();
1121 ok(!success
&& err
== WAIT_TIMEOUT
&& !oResult
,
1122 "ReadFile GetQueuedCompletionStatus returned %u, err=%i, oResult %p\n",
1123 success
, err
, oResult
);
1125 /* finish this connection, wait for next one */
1126 ok(FlushFileBuffers(hnp
), "FlushFileBuffers\n");
1127 success
= DisconnectNamedPipe(hnp
);
1128 ok(success
, "DisconnectNamedPipe failed, err %u\n", GetLastError());
1131 ret
= CloseHandle(hnp
);
1132 ok(ret
, "CloseHandle named pipe failed, err=%i\n", GetLastError());
1133 ret
= CloseHandle(hcompletion
);
1134 ok(ret
, "CloseHandle completion failed, err=%i\n", GetLastError());
1139 static int completion_called
;
1140 static DWORD completion_errorcode
;
1141 static DWORD completion_num_bytes
;
1142 static LPOVERLAPPED completion_lpoverlapped
;
1144 static VOID WINAPI
completion_routine(DWORD errorcode
, DWORD num_bytes
, LPOVERLAPPED lpoverlapped
)
1146 completion_called
++;
1147 completion_errorcode
= errorcode
;
1148 completion_num_bytes
= num_bytes
;
1149 completion_lpoverlapped
= lpoverlapped
;
1150 SetEvent(lpoverlapped
->hEvent
);
1153 /** Trivial byte echo server - uses ReadFileEx/WriteFileEx */
1154 static DWORD CALLBACK
serverThreadMain5(LPVOID arg
)
1159 if (winetest_debug
> 1) trace("serverThreadMain5\n");
1160 /* Set up a simple echo server */
1161 hnp
= CreateNamedPipeA(PIPENAME
"serverThreadMain5", PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
1162 PIPE_TYPE_BYTE
| PIPE_WAIT
,
1163 /* nMaxInstances */ 1,
1164 /* nOutBufSize */ 1024,
1165 /* nInBufSize */ 1024,
1166 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1167 /* lpSecurityAttrib */ NULL
);
1168 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
1170 hEvent
= CreateEventW(NULL
, /* security attribute */
1171 TRUE
, /* manual reset event */
1172 FALSE
, /* initial state */
1174 ok(hEvent
!= NULL
, "CreateEvent\n");
1176 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
1180 OVERLAPPED oOverlap
;
1183 memset(&oOverlap
, 0, sizeof(oOverlap
));
1184 oOverlap
.hEvent
= hEvent
;
1186 /* Wait for client to connect */
1187 if (winetest_debug
> 1) trace("Server calling ConnectNamedPipe...\n");
1188 success
= ConnectNamedPipe(hnp
, NULL
);
1189 err
= GetLastError();
1190 ok(success
|| (err
== ERROR_PIPE_CONNECTED
), "ConnectNamedPipe failed: %d\n", err
);
1191 if (winetest_debug
> 1) trace("ConnectNamedPipe operation complete.\n");
1193 /* Echo bytes once */
1194 memset(buf
, 0, sizeof(buf
));
1196 if (winetest_debug
> 1) trace("Server reading...\n");
1197 completion_called
= 0;
1199 success
= ReadFileEx(hnp
, buf
, sizeof(buf
), &oOverlap
, completion_routine
);
1200 if (winetest_debug
> 1) trace("Server ReadFileEx returned...\n");
1201 ok(success
, "ReadFileEx failed, err=%i\n", GetLastError());
1202 ok(completion_called
== 0, "completion routine called before ReadFileEx return\n");
1203 if (winetest_debug
> 1) trace("ReadFileEx returned.\n");
1207 ret
= WaitForSingleObjectEx(hEvent
, INFINITE
, TRUE
);
1208 } while (ret
== WAIT_IO_COMPLETION
);
1209 ok(ret
== 0, "wait ReadFileEx returned %x\n", ret
);
1211 ok(completion_called
== 1, "completion routine called %i times\n", completion_called
);
1212 ok(completion_errorcode
== ERROR_SUCCESS
, "completion routine got error %d\n", completion_errorcode
);
1213 ok(completion_num_bytes
!= 0, "read 0 bytes\n");
1214 ok(completion_lpoverlapped
== &oOverlap
, "got wrong overlapped pointer %p\n", completion_lpoverlapped
);
1215 readden
= completion_num_bytes
;
1216 if (winetest_debug
> 1) trace("Server done reading.\n");
1218 if (winetest_debug
> 1) trace("Server writing...\n");
1219 completion_called
= 0;
1221 success
= WriteFileEx(hnp
, buf
, readden
, &oOverlap
, completion_routine
);
1222 if (winetest_debug
> 1) trace("Server WriteFileEx returned...\n");
1223 ok(success
, "WriteFileEx failed, err=%i\n", GetLastError());
1224 ok(completion_called
== 0, "completion routine called before ReadFileEx return\n");
1225 if (winetest_debug
> 1) trace("overlapped WriteFile returned.\n");
1229 ret
= WaitForSingleObjectEx(hEvent
, INFINITE
, TRUE
);
1230 } while (ret
== WAIT_IO_COMPLETION
);
1231 ok(ret
== 0, "wait WriteFileEx returned %x\n", ret
);
1233 if (winetest_debug
> 1) trace("Server done writing.\n");
1234 ok(completion_called
== 1, "completion routine called %i times\n", completion_called
);
1235 ok(completion_errorcode
== ERROR_SUCCESS
, "completion routine got error %d\n", completion_errorcode
);
1236 ok(completion_num_bytes
== readden
, "read %i bytes wrote %i\n", readden
, completion_num_bytes
);
1237 ok(completion_lpoverlapped
== &oOverlap
, "got wrong overlapped pointer %p\n", completion_lpoverlapped
);
1239 /* finish this connection, wait for next one */
1240 ok(FlushFileBuffers(hnp
), "FlushFileBuffers\n");
1241 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe\n");
1246 static void exercizeServer(const char *pipename
, HANDLE serverThread
)
1250 if (winetest_debug
> 1) trace("exercizeServer starting\n");
1251 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
1252 HANDLE hFile
=INVALID_HANDLE_VALUE
;
1253 static const char obuf
[] = "Bit Bucket";
1259 for (loop
= 0; loop
< 3; loop
++) {
1261 if (winetest_debug
> 1) trace("Client connecting...\n");
1262 /* Connect to the server */
1263 hFile
= CreateFileA(pipename
, GENERIC_READ
| GENERIC_WRITE
, 0,
1264 NULL
, OPEN_EXISTING
, 0, 0);
1265 if (hFile
!= INVALID_HANDLE_VALUE
)
1267 err
= GetLastError();
1269 ok(err
== ERROR_PIPE_BUSY
|| err
== ERROR_FILE_NOT_FOUND
, "connecting to pipe\n");
1271 ok(err
== ERROR_PIPE_BUSY
, "connecting to pipe\n");
1272 if (winetest_debug
> 1) trace("connect failed, retrying\n");
1275 ok(hFile
!= INVALID_HANDLE_VALUE
, "client opening named pipe\n");
1277 /* Make sure it can echo */
1278 memset(ibuf
, 0, sizeof(ibuf
));
1279 if (winetest_debug
> 1) trace("Client writing...\n");
1280 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile to client end of pipe\n");
1281 ok(written
== sizeof(obuf
), "write file len\n");
1282 if (winetest_debug
> 1) trace("Client reading...\n");
1283 ok(ReadFile(hFile
, ibuf
, sizeof(obuf
), &readden
, NULL
), "ReadFile from client end of pipe\n");
1284 ok(readden
== sizeof(obuf
), "read file len\n");
1285 ok(memcmp(obuf
, ibuf
, written
) == 0, "content check\n");
1287 if (winetest_debug
> 1) trace("Client closing...\n");
1288 ok(CloseHandle(hFile
), "CloseHandle\n");
1291 ok(WaitForSingleObject(serverThread
,INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject\n");
1293 if (winetest_debug
> 1) trace("exercizeServer returning\n");
1296 static void test_NamedPipe_2(void)
1298 HANDLE serverThread
;
1299 DWORD serverThreadId
;
1301 DWORD alarmThreadId
;
1303 trace("test_NamedPipe_2 starting\n");
1304 /* Set up a twenty second timeout */
1305 alarm_event
= CreateEventW( NULL
, TRUE
, FALSE
, NULL
);
1306 SetLastError(0xdeadbeef);
1307 alarmThread
= CreateThread(NULL
, 0, alarmThreadMain
, (void *) 20000, 0, &alarmThreadId
);
1308 ok(alarmThread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1310 /* The servers we're about to exercise do try to clean up carefully,
1311 * but to reduce the chance of a test failure due to a pipe handle
1312 * leak in the test code, we'll use a different pipe name for each server.
1316 SetLastError(0xdeadbeef);
1317 serverThread
= CreateThread(NULL
, 0, serverThreadMain1
, (void *)8, 0, &serverThreadId
);
1318 ok(serverThread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1319 exercizeServer(PIPENAME
"serverThreadMain1", serverThread
);
1322 SetLastError(0xdeadbeef);
1323 serverThread
= CreateThread(NULL
, 0, serverThreadMain2
, 0, 0, &serverThreadId
);
1324 ok(serverThread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1325 exercizeServer(PIPENAME
"serverThreadMain2", serverThread
);
1328 SetLastError(0xdeadbeef);
1329 serverThread
= CreateThread(NULL
, 0, serverThreadMain3
, 0, 0, &serverThreadId
);
1330 ok(serverThread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1331 exercizeServer(PIPENAME
"serverThreadMain3", serverThread
);
1334 SetLastError(0xdeadbeef);
1335 serverThread
= CreateThread(NULL
, 0, serverThreadMain4
, 0, 0, &serverThreadId
);
1336 ok(serverThread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1337 exercizeServer(PIPENAME
"serverThreadMain4", serverThread
);
1340 SetLastError(0xdeadbeef);
1341 serverThread
= CreateThread(NULL
, 0, serverThreadMain5
, 0, 0, &serverThreadId
);
1342 ok(serverThread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1343 exercizeServer(PIPENAME
"serverThreadMain5", serverThread
);
1345 ok(SetEvent( alarm_event
), "SetEvent\n");
1346 CloseHandle( alarm_event
);
1347 if (winetest_debug
> 1) trace("test_NamedPipe_2 returning\n");
1350 static int test_DisconnectNamedPipe(void)
1354 static const char obuf
[] = "Bit Bucket";
1360 SetLastError(0xdeadbeef);
1361 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
1362 /* nMaxInstances */ 1,
1363 /* nOutBufSize */ 1024,
1364 /* nInBufSize */ 1024,
1365 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1366 /* lpSecurityAttrib */ NULL
);
1367 if ((hnp
== INVALID_HANDLE_VALUE
/* Win98 */ || !hnp
/* Win95 */)
1368 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
) {
1370 win_skip("Named pipes are not implemented\n");
1374 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
) == 0
1375 && GetLastError() == ERROR_PIPE_LISTENING
, "WriteFile to not-yet-connected pipe\n");
1376 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
) == 0
1377 && GetLastError() == ERROR_PIPE_LISTENING
, "ReadFile from not-yet-connected pipe\n");
1379 hFile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1380 ok(hFile
!= INVALID_HANDLE_VALUE
, "CreateFile failed\n");
1382 /* don't try to do i/o if one side couldn't be opened, as it hangs */
1383 if (hFile
!= INVALID_HANDLE_VALUE
) {
1385 /* see what happens if server calls DisconnectNamedPipe
1386 * when there are bytes in the pipe
1389 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile\n");
1390 ok(written
== sizeof(obuf
), "write file len\n");
1391 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe while messages waiting\n");
1392 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
) == 0
1393 && GetLastError() == ERROR_PIPE_NOT_CONNECTED
, "WriteFile to disconnected pipe\n");
1394 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
) == 0
1395 && GetLastError() == ERROR_PIPE_NOT_CONNECTED
,
1396 "ReadFile from disconnected pipe with bytes waiting\n");
1398 ok(!DisconnectNamedPipe(hnp
) && GetLastError() == ERROR_PIPE_NOT_CONNECTED
,
1399 "DisconnectNamedPipe worked twice\n");
1400 ret
= WaitForSingleObject(hFile
, 0);
1401 ok(ret
== WAIT_TIMEOUT
, "WaitForSingleObject returned %X\n", ret
);
1403 ret
= PeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, NULL
);
1405 ok(!ret
&& GetLastError() == ERROR_PIPE_NOT_CONNECTED
, "PeekNamedPipe returned %x (%u)\n",
1406 ret
, GetLastError());
1407 ret
= PeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, NULL
);
1409 ok(!ret
&& GetLastError() == ERROR_BAD_PIPE
, "PeekNamedPipe returned %x (%u)\n",
1410 ret
, GetLastError());
1411 ok(CloseHandle(hFile
), "CloseHandle\n");
1414 ok(CloseHandle(hnp
), "CloseHandle\n");
1418 static void test_CreatePipe(void)
1420 SECURITY_ATTRIBUTES pipe_attr
;
1421 HANDLE piperead
, pipewrite
;
1428 user_apc_ran
= FALSE
;
1430 ok(pQueueUserAPC(user_apc
, GetCurrentThread(), 0), "couldn't create user apc\n");
1432 pipe_attr
.nLength
= sizeof(SECURITY_ATTRIBUTES
);
1433 pipe_attr
.bInheritHandle
= TRUE
;
1434 pipe_attr
.lpSecurityDescriptor
= NULL
;
1435 ok(CreatePipe(&piperead
, &pipewrite
, &pipe_attr
, 0) != 0, "CreatePipe failed\n");
1436 test_pipe_info(piperead
, FILE_PIPE_SERVER_END
, 4096, 4096, 1);
1437 test_pipe_info(pipewrite
, 0, 4096, 4096, 1);
1439 ok(WriteFile(pipewrite
,PIPENAME
,sizeof(PIPENAME
), &written
, NULL
), "Write to anonymous pipe failed\n");
1440 ok(written
== sizeof(PIPENAME
), "Write to anonymous pipe wrote %d bytes\n", written
);
1441 ok(ReadFile(piperead
,readbuf
,sizeof(readbuf
),&read
, NULL
), "Read from non empty pipe failed\n");
1442 ok(read
== sizeof(PIPENAME
), "Read from anonymous pipe got %d bytes\n", read
);
1443 ok(CloseHandle(pipewrite
), "CloseHandle for the write pipe failed\n");
1444 ok(CloseHandle(piperead
), "CloseHandle for the read pipe failed\n");
1446 /* Now write another chunk*/
1447 ok(CreatePipe(&piperead
, &pipewrite
, &pipe_attr
, 0) != 0, "CreatePipe failed\n");
1448 ok(WriteFile(pipewrite
,PIPENAME
,sizeof(PIPENAME
), &written
, NULL
), "Write to anonymous pipe failed\n");
1449 ok(written
== sizeof(PIPENAME
), "Write to anonymous pipe wrote %d bytes\n", written
);
1450 /* and close the write end, read should still succeed*/
1451 ok(CloseHandle(pipewrite
), "CloseHandle for the Write Pipe failed\n");
1452 ok(ReadFile(piperead
,readbuf
,sizeof(readbuf
),&read
, NULL
), "Read from broken pipe with pending data failed\n");
1453 ok(read
== sizeof(PIPENAME
), "Read from anonymous pipe got %d bytes\n", read
);
1454 /* But now we need to get informed that the pipe is closed */
1455 ok(ReadFile(piperead
,readbuf
,sizeof(readbuf
),&read
, NULL
) == 0, "Broken pipe not detected\n");
1456 ok(CloseHandle(piperead
), "CloseHandle for the read pipe failed\n");
1458 /* Try bigger chunks */
1460 buffer
= HeapAlloc( GetProcessHeap(), 0, size
);
1461 for (i
= 0; i
< size
; i
++) buffer
[i
] = i
;
1462 ok(CreatePipe(&piperead
, &pipewrite
, &pipe_attr
, (size
+ 24)) != 0, "CreatePipe failed\n");
1463 ok(WriteFile(pipewrite
, buffer
, size
, &written
, NULL
), "Write to anonymous pipe failed\n");
1464 ok(written
== size
, "Write to anonymous pipe wrote %d bytes\n", written
);
1465 /* and close the write end, read should still succeed*/
1466 ok(CloseHandle(pipewrite
), "CloseHandle for the Write Pipe failed\n");
1467 memset( buffer
, 0, size
);
1468 ok(ReadFile(piperead
, buffer
, size
, &read
, NULL
), "Read from broken pipe with pending data failed\n");
1469 ok(read
== size
, "Read from anonymous pipe got %d bytes\n", read
);
1470 for (i
= 0; i
< size
; i
++) ok( buffer
[i
] == (BYTE
)i
, "invalid data %x at %x\n", buffer
[i
], i
);
1471 /* But now we need to get informed that the pipe is closed */
1472 ok(ReadFile(piperead
,readbuf
,sizeof(readbuf
),&read
, NULL
) == 0, "Broken pipe not detected\n");
1473 ok(CloseHandle(piperead
), "CloseHandle for the read pipe failed\n");
1474 HeapFree(GetProcessHeap(), 0, buffer
);
1476 ok(user_apc_ran
== FALSE
, "user apc ran, pipe using alertable io mode\n");
1477 SleepEx(0, TRUE
); /* get rid of apc */
1479 ok(CreatePipe(&piperead
, &pipewrite
, &pipe_attr
, 1) != 0, "CreatePipe failed\n");
1480 test_pipe_info(piperead
, FILE_PIPE_SERVER_END
, 1, 1, 1);
1481 test_pipe_info(pipewrite
, 0, 1, 1, 1);
1482 ok(CloseHandle(pipewrite
), "CloseHandle for the Write Pipe failed\n");
1483 ok(CloseHandle(piperead
), "CloseHandle for the read pipe failed\n");
1486 static void test_CloseHandle(void)
1488 static const char testdata
[] = "Hello World";
1489 DWORD state
, numbytes
;
1490 HANDLE hpipe
, hfile
;
1494 hpipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
1495 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1496 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1497 ok(hpipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %u\n", GetLastError());
1499 hfile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1500 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %u\n", GetLastError());
1502 numbytes
= 0xdeadbeef;
1503 ret
= WriteFile(hpipe
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1504 ok(ret
, "WriteFile failed with %u\n", GetLastError());
1505 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1507 numbytes
= 0xdeadbeef;
1508 ret
= PeekNamedPipe(hfile
, NULL
, 0, NULL
, &numbytes
, NULL
);
1509 ok(ret
, "PeekNamedPipe failed with %u\n", GetLastError());
1510 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1512 ret
= CloseHandle(hpipe
);
1513 ok(ret
, "CloseHandle failed with %u\n", GetLastError());
1515 numbytes
= 0xdeadbeef;
1516 memset(buffer
, 0, sizeof(buffer
));
1517 ret
= ReadFile(hfile
, buffer
, 0, &numbytes
, NULL
);
1518 ok(ret
, "ReadFile failed with %u\n", GetLastError());
1519 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
1521 numbytes
= 0xdeadbeef;
1522 ret
= PeekNamedPipe(hfile
, NULL
, 0, NULL
, &numbytes
, NULL
);
1523 ok(ret
, "PeekNamedPipe failed with %u\n", GetLastError());
1524 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1526 numbytes
= 0xdeadbeef;
1527 memset(buffer
, 0, sizeof(buffer
));
1528 ret
= ReadFile(hfile
, buffer
, sizeof(buffer
), &numbytes
, NULL
);
1529 ok(ret
, "ReadFile failed with %u\n", GetLastError());
1530 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1532 ret
= GetNamedPipeHandleStateA(hfile
, &state
, NULL
, NULL
, NULL
, NULL
, 0);
1533 ok(ret
, "GetNamedPipeHandleState failed with %u\n", GetLastError());
1534 state
= PIPE_READMODE_MESSAGE
| PIPE_WAIT
;
1535 ret
= SetNamedPipeHandleState(hfile
, &state
, NULL
, NULL
);
1536 ok(ret
, "SetNamedPipeHandleState failed with %u\n", GetLastError());
1538 SetLastError(0xdeadbeef);
1539 ret
= ReadFile(hfile
, buffer
, 0, &numbytes
, NULL
);
1540 ok(!ret
, "ReadFile unexpectedly succeeded\n");
1541 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1543 numbytes
= 0xdeadbeef;
1544 ret
= PeekNamedPipe(hfile
, NULL
, 0, NULL
, &numbytes
, NULL
);
1545 ok(!ret
&& GetLastError() == ERROR_BROKEN_PIPE
, "PeekNamedPipe returned %x (%u)\n",
1546 ret
, GetLastError());
1547 ok(numbytes
== 0xdeadbeef, "numbytes = %u\n", numbytes
);
1549 SetLastError(0xdeadbeef);
1550 ret
= WriteFile(hfile
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1551 ok(!ret
, "WriteFile unexpectedly succeeded\n");
1552 todo_wine
ok(GetLastError() == ERROR_NO_DATA
, "expected ERROR_NO_DATA, got %u\n", GetLastError());
1556 hpipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
1557 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1558 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1559 ok(hpipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %u\n", GetLastError());
1561 hfile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1562 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %u\n", GetLastError());
1564 numbytes
= 0xdeadbeef;
1565 ret
= WriteFile(hpipe
, testdata
, 0, &numbytes
, NULL
);
1566 ok(ret
, "WriteFile failed with %u\n", GetLastError());
1567 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
1569 ret
= CloseHandle(hpipe
);
1570 ok(ret
, "CloseHandle failed with %u\n", GetLastError());
1572 numbytes
= 0xdeadbeef;
1573 memset(buffer
, 0, sizeof(buffer
));
1574 ret
= ReadFile(hfile
, buffer
, sizeof(buffer
), &numbytes
, NULL
);
1575 ok(ret
, "ReadFile failed with %u\n", GetLastError());
1576 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
1578 SetLastError(0xdeadbeef);
1579 ret
= ReadFile(hfile
, buffer
, 0, &numbytes
, NULL
);
1580 ok(!ret
, "ReadFile unexpectedly succeeded\n");
1581 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1583 ret
= GetNamedPipeHandleStateA(hfile
, &state
, NULL
, NULL
, NULL
, NULL
, 0);
1584 ok(ret
, "GetNamedPipeHandleState failed with %u\n", GetLastError());
1585 state
= PIPE_READMODE_MESSAGE
| PIPE_WAIT
;
1586 ret
= SetNamedPipeHandleState(hfile
, &state
, NULL
, NULL
);
1587 ok(ret
, "SetNamedPipeHandleState failed with %u\n", GetLastError());
1589 SetLastError(0xdeadbeef);
1590 ret
= ReadFile(hfile
, buffer
, 0, &numbytes
, NULL
);
1591 ok(!ret
, "ReadFile unexpectedly succeeded\n");
1592 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1594 SetLastError(0xdeadbeef);
1595 ret
= WriteFile(hfile
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1596 ok(!ret
, "WriteFile unexpectedly succeeded\n");
1597 todo_wine
ok(GetLastError() == ERROR_NO_DATA
, "expected ERROR_NO_DATA, got %u\n", GetLastError());
1601 /* repeat test with hpipe <-> hfile swapped */
1603 hpipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
1604 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1605 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1606 ok(hpipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %u\n", GetLastError());
1608 hfile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1609 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %u\n", GetLastError());
1611 numbytes
= 0xdeadbeef;
1612 ret
= WriteFile(hfile
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1613 ok(ret
, "WriteFile failed with %u\n", GetLastError());
1614 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1616 numbytes
= 0xdeadbeef;
1617 ret
= PeekNamedPipe(hpipe
, NULL
, 0, NULL
, &numbytes
, NULL
);
1618 ok(ret
, "PeekNamedPipe failed with %u\n", GetLastError());
1619 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1621 ret
= CloseHandle(hfile
);
1622 ok(ret
, "CloseHandle failed with %u\n", GetLastError());
1624 numbytes
= 0xdeadbeef;
1625 memset(buffer
, 0, sizeof(buffer
));
1626 ret
= ReadFile(hpipe
, buffer
, 0, &numbytes
, NULL
);
1627 ok(ret
|| GetLastError() == ERROR_MORE_DATA
/* >= Win 8 */,
1628 "ReadFile failed with %u\n", GetLastError());
1629 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
1631 numbytes
= 0xdeadbeef;
1632 ret
= PeekNamedPipe(hpipe
, NULL
, 0, NULL
, &numbytes
, NULL
);
1633 ok(ret
, "PeekNamedPipe failed with %u\n", GetLastError());
1634 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1636 numbytes
= 0xdeadbeef;
1637 memset(buffer
, 0, sizeof(buffer
));
1638 ret
= ReadFile(hpipe
, buffer
, sizeof(buffer
), &numbytes
, NULL
);
1639 ok(ret
, "ReadFile failed with %u\n", GetLastError());
1640 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1642 ret
= GetNamedPipeHandleStateA(hpipe
, &state
, NULL
, NULL
, NULL
, NULL
, 0);
1643 ok(ret
, "GetNamedPipeHandleState failed with %u\n", GetLastError());
1644 state
= PIPE_READMODE_MESSAGE
| PIPE_WAIT
;
1645 ret
= SetNamedPipeHandleState(hpipe
, &state
, NULL
, NULL
);
1646 ok(ret
, "SetNamedPipeHandleState failed with %u\n", GetLastError());
1648 SetLastError(0xdeadbeef);
1649 ret
= ReadFile(hpipe
, buffer
, 0, &numbytes
, NULL
);
1650 ok(!ret
, "ReadFile unexpectedly succeeded\n");
1651 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1653 numbytes
= 0xdeadbeef;
1654 ret
= PeekNamedPipe(hpipe
, NULL
, 0, NULL
, &numbytes
, NULL
);
1655 ok(!ret
&& GetLastError() == ERROR_BROKEN_PIPE
, "PeekNamedPipe returned %x (%u)\n",
1656 ret
, GetLastError());
1657 ok(numbytes
== 0xdeadbeef, "numbytes = %u\n", numbytes
);
1659 SetLastError(0xdeadbeef);
1660 ret
= WriteFile(hpipe
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1661 ok(!ret
, "WriteFile unexpectedly succeeded\n");
1662 todo_wine
ok(GetLastError() == ERROR_NO_DATA
, "expected ERROR_NO_DATA, got %u\n", GetLastError());
1666 hpipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
1667 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1668 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1669 ok(hpipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %u\n", GetLastError());
1671 hfile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1672 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %u\n", GetLastError());
1674 numbytes
= 0xdeadbeef;
1675 ret
= WriteFile(hfile
, testdata
, 0, &numbytes
, NULL
);
1676 ok(ret
, "WriteFile failed with %u\n", GetLastError());
1677 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
1679 ret
= CloseHandle(hfile
);
1680 ok(ret
, "CloseHandle failed with %u\n", GetLastError());
1682 numbytes
= 0xdeadbeef;
1683 memset(buffer
, 0, sizeof(buffer
));
1684 ret
= ReadFile(hpipe
, buffer
, sizeof(buffer
), &numbytes
, NULL
);
1685 ok(ret
, "ReadFile failed with %u\n", GetLastError());
1686 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
1688 SetLastError(0xdeadbeef);
1689 ret
= ReadFile(hpipe
, buffer
, 0, &numbytes
, NULL
);
1690 ok(!ret
, "ReadFile unexpectedly succeeded\n");
1691 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1693 ret
= GetNamedPipeHandleStateA(hpipe
, &state
, NULL
, NULL
, NULL
, NULL
, 0);
1694 ok(ret
, "GetNamedPipeHandleState failed with %u\n", GetLastError());
1695 state
= PIPE_READMODE_MESSAGE
| PIPE_WAIT
;
1696 ret
= SetNamedPipeHandleState(hpipe
, &state
, NULL
, NULL
);
1697 ok(ret
, "SetNamedPipeHandleState failed with %u\n", GetLastError());
1699 SetLastError(0xdeadbeef);
1700 ret
= ReadFile(hpipe
, buffer
, 0, &numbytes
, NULL
);
1701 ok(!ret
, "ReadFile unexpectedly succeeded\n");
1702 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1704 SetLastError(0xdeadbeef);
1705 ret
= WriteFile(hpipe
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1706 ok(!ret
, "WriteFile unexpectedly succeeded\n");
1707 todo_wine
ok(GetLastError() == ERROR_NO_DATA
, "expected ERROR_NO_DATA, got %u\n", GetLastError());
1712 struct named_pipe_client_params
1714 DWORD security_flags
;
1719 #define PIPE_NAME "\\\\.\\pipe\\named_pipe_test"
1721 static DWORD CALLBACK
named_pipe_client_func(LPVOID p
)
1723 struct named_pipe_client_params
*params
= p
;
1726 const char message
[] = "Test";
1727 DWORD bytes_read
, bytes_written
;
1729 TOKEN_PRIVILEGES
*Privileges
= NULL
;
1735 /* modify the token so we can tell if the pipe impersonation
1736 * token reverts to the process token */
1737 ret
= AdjustTokenPrivileges(params
->token
, TRUE
, NULL
, 0, NULL
, NULL
);
1738 ok(ret
, "AdjustTokenPrivileges failed with error %d\n", GetLastError());
1740 ret
= SetThreadToken(NULL
, params
->token
);
1741 ok(ret
, "SetThreadToken failed with error %d\n", GetLastError());
1746 HANDLE process_token
;
1748 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
|TOKEN_ADJUST_PRIVILEGES
, &process_token
);
1749 ok(ret
, "OpenProcessToken failed with error %d\n", GetLastError());
1751 ret
= GetTokenInformation(process_token
, TokenPrivileges
, NULL
, 0, &Size
);
1752 ok(!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "GetTokenInformation(TokenPrivileges) failed with %d\n", GetLastError());
1753 Privileges
= HeapAlloc(GetProcessHeap(), 0, Size
);
1754 ret
= GetTokenInformation(process_token
, TokenPrivileges
, Privileges
, Size
, &Size
);
1755 ok(ret
, "GetTokenInformation(TokenPrivileges) failed with %d\n", GetLastError());
1757 ret
= AdjustTokenPrivileges(process_token
, TRUE
, NULL
, 0, NULL
, NULL
);
1758 ok(ret
, "AdjustTokenPrivileges failed with error %d\n", GetLastError());
1760 CloseHandle(process_token
);
1763 pipe
= CreateFileA(PIPE_NAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, params
->security_flags
, NULL
);
1764 ok(pipe
!= INVALID_HANDLE_VALUE
, "CreateFile for pipe failed with error %d\n", GetLastError());
1766 ret
= WriteFile(pipe
, message
, sizeof(message
), &bytes_written
, NULL
);
1767 ok(ret
, "WriteFile failed with error %d\n", GetLastError());
1769 ret
= ReadFile(pipe
, &dummy
, sizeof(dummy
), &bytes_read
, NULL
);
1770 ok(ret
, "ReadFile failed with error %d\n", GetLastError());
1776 ret
= RevertToSelf();
1777 ok(ret
, "RevertToSelf failed with error %d\n", GetLastError());
1781 ret
= AdjustTokenPrivileges(params
->token
, TRUE
, NULL
, 0, NULL
, NULL
);
1782 ok(ret
, "AdjustTokenPrivileges failed with error %d\n", GetLastError());
1787 HANDLE process_token
;
1789 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES
, &process_token
);
1790 ok(ret
, "OpenProcessToken failed with error %d\n", GetLastError());
1792 ret
= AdjustTokenPrivileges(process_token
, FALSE
, Privileges
, 0, NULL
, NULL
);
1793 ok(ret
, "AdjustTokenPrivileges failed with error %d\n", GetLastError());
1795 HeapFree(GetProcessHeap(), 0, Privileges
);
1797 CloseHandle(process_token
);
1800 ret
= WriteFile(pipe
, message
, sizeof(message
), &bytes_written
, NULL
);
1801 ok(ret
, "WriteFile failed with error %d\n", GetLastError());
1803 ret
= ReadFile(pipe
, &dummy
, sizeof(dummy
), &bytes_read
, NULL
);
1804 ok(ret
, "ReadFile failed with error %d\n", GetLastError());
1811 static HANDLE
make_impersonation_token(DWORD Access
, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
1813 HANDLE ProcessToken
;
1814 HANDLE Token
= NULL
;
1817 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE
, &ProcessToken
);
1818 ok(ret
, "OpenProcessToken failed with error %d\n", GetLastError());
1820 ret
= pDuplicateTokenEx(ProcessToken
, Access
, NULL
, ImpersonationLevel
, TokenImpersonation
, &Token
);
1821 ok(ret
, "DuplicateToken failed with error %d\n", GetLastError());
1823 CloseHandle(ProcessToken
);
1828 static void test_ImpersonateNamedPipeClient(HANDLE hClientToken
, DWORD security_flags
, BOOL revert
, void (*test_func
)(int, HANDLE
))
1837 struct named_pipe_client_params params
;
1839 DWORD dwBytesWritten
;
1840 HANDLE hToken
= NULL
;
1841 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
;
1844 hPipeServer
= CreateNamedPipeA(PIPE_NAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_READMODE_BYTE
| PIPE_WAIT
, 1, 100, 100, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1845 ok(hPipeServer
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with error %d\n", GetLastError());
1847 params
.security_flags
= security_flags
;
1848 params
.token
= hClientToken
;
1849 params
.revert
= revert
;
1850 hThread
= CreateThread(NULL
, 0, named_pipe_client_func
, ¶ms
, 0, &dwTid
);
1851 ok(hThread
!= NULL
, "CreateThread failed with error %d\n", GetLastError());
1853 SetLastError(0xdeadbeef);
1854 ret
= ImpersonateNamedPipeClient(hPipeServer
);
1855 error
= GetLastError();
1856 ok(ret
/* win2k3 */ || (error
== ERROR_CANNOT_IMPERSONATE
),
1857 "ImpersonateNamedPipeClient should have failed with ERROR_CANNOT_IMPERSONATE instead of %d\n", GetLastError());
1859 ret
= ConnectNamedPipe(hPipeServer
, NULL
);
1860 ok(ret
|| (GetLastError() == ERROR_PIPE_CONNECTED
), "ConnectNamedPipe failed with error %d\n", GetLastError());
1862 ret
= ReadFile(hPipeServer
, buffer
, sizeof(buffer
), &dwBytesRead
, NULL
);
1863 ok(ret
, "ReadFile failed with error %d\n", GetLastError());
1865 ret
= ImpersonateNamedPipeClient(hPipeServer
);
1866 ok(ret
, "ImpersonateNamedPipeClient failed with error %d\n", GetLastError());
1868 ret
= OpenThreadToken(GetCurrentThread(), TOKEN_QUERY
, FALSE
, &hToken
);
1869 ok(ret
, "OpenThreadToken failed with error %d\n", GetLastError());
1871 (*test_func
)(0, hToken
);
1873 ImpersonationLevel
= 0xdeadbeef; /* to avoid false positives */
1874 ret
= GetTokenInformation(hToken
, TokenImpersonationLevel
, &ImpersonationLevel
, sizeof(ImpersonationLevel
), &size
);
1875 ok(ret
, "GetTokenInformation(TokenImpersonationLevel) failed with error %d\n", GetLastError());
1876 ok(ImpersonationLevel
== SecurityImpersonation
, "ImpersonationLevel should have been SecurityImpersonation(%d) instead of %d\n", SecurityImpersonation
, ImpersonationLevel
);
1878 CloseHandle(hToken
);
1882 ret
= WriteFile(hPipeServer
, &dummy
, sizeof(dummy
), &dwBytesWritten
, NULL
);
1883 ok(ret
, "WriteFile failed with error %d\n", GetLastError());
1885 ret
= ReadFile(hPipeServer
, buffer
, sizeof(buffer
), &dwBytesRead
, NULL
);
1886 ok(ret
, "ReadFile failed with error %d\n", GetLastError());
1888 ret
= ImpersonateNamedPipeClient(hPipeServer
);
1889 ok(ret
, "ImpersonateNamedPipeClient failed with error %d\n", GetLastError());
1891 ret
= OpenThreadToken(GetCurrentThread(), TOKEN_QUERY
, FALSE
, &hToken
);
1892 ok(ret
, "OpenThreadToken failed with error %d\n", GetLastError());
1894 (*test_func
)(1, hToken
);
1896 CloseHandle(hToken
);
1900 ret
= WriteFile(hPipeServer
, &dummy
, sizeof(dummy
), &dwBytesWritten
, NULL
);
1901 ok(ret
, "WriteFile failed with error %d\n", GetLastError());
1903 WaitForSingleObject(hThread
, INFINITE
);
1905 ret
= ImpersonateNamedPipeClient(hPipeServer
);
1906 ok(ret
, "ImpersonateNamedPipeClient failed with error %d\n", GetLastError());
1910 CloseHandle(hThread
);
1911 CloseHandle(hPipeServer
);
1914 static BOOL
are_all_privileges_disabled(HANDLE hToken
)
1917 TOKEN_PRIVILEGES
*Privileges
= NULL
;
1919 BOOL all_privs_disabled
= TRUE
;
1922 ret
= GetTokenInformation(hToken
, TokenPrivileges
, NULL
, 0, &Size
);
1923 if (!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
1925 Privileges
= HeapAlloc(GetProcessHeap(), 0, Size
);
1926 ret
= GetTokenInformation(hToken
, TokenPrivileges
, Privileges
, Size
, &Size
);
1929 HeapFree(GetProcessHeap(), 0, Privileges
);
1936 for (i
= 0; i
< Privileges
->PrivilegeCount
; i
++)
1938 if (Privileges
->Privileges
[i
].Attributes
& SE_PRIVILEGE_ENABLED
)
1940 all_privs_disabled
= FALSE
;
1945 HeapFree(GetProcessHeap(), 0, Privileges
);
1947 return all_privs_disabled
;
1950 static DWORD
get_privilege_count(HANDLE hToken
)
1952 TOKEN_STATISTICS Statistics
;
1953 DWORD Size
= sizeof(Statistics
);
1956 ret
= GetTokenInformation(hToken
, TokenStatistics
, &Statistics
, Size
, &Size
);
1957 ok(ret
, "GetTokenInformation(TokenStatistics)\n");
1958 if (!ret
) return -1;
1960 return Statistics
.PrivilegeCount
;
1963 static void test_no_sqos_no_token(int call_index
, HANDLE hToken
)
1970 priv_count
= get_privilege_count(hToken
);
1972 ok(priv_count
== 0, "privilege count should have been 0 instead of %d\n", priv_count
);
1975 priv_count
= get_privilege_count(hToken
);
1976 ok(priv_count
> 0, "privilege count should now be > 0 instead of 0\n");
1977 ok(!are_all_privileges_disabled(hToken
), "impersonated token should not have been modified\n");
1980 ok(0, "shouldn't happen\n");
1984 static void test_no_sqos(int call_index
, HANDLE hToken
)
1989 ok(!are_all_privileges_disabled(hToken
), "token should be a copy of the process one\n");
1993 ok(are_all_privileges_disabled(hToken
), "impersonated token should have been modified\n");
1996 ok(0, "shouldn't happen\n");
2000 static void test_static_context(int call_index
, HANDLE hToken
)
2005 ok(!are_all_privileges_disabled(hToken
), "token should be a copy of the process one\n");
2008 ok(!are_all_privileges_disabled(hToken
), "impersonated token should not have been modified\n");
2011 ok(0, "shouldn't happen\n");
2015 static void test_dynamic_context(int call_index
, HANDLE hToken
)
2020 ok(!are_all_privileges_disabled(hToken
), "token should be a copy of the process one\n");
2024 ok(are_all_privileges_disabled(hToken
), "impersonated token should have been modified\n");
2027 ok(0, "shouldn't happen\n");
2031 static void test_dynamic_context_no_token(int call_index
, HANDLE hToken
)
2036 ok(are_all_privileges_disabled(hToken
), "token should be a copy of the process one\n");
2039 ok(!are_all_privileges_disabled(hToken
), "process token modification should have been detected and impersonation token updated\n");
2042 ok(0, "shouldn't happen\n");
2046 static void test_no_sqos_revert(int call_index
, HANDLE hToken
)
2052 priv_count
= get_privilege_count(hToken
);
2054 ok(priv_count
== 0, "privilege count should have been 0 instead of %d\n", priv_count
);
2057 priv_count
= get_privilege_count(hToken
);
2058 ok(priv_count
> 0, "privilege count should now be > 0 instead of 0\n");
2059 ok(!are_all_privileges_disabled(hToken
), "impersonated token should not have been modified\n");
2062 ok(0, "shouldn't happen\n");
2066 static void test_static_context_revert(int call_index
, HANDLE hToken
)
2072 ok(are_all_privileges_disabled(hToken
), "privileges should have been disabled\n");
2076 ok(are_all_privileges_disabled(hToken
), "impersonated token should not have been modified\n");
2079 ok(0, "shouldn't happen\n");
2083 static void test_dynamic_context_revert(int call_index
, HANDLE hToken
)
2089 ok(are_all_privileges_disabled(hToken
), "privileges should have been disabled\n");
2092 ok(!are_all_privileges_disabled(hToken
), "impersonated token should now be process token\n");
2095 ok(0, "shouldn't happen\n");
2099 static void test_impersonation(void)
2101 HANDLE hClientToken
;
2102 HANDLE hProcessToken
;
2105 if( !pDuplicateTokenEx
) {
2106 skip("DuplicateTokenEx not found\n");
2110 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
, &hProcessToken
);
2113 skip("couldn't open process token, skipping impersonation tests\n");
2117 if (!get_privilege_count(hProcessToken
) || are_all_privileges_disabled(hProcessToken
))
2119 skip("token didn't have any privileges or they were all disabled. token not suitable for impersonation tests\n");
2120 CloseHandle(hProcessToken
);
2123 CloseHandle(hProcessToken
);
2125 test_ImpersonateNamedPipeClient(NULL
, 0, FALSE
, test_no_sqos_no_token
);
2126 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2127 test_ImpersonateNamedPipeClient(hClientToken
, 0, FALSE
, test_no_sqos
);
2128 CloseHandle(hClientToken
);
2129 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2130 test_ImpersonateNamedPipeClient(hClientToken
,
2131 SECURITY_SQOS_PRESENT
| SECURITY_IMPERSONATION
, FALSE
,
2132 test_static_context
);
2133 CloseHandle(hClientToken
);
2134 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2135 test_ImpersonateNamedPipeClient(hClientToken
,
2136 SECURITY_SQOS_PRESENT
| SECURITY_CONTEXT_TRACKING
| SECURITY_IMPERSONATION
,
2137 FALSE
, test_dynamic_context
);
2138 CloseHandle(hClientToken
);
2139 test_ImpersonateNamedPipeClient(NULL
,
2140 SECURITY_SQOS_PRESENT
| SECURITY_CONTEXT_TRACKING
| SECURITY_IMPERSONATION
,
2141 FALSE
, test_dynamic_context_no_token
);
2143 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2144 test_ImpersonateNamedPipeClient(hClientToken
, 0, TRUE
, test_no_sqos_revert
);
2145 CloseHandle(hClientToken
);
2146 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2147 test_ImpersonateNamedPipeClient(hClientToken
,
2148 SECURITY_SQOS_PRESENT
| SECURITY_IMPERSONATION
, TRUE
,
2149 test_static_context_revert
);
2150 CloseHandle(hClientToken
);
2151 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2152 test_ImpersonateNamedPipeClient(hClientToken
,
2153 SECURITY_SQOS_PRESENT
| SECURITY_CONTEXT_TRACKING
| SECURITY_IMPERSONATION
,
2154 TRUE
, test_dynamic_context_revert
);
2155 CloseHandle(hClientToken
);
2158 struct overlapped_server_args
2160 HANDLE pipe_created
;
2163 static DWORD CALLBACK
overlapped_server(LPVOID arg
)
2168 struct overlapped_server_args
*a
= arg
;
2172 pipe
= CreateNamedPipeA("\\\\.\\pipe\\my pipe", FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
, PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
, 1, 0, 0, 100000, NULL
);
2173 ok(pipe
!= NULL
, "pipe NULL\n");
2175 ol
.hEvent
= CreateEventA(0, 1, 0, 0);
2176 ok(ol
.hEvent
!= NULL
, "event NULL\n");
2177 ret
= ConnectNamedPipe(pipe
, &ol
);
2178 err
= GetLastError();
2179 ok(ret
== 0, "ret %d\n", ret
);
2180 ok(err
== ERROR_IO_PENDING
, "gle %d\n", err
);
2181 SetEvent(a
->pipe_created
);
2183 ret
= WaitForSingleObjectEx(ol
.hEvent
, INFINITE
, 1);
2184 ok(ret
== WAIT_OBJECT_0
, "ret %x\n", ret
);
2186 ret
= GetOverlappedResult(pipe
, &ol
, &num
, 1);
2187 ok(ret
== 1, "ret %d\n", ret
);
2189 /* This should block */
2190 ret
= ReadFile(pipe
, buf
, sizeof(buf
), &num
, NULL
);
2191 ok(ret
== 1, "ret %d\n", ret
);
2193 DisconnectNamedPipe(pipe
);
2195 ret
= ConnectNamedPipe(pipe
, &ol
);
2196 err
= GetLastError();
2197 ok(ret
== 0, "ret %d\n", ret
);
2198 ok(err
== ERROR_IO_PENDING
, "gle %d\n", err
);
2200 ret
= WaitForSingleObjectEx(ol
.hEvent
, INFINITE
, 1);
2201 ok(ret
== WAIT_OBJECT_0
, "ret %x\n", ret
);
2203 ret
= GetOverlappedResult(pipe
, &ol
, &num
, 1);
2204 err
= GetLastError();
2205 ok(ret
== 0, "ret %d\n", ret
);
2206 ok(err
== ERROR_OPERATION_ABORTED
, "gle %d\n", err
);
2208 CloseHandle(ol
.hEvent
);
2213 static void test_overlapped(void)
2216 HANDLE thread
, pipe
;
2218 struct overlapped_server_args args
;
2220 args
.pipe_created
= CreateEventA(0, 1, 0, 0);
2221 thread
= CreateThread(NULL
, 0, overlapped_server
, &args
, 0, &tid
);
2223 WaitForSingleObject(args
.pipe_created
, INFINITE
);
2224 pipe
= CreateFileA("\\\\.\\pipe\\my pipe", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
2225 ok(pipe
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2227 /* Sleep to try to get the ReadFile in the server to occur before the following WriteFile */
2230 ret
= WriteFile(pipe
, "x", 1, &num
, NULL
);
2231 ok(ret
, "WriteFile failed with error %d\n", GetLastError());
2233 WaitForSingleObject(thread
, INFINITE
);
2235 CloseHandle(args
.pipe_created
);
2236 CloseHandle(thread
);
2239 static void test_overlapped_error(void)
2241 HANDLE pipe
, file
, event
;
2242 DWORD err
, numbytes
;
2243 OVERLAPPED overlapped
;
2246 event
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
2247 ok(event
!= NULL
, "CreateEventA failed with %u\n", GetLastError());
2249 pipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
2250 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
2251 1, 1024, 1024, NMPWAIT_WAIT_FOREVER
, NULL
);
2252 ok(pipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %u\n", GetLastError());
2254 memset(&overlapped
, 0, sizeof(overlapped
));
2255 overlapped
.hEvent
= event
;
2256 ret
= ConnectNamedPipe(pipe
, &overlapped
);
2257 err
= GetLastError();
2258 ok(ret
== FALSE
, "ConnectNamedPipe succeeded\n");
2259 ok(err
== ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %u\n", err
);
2261 file
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
,
2262 OPEN_EXISTING
, FILE_FLAG_OVERLAPPED
, 0);
2263 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %u\n", GetLastError());
2265 numbytes
= 0xdeadbeef;
2266 ret
= GetOverlappedResult(pipe
, &overlapped
, &numbytes
, TRUE
);
2267 ok(ret
== TRUE
, "GetOverlappedResult failed\n");
2268 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
2269 ok(overlapped
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08lx\n", overlapped
.Internal
);
2274 pipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
2275 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
2276 1, 1024, 1024, NMPWAIT_WAIT_FOREVER
, NULL
);
2277 ok(pipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %u\n", GetLastError());
2279 file
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
,
2280 OPEN_EXISTING
, FILE_FLAG_OVERLAPPED
, 0);
2281 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %u\n", GetLastError());
2283 memset(&overlapped
, 0, sizeof(overlapped
));
2284 overlapped
.hEvent
= event
;
2285 ret
= ConnectNamedPipe(pipe
, &overlapped
);
2286 err
= GetLastError();
2287 ok(ret
== FALSE
, "ConnectNamedPipe succeeded\n");
2288 ok(err
== ERROR_PIPE_CONNECTED
, "expected ERROR_PIPE_CONNECTED, got %u\n", err
);
2289 ok(overlapped
.Internal
== STATUS_PENDING
, "expected STATUS_PENDING, got %08lx\n", overlapped
.Internal
);
2297 static void test_NamedPipeHandleState(void)
2299 HANDLE server
, client
;
2301 DWORD state
, instances
, maxCollectionCount
, collectDataTimeout
;
2302 char userName
[MAX_PATH
];
2304 server
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
2305 /* dwOpenMode */ PIPE_TYPE_BYTE
| PIPE_WAIT
,
2306 /* nMaxInstances */ 1,
2307 /* nOutBufSize */ 1024,
2308 /* nInBufSize */ 1024,
2309 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2310 /* lpSecurityAttrib */ NULL
);
2311 ok(server
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2312 ret
= GetNamedPipeHandleStateA(server
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
2313 ok(ret
, "GetNamedPipeHandleState failed: %d\n", GetLastError());
2314 ret
= GetNamedPipeHandleStateA(server
, &state
, &instances
, NULL
, NULL
, NULL
,
2316 ok(ret
, "GetNamedPipeHandleState failed: %d\n", GetLastError());
2319 ok(state
== 0, "unexpected state %08x\n", state
);
2320 ok(instances
== 1, "expected 1 instances, got %d\n", instances
);
2322 /* Some parameters have no meaning, and therefore can't be retrieved,
2325 SetLastError(0xdeadbeef);
2326 ret
= GetNamedPipeHandleStateA(server
, &state
, &instances
,
2327 &maxCollectionCount
, &collectDataTimeout
, userName
,
2328 sizeof(userName
) / sizeof(userName
[0]));
2330 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2331 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2332 /* A byte-mode pipe server can't be changed to message mode. */
2333 state
= PIPE_READMODE_MESSAGE
;
2334 SetLastError(0xdeadbeef);
2335 ret
= SetNamedPipeHandleState(server
, &state
, NULL
, NULL
);
2336 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2337 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2339 client
= CreateFileA(PIPENAME
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
2340 OPEN_EXISTING
, 0, NULL
);
2341 ok(client
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2343 state
= PIPE_READMODE_BYTE
;
2344 ret
= SetNamedPipeHandleState(client
, &state
, NULL
, NULL
);
2345 ok(ret
, "SetNamedPipeHandleState failed: %d\n", GetLastError());
2346 /* A byte-mode pipe client can't be changed to message mode, either. */
2347 state
= PIPE_READMODE_MESSAGE
;
2348 SetLastError(0xdeadbeef);
2349 ret
= SetNamedPipeHandleState(server
, &state
, NULL
, NULL
);
2350 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2351 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2353 CloseHandle(client
);
2354 CloseHandle(server
);
2356 server
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
2357 /* dwOpenMode */ PIPE_TYPE_MESSAGE
| PIPE_WAIT
,
2358 /* nMaxInstances */ 1,
2359 /* nOutBufSize */ 1024,
2360 /* nInBufSize */ 1024,
2361 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2362 /* lpSecurityAttrib */ NULL
);
2363 ok(server
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2364 ret
= GetNamedPipeHandleStateA(server
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
2365 ok(ret
, "GetNamedPipeHandleState failed: %d\n", GetLastError());
2366 ret
= GetNamedPipeHandleStateA(server
, &state
, &instances
, NULL
, NULL
, NULL
,
2368 ok(ret
, "GetNamedPipeHandleState failed: %d\n", GetLastError());
2371 ok(state
== 0, "unexpected state %08x\n", state
);
2372 ok(instances
== 1, "expected 1 instances, got %d\n", instances
);
2374 /* In contrast to byte-mode pipes, a message-mode pipe server can be
2375 * changed to byte mode.
2377 state
= PIPE_READMODE_BYTE
;
2378 ret
= SetNamedPipeHandleState(server
, &state
, NULL
, NULL
);
2379 ok(ret
, "SetNamedPipeHandleState failed: %d\n", GetLastError());
2381 client
= CreateFileA(PIPENAME
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
2382 OPEN_EXISTING
, 0, NULL
);
2383 ok(client
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2385 state
= PIPE_READMODE_MESSAGE
;
2386 ret
= SetNamedPipeHandleState(client
, &state
, NULL
, NULL
);
2387 ok(ret
, "SetNamedPipeHandleState failed: %d\n", GetLastError());
2388 /* A message-mode pipe client can also be changed to byte mode.
2390 state
= PIPE_READMODE_BYTE
;
2391 ret
= SetNamedPipeHandleState(client
, &state
, NULL
, NULL
);
2392 ok(ret
, "SetNamedPipeHandleState failed: %d\n", GetLastError());
2394 CloseHandle(client
);
2395 CloseHandle(server
);
2398 static void test_GetNamedPipeInfo(void)
2402 server
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
2403 /* dwOpenMode */ PIPE_TYPE_BYTE
| PIPE_WAIT
,
2404 /* nMaxInstances */ 1,
2405 /* nOutBufSize */ 1024,
2406 /* nInBufSize */ 1024,
2407 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2408 /* lpSecurityAttrib */ NULL
);
2409 ok(server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
2411 test_pipe_info(server
, PIPE_SERVER_END
| PIPE_TYPE_BYTE
, 1024, 1024, 1);
2413 CloseHandle(server
);
2415 server
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
2416 /* dwOpenMode */ PIPE_TYPE_MESSAGE
| PIPE_NOWAIT
,
2417 /* nMaxInstances */ 3,
2418 /* nOutBufSize */ 1024,
2419 /* nInBufSize */ 1024,
2420 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2421 /* lpSecurityAttrib */ NULL
);
2422 ok(server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
2424 test_pipe_info(server
, PIPE_SERVER_END
| PIPE_TYPE_MESSAGE
, 1024, 1024, 3);
2426 CloseHandle(server
);
2428 server
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
,
2429 /* dwOpenMode */ PIPE_TYPE_MESSAGE
| PIPE_WAIT
,
2430 /* nMaxInstances */ 1,
2431 /* nOutBufSize */ 0,
2433 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2434 /* lpSecurityAttrib */ NULL
);
2435 ok(server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
2437 test_pipe_info(server
, PIPE_SERVER_END
| PIPE_TYPE_MESSAGE
, 0, 0, 1);
2439 CloseHandle(server
);
2441 server
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
,
2442 /* dwOpenMode */ PIPE_TYPE_MESSAGE
| PIPE_WAIT
,
2443 /* nMaxInstances */ 1,
2444 /* nOutBufSize */ 0xf000,
2445 /* nInBufSize */ 0xf000,
2446 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2447 /* lpSecurityAttrib */ NULL
);
2448 ok(server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
2450 test_pipe_info(server
, PIPE_SERVER_END
| PIPE_TYPE_MESSAGE
, 0xf000, 0xf000, 1);
2452 CloseHandle(server
);
2455 static void test_readfileex_pending(void)
2457 HANDLE server
, client
, event
;
2459 DWORD err
, wait
, num_bytes
;
2460 OVERLAPPED overlapped
;
2461 char read_buf
[1024];
2462 char write_buf
[1024];
2463 const char test_string
[] = "test";
2466 server
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| 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
, "cf failed\n");
2475 event
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
2476 ok(event
!= NULL
, "CreateEventA failed\n");
2478 memset(&overlapped
, 0, sizeof(overlapped
));
2479 overlapped
.hEvent
= event
;
2481 ret
= ConnectNamedPipe(server
, &overlapped
);
2482 err
= GetLastError();
2483 ok(ret
== FALSE
, "ConnectNamedPipe succeeded\n");
2484 ok(err
== ERROR_IO_PENDING
, "ConnectNamedPipe set error %i\n", err
);
2486 wait
= WaitForSingleObject(event
, 0);
2487 ok(wait
== WAIT_TIMEOUT
, "WaitForSingleObject returned %x\n", wait
);
2489 client
= CreateFileA(PIPENAME
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
2490 OPEN_EXISTING
, 0, NULL
);
2491 ok(client
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2493 wait
= WaitForSingleObject(event
, 0);
2494 ok(wait
== WAIT_OBJECT_0
, "WaitForSingleObject returned %x\n", wait
);
2496 /* Start a read that can't complete immediately. */
2497 completion_called
= 0;
2499 ret
= ReadFileEx(server
, read_buf
, sizeof(read_buf
), &overlapped
, completion_routine
);
2500 ok(ret
== TRUE
, "ReadFileEx failed, err=%i\n", GetLastError());
2501 ok(completion_called
== 0, "completion routine called before ReadFileEx returned\n");
2503 ret
= WriteFile(client
, test_string
, strlen(test_string
), &num_bytes
, NULL
);
2504 ok(ret
== TRUE
, "WriteFile failed\n");
2505 ok(num_bytes
== strlen(test_string
), "only %i bytes written\n", num_bytes
);
2507 ok(completion_called
== 0, "completion routine called during WriteFile\n");
2509 wait
= WaitForSingleObjectEx(event
, 0, TRUE
);
2510 ok(wait
== WAIT_IO_COMPLETION
|| wait
== WAIT_OBJECT_0
, "WaitForSingleObjectEx returned %x\n", wait
);
2512 ok(completion_called
== 1, "completion not called after writing pipe\n");
2513 ok(completion_errorcode
== 0, "completion called with error %x\n", completion_errorcode
);
2514 ok(completion_num_bytes
== strlen(test_string
), "ReadFileEx returned only %d bytes\n", completion_num_bytes
);
2515 ok(completion_lpoverlapped
== &overlapped
, "completion called with wrong overlapped pointer\n");
2516 ok(!memcmp(test_string
, read_buf
, strlen(test_string
)), "ReadFileEx read wrong bytes\n");
2518 /* Make writes until the pipe is full and the write fails */
2519 memset(write_buf
, 0xaa, sizeof(write_buf
));
2520 for (i
=0; i
<256; i
++)
2522 completion_called
= 0;
2524 ret
= WriteFileEx(server
, write_buf
, sizeof(write_buf
), &overlapped
, completion_routine
);
2525 err
= GetLastError();
2527 ok(completion_called
== 0, "completion routine called during WriteFileEx\n");
2529 wait
= WaitForSingleObjectEx(event
, 0, TRUE
);
2531 if (wait
== WAIT_TIMEOUT
)
2532 /* write couldn't complete immediately, presumably the pipe is full */
2535 ok(wait
== WAIT_IO_COMPLETION
|| wait
== WAIT_OBJECT_0
, "WaitForSingleObject returned %x\n", wait
);
2537 ok(ret
== TRUE
, "WriteFileEx failed, err=%i\n", err
);
2538 ok(completion_errorcode
== 0, "completion called with error %x\n", completion_errorcode
);
2539 ok(completion_lpoverlapped
== &overlapped
, "completion called with wrong overlapped pointer\n");
2542 ok(ret
== TRUE
, "WriteFileEx failed, err=%i\n", err
);
2543 ok(completion_called
== 0, "completion routine called but wait timed out\n");
2544 ok(completion_errorcode
== 0, "completion called with error %x\n", completion_errorcode
);
2545 ok(completion_lpoverlapped
== &overlapped
, "completion called with wrong overlapped pointer\n");
2547 /* free up some space in the pipe */
2548 for (i
=0; i
<256; i
++)
2550 ret
= ReadFile(client
, read_buf
, sizeof(read_buf
), &num_bytes
, NULL
);
2551 ok(ret
== TRUE
, "ReadFile failed\n");
2553 ok(completion_called
== 0, "completion routine called during ReadFile\n");
2555 wait
= WaitForSingleObjectEx(event
, 0, TRUE
);
2556 ok(wait
== WAIT_IO_COMPLETION
|| wait
== WAIT_OBJECT_0
|| wait
== WAIT_TIMEOUT
,
2557 "WaitForSingleObject returned %x\n", wait
);
2558 if (wait
!= WAIT_TIMEOUT
) break;
2561 ok(completion_called
== 1, "completion routine not called\n");
2562 ok(completion_errorcode
== 0, "completion called with error %x\n", completion_errorcode
);
2563 ok(completion_lpoverlapped
== &overlapped
, "completion called with wrong overlapped pointer\n");
2565 num_bytes
= 0xdeadbeef;
2566 SetLastError(0xdeadbeef);
2567 ret
= ReadFile(INVALID_HANDLE_VALUE
, read_buf
, 0, &num_bytes
, NULL
);
2568 ok(!ret
, "ReadFile should fail\n");
2569 ok(GetLastError() == ERROR_INVALID_HANDLE
, "wrong error %u\n", GetLastError());
2570 ok(num_bytes
== 0, "expected 0, got %u\n", num_bytes
);
2572 S(U(overlapped
)).Offset
= 0;
2573 S(U(overlapped
)).OffsetHigh
= 0;
2574 overlapped
.Internal
= -1;
2575 overlapped
.InternalHigh
= -1;
2576 overlapped
.hEvent
= event
;
2577 num_bytes
= 0xdeadbeef;
2578 SetLastError(0xdeadbeef);
2579 ret
= ReadFile(server
, read_buf
, 0, &num_bytes
, &overlapped
);
2580 ok(!ret
, "ReadFile should fail\n");
2581 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
2582 ok(num_bytes
== 0, "bytes %u\n", num_bytes
);
2583 ok((NTSTATUS
)overlapped
.Internal
== STATUS_PENDING
, "expected STATUS_PENDING, got %#lx\n", overlapped
.Internal
);
2585 ok(overlapped
.InternalHigh
== -1, "expected -1, got %lu\n", overlapped
.InternalHigh
);
2587 wait
= WaitForSingleObject(event
, 100);
2588 ok(wait
== WAIT_TIMEOUT
, "WaitForSingleObject returned %x\n", wait
);
2590 num_bytes
= 0xdeadbeef;
2591 ret
= WriteFile(client
, test_string
, 1, &num_bytes
, NULL
);
2592 ok(ret
, "WriteFile failed\n");
2593 ok(num_bytes
== 1, "bytes %u\n", num_bytes
);
2595 wait
= WaitForSingleObject(event
, 100);
2596 ok(wait
== WAIT_OBJECT_0
, "WaitForSingleObject returned %x\n", wait
);
2598 ok(num_bytes
== 1, "bytes %u\n", num_bytes
);
2599 ok((NTSTATUS
)overlapped
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", overlapped
.Internal
);
2600 ok(overlapped
.InternalHigh
== 0, "expected 0, got %lu\n", overlapped
.InternalHigh
);
2602 /* read the pending byte and clear the pipe */
2603 num_bytes
= 0xdeadbeef;
2604 ret
= ReadFile(server
, read_buf
, 1, &num_bytes
, &overlapped
);
2605 ok(ret
, "ReadFile failed\n");
2606 ok(num_bytes
== 1, "bytes %u\n", num_bytes
);
2608 CloseHandle(client
);
2609 CloseHandle(server
);
2613 #define test_peek_pipe(a,b,c,d) _test_peek_pipe(__LINE__,a,b,c,d)
2614 static void _test_peek_pipe(unsigned line
, HANDLE pipe
, DWORD expected_read
, DWORD expected_avail
, DWORD expected_message_length
)
2616 DWORD bytes_read
= 0xdeadbeed, avail
= 0xdeadbeef, left
= 0xdeadbeed;
2618 FILE_PIPE_PEEK_BUFFER
*peek_buf
= (void*)buf
;
2623 r
= PeekNamedPipe(pipe
, buf
, sizeof(buf
), &bytes_read
, &avail
, &left
);
2624 ok_(__FILE__
,line
)(r
, "PeekNamedPipe failed: %u\n", GetLastError());
2625 ok_(__FILE__
,line
)(bytes_read
== expected_read
, "bytes_read = %u, expected %u\n", bytes_read
, expected_read
);
2626 ok_(__FILE__
,line
)(avail
== expected_avail
, "avail = %u, expected %u\n", avail
, expected_avail
);
2627 ok_(__FILE__
,line
)(left
== expected_message_length
- expected_read
, "left = %d, expected %d\n",
2628 left
, expected_message_length
- expected_read
);
2630 status
= NtFsControlFile(pipe
, 0, NULL
, NULL
, &io
, FSCTL_PIPE_PEEK
, NULL
, 0, buf
, sizeof(buf
));
2631 ok_(__FILE__
,line
)(!status
|| status
== STATUS_PENDING
, "NtFsControlFile(FSCTL_PIPE_PEEK) failed: %x\n", status
);
2632 ok_(__FILE__
,line
)(io
.Information
== FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER
, Data
[expected_read
]),
2633 "io.Information = %lu\n", io
.Information
);
2634 ok_(__FILE__
,line
)(peek_buf
->ReadDataAvailable
== expected_avail
, "ReadDataAvailable = %u, expected %u\n",
2635 peek_buf
->ReadDataAvailable
, expected_avail
);
2636 ok_(__FILE__
,line
)(peek_buf
->MessageLength
== expected_message_length
, "MessageLength = %u, expected %u\n",
2637 peek_buf
->MessageLength
, expected_message_length
);
2641 r
= PeekNamedPipe(pipe
, buf
, 1, &bytes_read
, &avail
, &left
);
2642 ok_(__FILE__
,line
)(r
, "PeekNamedPipe failed: %u\n", GetLastError());
2643 ok_(__FILE__
,line
)(bytes_read
== 1, "bytes_read = %u, expected %u\n", bytes_read
, expected_read
);
2644 ok_(__FILE__
,line
)(avail
== expected_avail
, "avail = %u, expected %u\n", avail
, expected_avail
);
2645 ok_(__FILE__
,line
)(left
== expected_message_length
-1, "left = %d, expected %d\n", left
, expected_message_length
-1);
2649 #define overlapped_read_sync(a,b,c,d,e) _overlapped_read_sync(__LINE__,a,b,c,d,e)
2650 static void _overlapped_read_sync(unsigned line
, HANDLE reader
, void *buf
, DWORD buf_size
, DWORD expected_result
, BOOL partial_read
)
2652 DWORD read_bytes
= 0xdeadbeef;
2653 OVERLAPPED overlapped
;
2656 memset(&overlapped
, 0, sizeof(overlapped
));
2657 overlapped
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
2658 res
= ReadFile(reader
, buf
, buf_size
, &read_bytes
, &overlapped
);
2660 ok_(__FILE__
,line
)(!res
&& GetLastError() == ERROR_MORE_DATA
, "ReadFile returned: %x (%u)\n", res
, GetLastError());
2662 ok_(__FILE__
,line
)(res
, "ReadFile failed: %u\n", GetLastError());
2664 todo_wine
ok_(__FILE__
,line
)(!read_bytes
, "read_bytes %u expected 0\n", read_bytes
);
2666 ok_(__FILE__
,line
)(read_bytes
== expected_result
, "read_bytes %u expected %u\n", read_bytes
, expected_result
);
2668 read_bytes
= 0xdeadbeef;
2669 res
= GetOverlappedResult(reader
, &overlapped
, &read_bytes
, FALSE
);
2671 ok_(__FILE__
,line
)(!res
&& GetLastError() == ERROR_MORE_DATA
,
2672 "GetOverlappedResult returned: %x (%u)\n", res
, GetLastError());
2674 ok_(__FILE__
,line
)(res
, "GetOverlappedResult failed: %u\n", GetLastError());
2675 ok_(__FILE__
,line
)(read_bytes
== expected_result
, "read_bytes %u expected %u\n", read_bytes
, expected_result
);
2676 CloseHandle(overlapped
.hEvent
);
2679 #define overlapped_read_async(a,b,c,d) _overlapped_read_async(__LINE__,a,b,c,d)
2680 static void _overlapped_read_async(unsigned line
, HANDLE reader
, void *buf
, DWORD buf_size
, OVERLAPPED
*overlapped
)
2682 DWORD read_bytes
= 0xdeadbeef;
2685 memset(overlapped
, 0, sizeof(*overlapped
));
2686 overlapped
->hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
2687 res
= ReadFile(reader
, buf
, buf_size
, &read_bytes
, overlapped
);
2688 ok_(__FILE__
,line
)(!res
&& GetLastError() == ERROR_IO_PENDING
, "ReadFile returned %x(%u)\n", res
, GetLastError());
2689 ok_(__FILE__
,line
)(!read_bytes
, "read_bytes %u expected 0\n", read_bytes
);
2691 _test_not_signaled(line
, overlapped
->hEvent
);
2694 #define overlapped_write_sync(a,b,c) _overlapped_write_sync(__LINE__,a,b,c)
2695 static void _overlapped_write_sync(unsigned line
, HANDLE writer
, void *buf
, DWORD size
)
2697 DWORD written_bytes
= 0xdeadbeef;
2698 OVERLAPPED overlapped
;
2701 memset(&overlapped
, 0, sizeof(overlapped
));
2702 overlapped
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
2703 res
= WriteFile(writer
, buf
, size
, &written_bytes
, &overlapped
);
2704 ok_(__FILE__
,line
)(res
, "WriteFile returned %x(%u)\n", res
, GetLastError());
2705 ok_(__FILE__
,line
)(written_bytes
== size
, "WriteFile returned written_bytes = %u\n", written_bytes
);
2707 written_bytes
= 0xdeadbeef;
2708 res
= GetOverlappedResult(writer
, &overlapped
, &written_bytes
, FALSE
);
2709 ok_(__FILE__
,line
)(res
, "GetOverlappedResult failed: %u\n", GetLastError());
2710 ok_(__FILE__
,line
)(written_bytes
== size
, "GetOverlappedResult returned written_bytes %u expected %u\n", written_bytes
, size
);
2712 CloseHandle(overlapped
.hEvent
);
2715 #define overlapped_write_async(a,b,c,d) _overlapped_write_async(__LINE__,a,b,c,d)
2716 static void _overlapped_write_async(unsigned line
, HANDLE writer
, void *buf
, DWORD size
, OVERLAPPED
*overlapped
)
2718 DWORD written_bytes
= 0xdeadbeef;
2721 memset(overlapped
, 0, sizeof(*overlapped
));
2722 overlapped
->hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
2723 res
= WriteFile(writer
, buf
, size
, &written_bytes
, overlapped
);
2724 ok_(__FILE__
,line
)(!res
&& GetLastError() == ERROR_IO_PENDING
, "WriteFile returned %x(%u)\n", res
, GetLastError());
2725 todo_wine
ok_(__FILE__
,line
)(!written_bytes
, "written_bytes = %u\n", written_bytes
);
2727 _test_not_signaled(line
, overlapped
->hEvent
);
2730 #define test_flush_sync(a) _test_flush_sync(__LINE__,a)
2731 static void _test_flush_sync(unsigned line
, HANDLE pipe
)
2735 res
= FlushFileBuffers(pipe
);
2736 ok_(__FILE__
,line
)(res
, "FlushFileBuffers failed: %u\n", GetLastError());
2739 static DWORD expected_flush_error
;
2741 static DWORD CALLBACK
flush_proc(HANDLE pipe
)
2745 res
= FlushFileBuffers(pipe
);
2746 if (expected_flush_error
== ERROR_SUCCESS
)
2747 ok(res
, "FlushFileBuffers failed: %u\n", GetLastError());
2749 todo_wine
ok(!res
&& GetLastError() == expected_flush_error
, "FlushFileBuffers failed: %u\n", GetLastError());
2753 #define test_flush_async(a,b) _test_flush_async(__LINE__,a,b)
2754 static HANDLE
_test_flush_async(unsigned line
, HANDLE pipe
, DWORD error
)
2759 expected_flush_error
= error
;
2760 thread
= CreateThread(NULL
, 0, flush_proc
, pipe
, 0, &tid
);
2761 ok_(__FILE__
,line
)(thread
!= NULL
, "CreateThread failed: %u\n", GetLastError());
2764 _test_not_signaled(line
, thread
);
2768 #define test_flush_done(a) _test_flush_done(__LINE__,a)
2769 static void _test_flush_done(unsigned line
, HANDLE thread
)
2771 DWORD res
= WaitForSingleObject(thread
, 1000);
2772 ok_(__FILE__
,line
)(res
== WAIT_OBJECT_0
, "WaitForSingleObject returned %u (%u)\n", res
, GetLastError());
2773 CloseHandle(thread
);
2776 #define test_overlapped_result(a,b,c,d) _test_overlapped_result(__LINE__,a,b,c,d)
2777 static void _test_overlapped_result(unsigned line
, HANDLE handle
, OVERLAPPED
*overlapped
, DWORD expected_result
, BOOL partial_read
)
2779 DWORD result
= 0xdeadbeef;
2782 _test_signaled(line
, overlapped
->hEvent
);
2784 res
= GetOverlappedResult(handle
, overlapped
, &result
, FALSE
);
2786 ok_(__FILE__
,line
)(!res
&& GetLastError() == ERROR_MORE_DATA
, "GetOverlappedResult returned: %x (%u)\n", res
, GetLastError());
2788 ok_(__FILE__
,line
)(res
, "GetOverlappedResult failed: %u\n", GetLastError());
2789 ok_(__FILE__
,line
)(result
== expected_result
, "read_bytes = %u, expected %u\n", result
, expected_result
);
2790 CloseHandle(overlapped
->hEvent
);
2793 #define test_overlapped_failure(a,b,c) _test_overlapped_failure(__LINE__,a,b,c)
2794 static void _test_overlapped_failure(unsigned line
, HANDLE handle
, OVERLAPPED
*overlapped
, DWORD error
)
2799 _test_signaled(line
, overlapped
->hEvent
);
2801 res
= GetOverlappedResult(handle
, overlapped
, &result
, FALSE
);
2802 ok_(__FILE__
,line
)(!res
&& GetLastError() == error
, "GetOverlappedResult returned: %x (%u), expected error %u\n",
2803 res
, GetLastError(), error
);
2804 ok_(__FILE__
,line
)(!result
, "result = %u\n", result
);
2805 CloseHandle(overlapped
->hEvent
);
2808 #define cancel_overlapped(a,b) _cancel_overlapped(__LINE__,a,b)
2809 static void _cancel_overlapped(unsigned line
, HANDLE handle
, OVERLAPPED
*overlapped
)
2813 res
= pCancelIoEx(handle
, overlapped
);
2814 ok_(__FILE__
,line
)(res
, "CancelIoEx failed: %u\n", GetLastError());
2816 _test_overlapped_failure(line
, handle
, overlapped
, ERROR_OPERATION_ABORTED
);
2819 static void test_blocking_rw(HANDLE writer
, HANDLE reader
, DWORD buf_size
, BOOL msg_mode
, BOOL msg_read
)
2821 OVERLAPPED read_overlapped
, read_overlapped2
, write_overlapped
, write_overlapped2
;
2822 char buf
[10000], read_buf
[10000];
2823 HANDLE flush_thread
;
2825 memset(buf
, 0xaa, sizeof(buf
));
2827 /* test pending read with overlapped event */
2828 overlapped_read_async(reader
, read_buf
, 1000, &read_overlapped
);
2829 test_flush_sync(writer
);
2830 test_peek_pipe(reader
, 0, 0, 0);
2832 /* write more data than needed for read */
2833 overlapped_write_sync(writer
, buf
, 4000);
2834 test_overlapped_result(reader
, &read_overlapped
, 1000, msg_read
);
2836 /* test pending write with overlapped event */
2837 overlapped_write_async(writer
, buf
, buf_size
, &write_overlapped
);
2839 /* write one more byte */
2840 overlapped_write_async(writer
, buf
, 1, &write_overlapped2
);
2841 flush_thread
= test_flush_async(writer
, ERROR_SUCCESS
);
2842 test_not_signaled(write_overlapped
.hEvent
);
2844 /* empty write will not block */
2845 overlapped_write_sync(writer
, buf
, 0);
2846 test_not_signaled(write_overlapped
.hEvent
);
2847 test_not_signaled(write_overlapped2
.hEvent
);
2849 /* read remaining data from the first write */
2850 overlapped_read_sync(reader
, read_buf
, 3000, 3000, FALSE
);
2851 test_overlapped_result(writer
, &write_overlapped
, buf_size
, FALSE
);
2852 test_not_signaled(write_overlapped2
.hEvent
);
2853 test_not_signaled(flush_thread
);
2855 /* read one byte so that the next write fits the buffer */
2856 overlapped_read_sync(reader
, read_buf
, 1, 1, msg_read
);
2857 test_overlapped_result(writer
, &write_overlapped2
, 1, FALSE
);
2859 /* read the whole buffer */
2860 overlapped_read_sync(reader
, read_buf
, buf_size
, buf_size
-msg_read
, FALSE
);
2863 overlapped_read_sync(reader
, read_buf
, 1000, 1, FALSE
);
2866 /* we still have an empty message in queue */
2867 overlapped_read_sync(reader
, read_buf
, 1000, 0, FALSE
);
2869 test_flush_done(flush_thread
);
2871 /* pipe is empty, the next read will block */
2872 overlapped_read_async(reader
, read_buf
, 0, &read_overlapped
);
2873 overlapped_read_async(reader
, read_buf
, 1000, &read_overlapped2
);
2875 /* write one byte */
2876 overlapped_write_sync(writer
, buf
, 1);
2877 test_overlapped_result(reader
, &read_overlapped
, 0, msg_read
);
2878 test_overlapped_result(reader
, &read_overlapped2
, 1, FALSE
);
2880 /* write a message larger than buffer */
2881 overlapped_write_async(writer
, buf
, buf_size
+2000, &write_overlapped
);
2883 /* read so that pending write is still larger than the buffer */
2884 overlapped_read_sync(reader
, read_buf
, 1999, 1999, msg_read
);
2885 test_not_signaled(write_overlapped
.hEvent
);
2887 /* read one more byte */
2888 overlapped_read_sync(reader
, read_buf
, 1, 1, msg_read
);
2889 test_overlapped_result(writer
, &write_overlapped
, buf_size
+2000, FALSE
);
2891 /* read remaining data */
2892 overlapped_read_sync(reader
, read_buf
, buf_size
+1, buf_size
, FALSE
);
2894 /* simple pass of empty message */
2895 overlapped_write_sync(writer
, buf
, 0);
2897 overlapped_read_sync(reader
, read_buf
, 1, 0, FALSE
);
2899 /* pipe is empty, the next read will block */
2900 test_flush_sync(writer
);
2901 overlapped_read_async(reader
, read_buf
, 0, &read_overlapped
);
2902 overlapped_read_async(reader
, read_buf
, 1, &read_overlapped2
);
2904 /* 0 length write wakes one read in msg mode */
2905 overlapped_write_sync(writer
, buf
, 0);
2907 test_overlapped_result(reader
, &read_overlapped
, 0, FALSE
);
2909 test_not_signaled(read_overlapped
.hEvent
);
2910 test_not_signaled(read_overlapped2
.hEvent
);
2911 overlapped_write_sync(writer
, buf
, 1);
2912 test_overlapped_result(reader
, &read_overlapped2
, 1, FALSE
);
2914 overlapped_write_sync(writer
, buf
, 20);
2915 test_peek_pipe(reader
, 20, 20, msg_mode
? 20 : 0);
2916 overlapped_write_sync(writer
, buf
, 15);
2917 test_peek_pipe(reader
, msg_mode
? 20 : 35, 35, msg_mode
? 20 : 0);
2918 overlapped_read_sync(reader
, read_buf
, 10, 10, msg_read
);
2919 test_peek_pipe(reader
, msg_mode
? 10 : 25, 25, msg_mode
? 10 : 0);
2920 overlapped_read_sync(reader
, read_buf
, 10, 10, FALSE
);
2921 test_peek_pipe(reader
, 15, 15, msg_mode
? 15 : 0);
2922 overlapped_read_sync(reader
, read_buf
, 15, 15, FALSE
);
2925 win_skip("CancelIoEx not available\n");
2929 /* add one more pending read, then cancel the first one */
2930 overlapped_read_async(reader
, read_buf
, 1, &read_overlapped
);
2931 overlapped_read_async(reader
, read_buf
, 1, &read_overlapped2
);
2932 cancel_overlapped(reader
, &read_overlapped2
);
2933 test_not_signaled(read_overlapped
.hEvent
);
2934 overlapped_write_sync(writer
, buf
, 1);
2935 test_overlapped_result(reader
, &read_overlapped
, 1, FALSE
);
2937 /* make two async writes, cancel the first one and make sure that we read from the second one */
2938 overlapped_write_async(writer
, buf
, buf_size
+2000, &write_overlapped
);
2939 overlapped_write_async(writer
, buf
, 1, &write_overlapped2
);
2940 cancel_overlapped(writer
, &write_overlapped
);
2941 overlapped_read_sync(reader
, read_buf
, 1000, 1, FALSE
);
2942 test_overlapped_result(writer
, &write_overlapped2
, 1, FALSE
);
2944 /* same as above, but parially read written data before canceling */
2945 overlapped_write_async(writer
, buf
, buf_size
+2000, &write_overlapped
);
2946 overlapped_write_async(writer
, buf
, 1, &write_overlapped2
);
2947 overlapped_read_sync(reader
, read_buf
, 10, 10, msg_read
);
2948 test_not_signaled(write_overlapped
.hEvent
);
2949 cancel_overlapped(writer
, &write_overlapped
);
2950 overlapped_read_sync(reader
, read_buf
, 1000, 1, FALSE
);
2951 test_overlapped_result(writer
, &write_overlapped2
, 1, FALSE
);
2953 /* empty queue by canceling write and make sure that flush is signaled */
2954 overlapped_write_async(writer
, buf
, buf_size
+2000, &write_overlapped
);
2955 flush_thread
= test_flush_async(writer
, ERROR_SUCCESS
);
2956 test_not_signaled(flush_thread
);
2957 cancel_overlapped(writer
, &write_overlapped
);
2958 test_flush_done(flush_thread
);
2961 static void child_process_write_pipe(HANDLE pipe
)
2963 OVERLAPPED overlapped
;
2966 memset(buf
, 'x', sizeof(buf
));
2967 overlapped_write_async(pipe
, buf
, sizeof(buf
), &overlapped
);
2969 /* sleep until parent process terminates this process */
2973 static HANDLE
create_writepipe_process(HANDLE pipe
)
2975 STARTUPINFOA si
= { sizeof(si
) };
2976 PROCESS_INFORMATION info
;
2977 char **argv
, buf
[MAX_PATH
];
2980 winetest_get_mainargs(&argv
);
2981 sprintf(buf
, "\"%s\" pipe writepipe %lx", argv
[0], (UINT_PTR
)pipe
);
2982 res
= CreateProcessA(NULL
, buf
, NULL
, NULL
, TRUE
, 0L, NULL
, NULL
, &si
, &info
);
2983 ok(res
, "CreateProcess failed: %u\n", GetLastError());
2984 CloseHandle(info
.hThread
);
2986 return info
.hProcess
;
2989 static void create_overlapped_pipe(DWORD mode
, HANDLE
*client
, HANDLE
*server
)
2991 SECURITY_ATTRIBUTES sec_attr
= { sizeof(sec_attr
), NULL
, TRUE
};
2992 DWORD read_mode
= mode
& (PIPE_READMODE_BYTE
| PIPE_READMODE_MESSAGE
);
2993 OVERLAPPED overlapped
;
2996 *server
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
,
2997 PIPE_WAIT
| mode
, 1, 5000, 6000, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
2998 ok(&server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed: %u\n", GetLastError());
2999 test_signaled(*server
);
3001 memset(&overlapped
, 0, sizeof(overlapped
));
3002 overlapped
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
3003 res
= ConnectNamedPipe(*server
, &overlapped
);
3004 ok(!res
&& GetLastError() == ERROR_IO_PENDING
, "WriteFile returned %x(%u)\n", res
, GetLastError());
3005 test_not_signaled(*server
);
3006 test_not_signaled(overlapped
.hEvent
);
3008 *client
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, &sec_attr
, OPEN_EXISTING
, FILE_FLAG_OVERLAPPED
, NULL
);
3009 ok(*server
!= INVALID_HANDLE_VALUE
, "CreateFile failed: %u\n", GetLastError());
3011 res
= SetNamedPipeHandleState(*client
, &read_mode
, NULL
, NULL
);
3012 ok(res
, "SetNamedPipeHandleState failed: %u\n", GetLastError());
3014 test_signaled(*client
);
3015 test_not_signaled(*server
);
3016 test_overlapped_result(*server
, &overlapped
, 0, FALSE
);
3019 static void test_overlapped_transport(BOOL msg_mode
, BOOL msg_read_mode
)
3021 OVERLAPPED overlapped
, overlapped2
;
3022 HANDLE server
, client
, flush
;
3028 DWORD create_flags
=
3029 (msg_mode
? PIPE_TYPE_MESSAGE
: PIPE_TYPE_BYTE
) |
3030 (msg_read_mode
? PIPE_READMODE_MESSAGE
: PIPE_READMODE_BYTE
);
3032 create_overlapped_pipe(create_flags
, &client
, &server
);
3034 trace("testing %s, %s server->client writes...\n",
3035 msg_mode
? "message mode" : "byte mode", msg_read_mode
? "message read" : "byte read");
3036 test_blocking_rw(server
, client
, 5000, msg_mode
, msg_read_mode
);
3037 trace("testing %s, %s client->server writes...\n",
3038 msg_mode
? "message mode" : "byte mode", msg_read_mode
? "message read" : "byte read");
3039 test_blocking_rw(client
, server
, 6000, msg_mode
, msg_read_mode
);
3041 CloseHandle(client
);
3042 CloseHandle(server
);
3044 /* close client with pending writes */
3045 create_overlapped_pipe(create_flags
, &client
, &server
);
3046 overlapped_write_async(server
, buf
, 7000, &overlapped
);
3047 flush
= test_flush_async(server
, ERROR_BROKEN_PIPE
);
3048 CloseHandle(client
);
3049 test_overlapped_failure(server
, &overlapped
, ERROR_BROKEN_PIPE
);
3050 test_flush_done(flush
);
3051 CloseHandle(server
);
3053 /* close server with pending writes */
3054 create_overlapped_pipe(create_flags
, &client
, &server
);
3055 overlapped_write_async(client
, buf
, 7000, &overlapped
);
3056 flush
= test_flush_async(client
, ERROR_BROKEN_PIPE
);
3057 CloseHandle(server
);
3058 test_overlapped_failure(client
, &overlapped
, ERROR_BROKEN_PIPE
);
3059 test_flush_done(flush
);
3060 CloseHandle(client
);
3062 /* disconnect with pending writes */
3063 create_overlapped_pipe(create_flags
, &client
, &server
);
3064 overlapped_write_async(client
, buf
, 7000, &overlapped
);
3065 overlapped_write_async(server
, buf
, 7000, &overlapped2
);
3066 flush
= test_flush_async(client
, ERROR_PIPE_NOT_CONNECTED
);
3067 res
= DisconnectNamedPipe(server
);
3068 ok(res
, "DisconnectNamedPipe failed: %u\n", GetLastError());
3069 test_overlapped_failure(client
, &overlapped
, ERROR_PIPE_NOT_CONNECTED
);
3070 test_overlapped_failure(client
, &overlapped2
, ERROR_PIPE_NOT_CONNECTED
);
3071 test_flush_done(flush
);
3072 CloseHandle(server
);
3073 CloseHandle(client
);
3075 /* terminate process with pending write */
3076 create_overlapped_pipe(create_flags
, &client
, &server
);
3077 process
= create_writepipe_process(client
);
3078 /* successfully read part of write that is pending in child process */
3079 res
= ReadFile(server
, buf
, 10, &read_bytes
, NULL
);
3081 ok(res
, "ReadFile failed: %u\n", GetLastError());
3083 ok(!res
&& GetLastError() == ERROR_MORE_DATA
, "ReadFile returned: %x %u\n", res
, GetLastError());
3084 ok(read_bytes
== 10, "read_bytes = %u\n", read_bytes
);
3085 TerminateProcess(process
, 0);
3086 winetest_wait_child_process(process
);
3087 /* after terminating process, there is no pending write and pipe buffer is empty */
3088 overlapped_read_async(server
, buf
, 10, &overlapped
);
3089 overlapped_write_sync(client
, buf
, 1);
3090 test_overlapped_result(server
, &overlapped
, 1, FALSE
);
3091 CloseHandle(process
);
3092 CloseHandle(server
);
3093 CloseHandle(client
);
3102 hmod
= GetModuleHandleA("advapi32.dll");
3103 pDuplicateTokenEx
= (void *) GetProcAddress(hmod
, "DuplicateTokenEx");
3104 hmod
= GetModuleHandleA("kernel32.dll");
3105 pQueueUserAPC
= (void *) GetProcAddress(hmod
, "QueueUserAPC");
3106 pCancelIoEx
= (void *) GetProcAddress(hmod
, "CancelIoEx");
3108 argc
= winetest_get_mainargs(&argv
);
3110 if (argc
> 3 && !strcmp(argv
[2], "writepipe"))
3113 sscanf(argv
[3], "%lx", &handle
);
3114 child_process_write_pipe((HANDLE
)handle
);
3118 if (test_DisconnectNamedPipe())
3120 test_CreateNamedPipe_instances_must_match();
3122 test_CreateNamedPipe(PIPE_TYPE_BYTE
);
3123 test_CreateNamedPipe(PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
);
3126 test_impersonation();
3128 test_overlapped_error();
3129 test_NamedPipeHandleState();
3130 test_GetNamedPipeInfo();
3131 test_readfileex_pending();
3132 test_overlapped_transport(TRUE
, FALSE
);
3133 test_overlapped_transport(TRUE
, TRUE
);
3134 test_overlapped_transport(FALSE
, FALSE
);