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
28 #include "wine/winternl.h"
29 #include "wine/test.h"
31 #define PIPENAME "\\\\.\\PiPe\\tests_pipe.c"
32 #define PIPENAME_SPECIAL "\\\\.\\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
);
41 static BOOL user_apc_ran
;
42 static void CALLBACK
user_apc(ULONG_PTR param
)
57 ULONG_PTR returnValue
;
63 static DWORD CALLBACK
rpcThreadMain(LPVOID arg
)
65 struct rpcThreadArgs
*rpcargs
= (struct rpcThreadArgs
*)arg
;
66 trace("rpcThreadMain starting\n");
67 SetLastError( rpcargs
->lastError
);
72 rpcargs
->returnValue
= (ULONG_PTR
)ReadFile( (HANDLE
)rpcargs
->args
[0], /* hFile */
73 (LPVOID
)rpcargs
->args
[1], /* buffer */
74 (DWORD
)rpcargs
->args
[2], /* bytesToRead */
75 (LPDWORD
)rpcargs
->args
[3], /* bytesRead */
76 (LPOVERLAPPED
)rpcargs
->args
[4] ); /* overlapped */
80 rpcargs
->returnValue
= (ULONG_PTR
)WriteFile( (HANDLE
)rpcargs
->args
[0], /* hFile */
81 (LPCVOID
)rpcargs
->args
[1], /* buffer */
82 (DWORD
)rpcargs
->args
[2], /* bytesToWrite */
83 (LPDWORD
)rpcargs
->args
[3], /* bytesWritten */
84 (LPOVERLAPPED
)rpcargs
->args
[4] ); /* overlapped */
87 case RPC_PEEKNAMEDPIPE
:
88 rpcargs
->returnValue
= (ULONG_PTR
)PeekNamedPipe( (HANDLE
)rpcargs
->args
[0], /* hPipe */
89 (LPVOID
)rpcargs
->args
[1], /* lpvBuffer */
90 (DWORD
)rpcargs
->args
[2], /* cbBuffer */
91 (LPDWORD
)rpcargs
->args
[3], /* lpcbRead */
92 (LPDWORD
)rpcargs
->args
[4], /* lpcbAvail */
93 (LPDWORD
)rpcargs
->args
[5] ); /* lpcbMessage */
97 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
98 rpcargs
->returnValue
= 0;
102 rpcargs
->lastError
= GetLastError();
103 trace("rpcThreadMain returning\n");
107 /* Runs ReadFile(...) from a different thread */
108 static BOOL
RpcReadFile(HANDLE hFile
, LPVOID buffer
, DWORD bytesToRead
, LPDWORD bytesRead
, LPOVERLAPPED overlapped
)
110 struct rpcThreadArgs rpcargs
;
114 rpcargs
.returnValue
= 0;
115 rpcargs
.lastError
= GetLastError();
116 rpcargs
.op
= RPC_READFILE
;
117 rpcargs
.args
[0] = (ULONG_PTR
)hFile
;
118 rpcargs
.args
[1] = (ULONG_PTR
)buffer
;
119 rpcargs
.args
[2] = (ULONG_PTR
)bytesToRead
;
120 rpcargs
.args
[3] = (ULONG_PTR
)bytesRead
;
121 rpcargs
.args
[4] = (ULONG_PTR
)overlapped
;
123 thread
= CreateThread(NULL
, 0, rpcThreadMain
, (void *)&rpcargs
, 0, &threadId
);
124 ok(thread
!= NULL
, "CreateThread failed. %d\n", GetLastError());
125 ret
= WaitForSingleObject(thread
, INFINITE
);
126 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject failed with %d.\n", GetLastError());
129 SetLastError(rpcargs
.lastError
);
130 return (BOOL
)rpcargs
.returnValue
;
133 /* Runs PeekNamedPipe(...) from a different thread */
134 static BOOL
RpcPeekNamedPipe(HANDLE hPipe
, LPVOID lpvBuffer
, DWORD cbBuffer
,
135 LPDWORD lpcbRead
, LPDWORD lpcbAvail
, LPDWORD lpcbMessage
)
137 struct rpcThreadArgs rpcargs
;
141 rpcargs
.returnValue
= 0;
142 rpcargs
.lastError
= GetLastError();
143 rpcargs
.op
= RPC_PEEKNAMEDPIPE
;
144 rpcargs
.args
[0] = (ULONG_PTR
)hPipe
;
145 rpcargs
.args
[1] = (ULONG_PTR
)lpvBuffer
;
146 rpcargs
.args
[2] = (ULONG_PTR
)cbBuffer
;
147 rpcargs
.args
[3] = (ULONG_PTR
)lpcbRead
;
148 rpcargs
.args
[4] = (ULONG_PTR
)lpcbAvail
;
149 rpcargs
.args
[5] = (ULONG_PTR
)lpcbMessage
;
151 thread
= CreateThread(NULL
, 0, rpcThreadMain
, (void *)&rpcargs
, 0, &threadId
);
152 ok(thread
!= NULL
, "CreateThread failed. %d\n", GetLastError());
153 ok(WaitForSingleObject(thread
, INFINITE
) == WAIT_OBJECT_0
,"WaitForSingleObject failed with %d.\n", GetLastError());
156 SetLastError(rpcargs
.lastError
);
157 return (BOOL
)rpcargs
.returnValue
;
160 static void test_CreateNamedPipe(int pipemode
)
164 static const char obuf
[] = "Bit Bucket";
165 static const char obuf2
[] = "More bits";
166 char ibuf
[32], *pbuf
;
174 if (pipemode
== PIPE_TYPE_BYTE
)
175 trace("test_CreateNamedPipe starting in byte mode\n");
177 trace("test_CreateNamedPipe starting in message mode\n");
179 /* Wait for nonexistent pipe */
180 ret
= WaitNamedPipeA(PIPENAME
, 2000);
181 ok(ret
== 0, "WaitNamedPipe returned %d for nonexistent pipe\n", ret
);
182 ok(GetLastError() == ERROR_FILE_NOT_FOUND
, "wrong error %u\n", GetLastError());
184 /* Bad parameter checks */
185 hnp
= CreateNamedPipeA("not a named pipe", PIPE_ACCESS_DUPLEX
, pipemode
| PIPE_WAIT
,
186 /* nMaxInstances */ 1,
187 /* nOutBufSize */ 1024,
188 /* nInBufSize */ 1024,
189 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
190 /* lpSecurityAttrib */ NULL
);
191 ok(hnp
== INVALID_HANDLE_VALUE
&& GetLastError() == ERROR_INVALID_NAME
,
192 "CreateNamedPipe should fail if name doesn't start with \\\\.\\pipe\n");
194 if (pipemode
== PIPE_TYPE_BYTE
)
196 /* Bad parameter checks */
197 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_READMODE_MESSAGE
,
198 /* nMaxInstances */ 1,
199 /* nOutBufSize */ 1024,
200 /* nInBufSize */ 1024,
201 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
202 /* lpSecurityAttrib */ NULL
);
203 ok(hnp
== INVALID_HANDLE_VALUE
&& GetLastError() == ERROR_INVALID_PARAMETER
,
204 "CreateNamedPipe should fail with PIPE_TYPE_BYTE | PIPE_READMODE_MESSAGE\n");
207 hnp
= CreateNamedPipeA(NULL
,
208 PIPE_ACCESS_DUPLEX
, pipemode
| PIPE_WAIT
,
209 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
210 ok(hnp
== INVALID_HANDLE_VALUE
&& GetLastError() == ERROR_PATH_NOT_FOUND
,
211 "CreateNamedPipe should fail if name is NULL\n");
213 hFile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
214 ok(hFile
== INVALID_HANDLE_VALUE
215 && GetLastError() == ERROR_FILE_NOT_FOUND
,
216 "connecting to nonexistent named pipe should fail with ERROR_FILE_NOT_FOUND\n");
218 /* Functional checks */
220 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, pipemode
| PIPE_WAIT
,
221 /* nMaxInstances */ 1,
222 /* nOutBufSize */ 1024,
223 /* nInBufSize */ 1024,
224 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
225 /* lpSecurityAttrib */ NULL
);
226 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
228 ret
= WaitNamedPipeA(PIPENAME
, 2000);
229 ok(ret
, "WaitNamedPipe failed (%d)\n", GetLastError());
231 hFile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
232 ok(hFile
!= INVALID_HANDLE_VALUE
, "CreateFile failed (%d)\n", GetLastError());
234 ok(!WaitNamedPipeA(PIPENAME
, 1000), "WaitNamedPipe succeeded\n");
236 ok(GetLastError() == ERROR_SEM_TIMEOUT
, "wrong error %u\n", GetLastError());
238 /* don't try to do i/o if one side couldn't be opened, as it hangs */
239 if (hFile
!= INVALID_HANDLE_VALUE
) {
242 /* Make sure we can read and write a few bytes in both directions */
243 memset(ibuf
, 0, sizeof(ibuf
));
244 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile\n");
245 ok(written
== sizeof(obuf
), "write file len\n");
246 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
247 ok(readden
== sizeof(obuf
), "read got %d bytes\n", readden
);
248 ok(memcmp(obuf
, ibuf
, written
) == 0, "content check\n");
250 memset(ibuf
, 0, sizeof(ibuf
));
251 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile\n");
252 ok(written
== sizeof(obuf2
), "write file len\n");
253 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
254 ok(readden
== sizeof(obuf2
), "read got %d bytes\n", readden
);
255 ok(memcmp(obuf2
, ibuf
, written
) == 0, "content check\n");
257 /* Now the same again, but with an additional call to PeekNamedPipe */
258 memset(ibuf
, 0, sizeof(ibuf
));
259 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile\n");
260 ok(written
== sizeof(obuf
), "write file len 1\n");
261 ok(PeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, NULL
), "Peek\n");
262 ok(readden
== sizeof(obuf
), "peek 1 got %d bytes\n", readden
);
263 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
264 ok(readden
== sizeof(obuf
), "read 1 got %d bytes\n", readden
);
265 ok(memcmp(obuf
, ibuf
, written
) == 0, "content 1 check\n");
267 memset(ibuf
, 0, sizeof(ibuf
));
268 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile\n");
269 ok(written
== sizeof(obuf2
), "write file len 2\n");
270 ok(PeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, NULL
), "Peek\n");
271 ok(readden
== sizeof(obuf2
), "peek 2 got %d bytes\n", readden
);
272 ok(PeekNamedPipe(hnp
, (LPVOID
)1, 0, NULL
, &readden
, NULL
), "Peek\n");
273 ok(readden
== sizeof(obuf2
), "peek 2 got %d bytes\n", readden
);
274 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
275 ok(readden
== sizeof(obuf2
), "read 2 got %d bytes\n", readden
);
276 ok(memcmp(obuf2
, ibuf
, written
) == 0, "content 2 check\n");
278 /* Test how ReadFile behaves when the buffer is not big enough for the whole message */
279 memset(ibuf
, 0, sizeof(ibuf
));
280 ok(WriteFile(hnp
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile\n");
281 ok(written
== sizeof(obuf2
), "write file len\n");
282 ok(ReadFile(hFile
, ibuf
, 4, &readden
, NULL
), "ReadFile\n");
283 ok(readden
== 4, "read got %d bytes\n", readden
);
284 readden
= leftmsg
= -1;
285 ok(PeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, &leftmsg
), "PeekNamedPipe\n");
286 ok(readden
== sizeof(obuf2
) - 4, "peek got %d bytes total\n", readden
);
287 if (pipemode
== PIPE_TYPE_BYTE
)
288 ok(leftmsg
== 0, "peek got %d bytes left in message\n", leftmsg
);
290 ok(leftmsg
== sizeof(obuf2
) - 4, "peek got %d bytes left in message\n", leftmsg
);
291 ok(ReadFile(hFile
, ibuf
+ 4, sizeof(ibuf
) - 4, &readden
, NULL
), "ReadFile\n");
292 ok(readden
== sizeof(obuf2
) - 4, "read got %d bytes\n", readden
);
293 ok(memcmp(obuf2
, ibuf
, written
) == 0, "content check\n");
294 readden
= leftmsg
= -1;
295 ok(PeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, &leftmsg
), "PeekNamedPipe\n");
296 ok(readden
== 0, "peek got %d bytes total\n", readden
);
297 ok(leftmsg
== 0, "peek got %d bytes left in message\n", leftmsg
);
299 memset(ibuf
, 0, sizeof(ibuf
));
300 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile\n");
301 ok(written
== sizeof(obuf
), "write file len\n");
302 if (pipemode
== PIPE_TYPE_BYTE
)
304 ok(ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile\n");
308 SetLastError(0xdeadbeef);
309 ok(!ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile\n");
310 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error\n");
312 ok(readden
== 4, "read got %d bytes\n", readden
);
313 ok(ReadFile(hnp
, ibuf
+ 4, sizeof(ibuf
) - 4, &readden
, NULL
), "ReadFile\n");
314 ok(readden
== sizeof(obuf
) - 4, "read got %d bytes\n", readden
);
315 ok(memcmp(obuf
, ibuf
, written
) == 0, "content check\n");
317 /* Similar to above, but use a read buffer size small enough to read in three parts */
318 memset(ibuf
, 0, sizeof(ibuf
));
319 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile\n");
320 ok(written
== sizeof(obuf2
), "write file len\n");
321 if (pipemode
== PIPE_TYPE_BYTE
)
323 ok(ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile\n");
324 ok(readden
== 4, "read got %d bytes\n", readden
);
325 ok(ReadFile(hnp
, ibuf
+ 4, 4, &readden
, NULL
), "ReadFile\n");
329 SetLastError(0xdeadbeef);
330 ok(!ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile\n");
331 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error\n");
332 ok(readden
== 4, "read got %d bytes\n", readden
);
333 SetLastError(0xdeadbeef);
334 ok(!ReadFile(hnp
, ibuf
+ 4, 4, &readden
, NULL
), "ReadFile\n");
335 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error\n");
337 ok(readden
== 4, "read got %d bytes\n", readden
);
338 ok(ReadFile(hnp
, ibuf
+ 8, sizeof(ibuf
) - 8, &readden
, NULL
), "ReadFile\n");
339 ok(readden
== sizeof(obuf2
) - 8, "read got %d bytes\n", readden
);
340 ok(memcmp(obuf2
, ibuf
, written
) == 0, "content check\n");
342 /* Tests for sending empty messages */
343 memset(ibuf
, 0, sizeof(ibuf
));
344 ok(WriteFile(hnp
, obuf
, 0, &written
, NULL
), "WriteFile\n");
345 ok(written
== 0, "write file len\n");
346 if (pipemode
!= PIPE_TYPE_BYTE
)
348 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
349 ok(readden
== 0, "read got %d bytes\n", readden
);
352 memset(ibuf
, 0, sizeof(ibuf
));
353 ok(WriteFile(hFile
, obuf
, 0, &written
, NULL
), "WriteFile\n");
354 ok(written
== 0, "write file len\n");
355 if (pipemode
!= PIPE_TYPE_BYTE
)
357 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
358 ok(readden
== 0, "read got %d bytes\n", readden
);
361 /* similar to above, but with an additional call to PeekNamedPipe inbetween */
362 memset(ibuf
, 0, sizeof(ibuf
));
363 ok(WriteFile(hnp
, obuf
, 0, &written
, NULL
), "WriteFile\n");
364 ok(written
== 0, "write file len\n");
365 ok(PeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, NULL
), "Peek\n");
366 ok(readden
== 0, "peek got %d bytes\n", readden
);
367 if (pipemode
!= PIPE_TYPE_BYTE
)
369 struct rpcThreadArgs rpcargs
;
373 rpcargs
.returnValue
= 0;
374 rpcargs
.lastError
= GetLastError();
375 rpcargs
.op
= RPC_READFILE
;
376 rpcargs
.args
[0] = (ULONG_PTR
)hFile
;
377 rpcargs
.args
[1] = (ULONG_PTR
)ibuf
;
378 rpcargs
.args
[2] = (ULONG_PTR
)sizeof(ibuf
);
379 rpcargs
.args
[3] = (ULONG_PTR
)&readden
;
380 rpcargs
.args
[4] = (ULONG_PTR
)NULL
;
382 thread
= CreateThread(NULL
, 0, rpcThreadMain
, (void *)&rpcargs
, 0, &threadId
);
383 ok(thread
!= NULL
, "CreateThread failed. %d\n", GetLastError());
384 ret
= WaitForSingleObject(thread
, 200);
386 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject returned %d instead of %d.\n", ret
, WAIT_OBJECT_0
);
387 if (ret
== WAIT_TIMEOUT
)
389 ok(WriteFile(hnp
, obuf
, 0, &written
, NULL
), "WriteFile\n");
390 ok(written
== 0, "write file len\n");
391 ret
= WaitForSingleObject(thread
, 200);
392 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject returned %d instead of %d.\n", ret
, WAIT_OBJECT_0
);
395 ok((BOOL
)rpcargs
.returnValue
, "ReadFile\n");
396 ok(readden
== 0, "read got %d bytes\n", readden
);
399 memset(ibuf
, 0, sizeof(ibuf
));
400 ok(WriteFile(hFile
, obuf
, 0, &written
, NULL
), "WriteFile\n");
401 ok(written
== 0, "write file len\n");
402 ok(PeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, NULL
), "Peek\n");
403 ok(readden
== 0, "peek got %d bytes\n", readden
);
404 if (pipemode
!= PIPE_TYPE_BYTE
)
406 struct rpcThreadArgs rpcargs
;
410 rpcargs
.returnValue
= 0;
411 rpcargs
.lastError
= GetLastError();
412 rpcargs
.op
= RPC_READFILE
;
413 rpcargs
.args
[0] = (ULONG_PTR
)hnp
;
414 rpcargs
.args
[1] = (ULONG_PTR
)ibuf
;
415 rpcargs
.args
[2] = (ULONG_PTR
)sizeof(ibuf
);
416 rpcargs
.args
[3] = (ULONG_PTR
)&readden
;
417 rpcargs
.args
[4] = (ULONG_PTR
)NULL
;
419 thread
= CreateThread(NULL
, 0, rpcThreadMain
, (void *)&rpcargs
, 0, &threadId
);
420 ok(thread
!= NULL
, "CreateThread failed. %d\n", GetLastError());
421 ret
= WaitForSingleObject(thread
, 200);
423 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject returned %d instead of %d.\n", ret
, WAIT_OBJECT_0
);
424 if (ret
== WAIT_TIMEOUT
)
426 ok(WriteFile(hFile
, obuf
, 0, &written
, NULL
), "WriteFile\n");
427 ok(written
== 0, "write file len\n");
428 ret
= WaitForSingleObject(thread
, 200);
429 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject returned %d instead of %d.\n", ret
, WAIT_OBJECT_0
);
432 ok((BOOL
)rpcargs
.returnValue
, "ReadFile\n");
433 ok(readden
== 0, "read got %d bytes\n", readden
);
436 /* similar to above, but now with PeekNamedPipe and multiple messages */
437 memset(ibuf
, 0, sizeof(ibuf
));
438 ok(WriteFile(hnp
, obuf
, 0, &written
, NULL
), "WriteFile\n");
439 ok(written
== 0, "write file len\n");
440 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile\n");
441 ok(written
== sizeof(obuf
), "write file len\n");
442 ok(PeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, &leftmsg
), "Peek\n");
443 ok(readden
== sizeof(obuf
), "peek got %d bytes\n", readden
);
444 ok(leftmsg
== 0, "peek got %d bytes left in msg\n", leftmsg
);
445 ok(PeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, &leftmsg
), "Peek\n");
446 ok(readden
== sizeof(obuf
), "peek got %d bytes\n", readden
);
447 if (pipemode
!= PIPE_TYPE_BYTE
)
449 ok(leftmsg
== 0, "peek got %d bytes left in msg\n", leftmsg
);
451 ok(leftmsg
== 0, "peek got %d bytes left in msg\n", leftmsg
);
452 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
453 ok(readden
== sizeof(obuf
), "read got %d bytes\n", readden
);
454 ok(memcmp(obuf
, ibuf
, sizeof(obuf
)) == 0, "content check\n");
456 memset(ibuf
, 0, sizeof(ibuf
));
457 ok(WriteFile(hFile
, obuf2
, 0, &written
, NULL
), "WriteFile\n");
458 ok(written
== 0, "write file len\n");
459 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile\n");
460 ok(written
== sizeof(obuf2
), "write file len\n");
461 ok(PeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, &leftmsg
), "Peek\n");
462 ok(readden
== sizeof(obuf2
), "peek got %d bytes\n", readden
);
463 ok(leftmsg
== 0, "peek got %d bytes left in msg\n", leftmsg
);
464 ok(PeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, &leftmsg
), "Peek\n");
465 ok(readden
== sizeof(obuf2
), "peek got %d bytes\n", readden
);
466 if (pipemode
!= PIPE_TYPE_BYTE
)
468 ok(leftmsg
== 0, "peek got %d bytes left in msg\n", leftmsg
);
470 ok(leftmsg
== 0, "peek got %d bytes left in msg\n", leftmsg
);
471 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
472 if (pipemode
!= PIPE_TYPE_BYTE
)
475 ok(readden
== 0, "read got %d bytes\n", readden
);
477 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
479 ok(readden
== sizeof(obuf2
), "read got %d bytes\n", readden
);
480 ok(memcmp(obuf2
, ibuf
, sizeof(obuf2
)) == 0, "content check\n");
482 /* Test reading of multiple writes */
483 memset(ibuf
, 0, sizeof(ibuf
));
484 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile3a\n");
485 ok(written
== sizeof(obuf
), "write file len 3a\n");
486 ok(WriteFile(hnp
, obuf2
, sizeof(obuf2
), &written
, NULL
), " WriteFile3b\n");
487 ok(written
== sizeof(obuf2
), "write file len 3b\n");
488 ok(PeekNamedPipe(hFile
, ibuf
, sizeof(ibuf
), &readden
, &avail
, NULL
), "Peek3\n");
489 if (pipemode
== PIPE_TYPE_BYTE
) {
490 ok(readden
== sizeof(obuf
) + sizeof(obuf2
), "peek3 got %d bytes\n", readden
);
494 ok(readden
== sizeof(obuf
), "peek3 got %d bytes\n", readden
);
496 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek3 got %d bytes available\n", avail
);
498 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "pipe content 3a check\n");
499 if (pipemode
== PIPE_TYPE_BYTE
&& readden
>= sizeof(obuf
)+sizeof(obuf2
)) {
500 pbuf
+= sizeof(obuf
);
501 ok(memcmp(obuf2
, pbuf
, sizeof(obuf2
)) == 0, "pipe content 3b check\n");
503 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
504 ok(readden
== sizeof(obuf
) + sizeof(obuf2
), "read 3 got %d bytes\n", readden
);
506 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 3a check\n");
507 pbuf
+= sizeof(obuf
);
508 ok(memcmp(obuf2
, pbuf
, sizeof(obuf2
)) == 0, "content 3b check\n");
510 /* Multiple writes in the reverse direction */
511 memset(ibuf
, 0, sizeof(ibuf
));
512 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile4a\n");
513 ok(written
== sizeof(obuf
), "write file len 4a\n");
514 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), " WriteFile4b\n");
515 ok(written
== sizeof(obuf2
), "write file len 4b\n");
516 ok(PeekNamedPipe(hnp
, ibuf
, sizeof(ibuf
), &readden
, &avail
, NULL
), "Peek4\n");
517 if (pipemode
== PIPE_TYPE_BYTE
) {
518 ok(readden
== sizeof(obuf
) + sizeof(obuf2
), "peek4 got %d bytes\n", readden
);
522 ok(readden
== sizeof(obuf
), "peek4 got %d bytes\n", readden
);
524 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek4 got %d bytes available\n", avail
);
526 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "pipe content 4a check\n");
527 if (pipemode
== PIPE_TYPE_BYTE
&& readden
>= sizeof(obuf
)+sizeof(obuf2
)) {
528 pbuf
+= sizeof(obuf
);
529 ok(memcmp(obuf2
, pbuf
, sizeof(obuf2
)) == 0, "pipe content 4b check\n");
531 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
532 if (pipemode
== PIPE_TYPE_BYTE
) {
533 ok(readden
== sizeof(obuf
) + sizeof(obuf2
), "read 4 got %d bytes\n", readden
);
536 ok(readden
== sizeof(obuf
), "read 4 got %d bytes\n", readden
);
539 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 4a check\n");
540 if (pipemode
== PIPE_TYPE_BYTE
) {
541 pbuf
+= sizeof(obuf
);
542 ok(memcmp(obuf2
, pbuf
, sizeof(obuf2
)) == 0, "content 4b check\n");
545 /* Test reading of multiple writes after a mode change
546 (CreateFile always creates a byte mode pipe) */
547 lpmode
= PIPE_READMODE_MESSAGE
;
548 if (pipemode
== PIPE_TYPE_BYTE
) {
549 /* trying to change the client end of a byte pipe to message mode should fail */
550 ok(!SetNamedPipeHandleState(hFile
, &lpmode
, NULL
, NULL
), "Change mode\n");
553 ok(SetNamedPipeHandleState(hFile
, &lpmode
, NULL
, NULL
), "Change mode\n");
555 memset(ibuf
, 0, sizeof(ibuf
));
556 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile5a\n");
557 ok(written
== sizeof(obuf
), "write file len 3a\n");
558 ok(WriteFile(hnp
, obuf2
, sizeof(obuf2
), &written
, NULL
), " WriteFile5b\n");
559 ok(written
== sizeof(obuf2
), "write file len 3b\n");
560 ok(PeekNamedPipe(hFile
, ibuf
, sizeof(ibuf
), &readden
, &avail
, NULL
), "Peek5\n");
561 ok(readden
== sizeof(obuf
), "peek5 got %d bytes\n", readden
);
562 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek5 got %d bytes available\n", avail
);
564 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 5a check\n");
565 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
566 ok(readden
== sizeof(obuf
), "read 5 got %d bytes\n", readden
);
568 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 5a check\n");
569 if (readden
<= sizeof(obuf
))
570 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
572 /* Multiple writes in the reverse direction */
573 /* the write of obuf2 from write4 should still be in the buffer */
574 ok(PeekNamedPipe(hnp
, ibuf
, sizeof(ibuf
), &readden
, &avail
, NULL
), "Peek6a\n");
575 ok(readden
== sizeof(obuf2
), "peek6a got %d bytes\n", readden
);
576 ok(avail
== sizeof(obuf2
), "peek6a got %d bytes available\n", avail
);
578 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
579 ok(readden
== sizeof(obuf2
), "read 6a got %d bytes\n", readden
);
581 ok(memcmp(obuf2
, pbuf
, sizeof(obuf2
)) == 0, "content 6a check\n");
583 memset(ibuf
, 0, sizeof(ibuf
));
584 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile6a\n");
585 ok(written
== sizeof(obuf
), "write file len 6a\n");
586 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), " WriteFile6b\n");
587 ok(written
== sizeof(obuf2
), "write file len 6b\n");
588 ok(PeekNamedPipe(hnp
, ibuf
, sizeof(ibuf
), &readden
, &avail
, NULL
), "Peek6\n");
589 ok(readden
== sizeof(obuf
), "peek6 got %d bytes\n", readden
);
590 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek6b got %d bytes available\n", avail
);
592 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 6a check\n");
593 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
594 ok(readden
== sizeof(obuf
), "read 6b got %d bytes\n", readden
);
596 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 6a check\n");
597 if (readden
<= sizeof(obuf
))
598 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
600 /* Tests for sending empty messages */
601 memset(ibuf
, 0, sizeof(ibuf
));
602 ok(WriteFile(hnp
, obuf
, 0, &written
, NULL
), "WriteFile\n");
603 ok(written
== 0, "write file len\n");
604 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
605 ok(readden
== 0, "read got %d bytes\n", readden
);
607 memset(ibuf
, 0, sizeof(ibuf
));
608 ok(WriteFile(hFile
, obuf
, 0, &written
, NULL
), "WriteFile\n");
609 ok(written
== 0, "write file len\n");
610 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
611 ok(readden
== 0, "read got %d bytes\n", readden
);
613 /* similar to above, but with an additional call to PeekNamedPipe inbetween */
614 memset(ibuf
, 0, sizeof(ibuf
));
615 ok(WriteFile(hnp
, obuf
, 0, &written
, NULL
), "WriteFile\n");
616 ok(written
== 0, "write file len\n");
617 ok(PeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, NULL
), "Peek\n");
618 ok(readden
== 0, "peek got %d bytes\n", readden
);
620 struct rpcThreadArgs rpcargs
;
624 rpcargs
.returnValue
= 0;
625 rpcargs
.lastError
= GetLastError();
626 rpcargs
.op
= RPC_READFILE
;
627 rpcargs
.args
[0] = (ULONG_PTR
)hFile
;
628 rpcargs
.args
[1] = (ULONG_PTR
)ibuf
;
629 rpcargs
.args
[2] = (ULONG_PTR
)sizeof(ibuf
);
630 rpcargs
.args
[3] = (ULONG_PTR
)&readden
;
631 rpcargs
.args
[4] = (ULONG_PTR
)NULL
;
633 thread
= CreateThread(NULL
, 0, rpcThreadMain
, (void *)&rpcargs
, 0, &threadId
);
634 ok(thread
!= NULL
, "CreateThread failed. %d\n", GetLastError());
635 ret
= WaitForSingleObject(thread
, 200);
637 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject returned %d instead of %d.\n", ret
, WAIT_OBJECT_0
);
638 if (ret
== WAIT_TIMEOUT
)
640 ok(WriteFile(hnp
, obuf
, 0, &written
, NULL
), "WriteFile\n");
641 ok(written
== 0, "write file len\n");
642 ret
= WaitForSingleObject(thread
, 200);
643 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject returned %d instead of %d.\n", ret
, WAIT_OBJECT_0
);
646 ok((BOOL
)rpcargs
.returnValue
, "ReadFile\n");
647 ok(readden
== 0, "read got %d bytes\n", readden
);
650 memset(ibuf
, 0, sizeof(ibuf
));
651 ok(WriteFile(hFile
, obuf
, 0, &written
, NULL
), "WriteFile\n");
652 ok(written
== 0, "write file len\n");
653 ok(PeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, NULL
), "Peek\n");
654 ok(readden
== 0, "peek got %d bytes\n", readden
);
656 struct rpcThreadArgs rpcargs
;
660 rpcargs
.returnValue
= 0;
661 rpcargs
.lastError
= GetLastError();
662 rpcargs
.op
= RPC_READFILE
;
663 rpcargs
.args
[0] = (ULONG_PTR
)hnp
;
664 rpcargs
.args
[1] = (ULONG_PTR
)ibuf
;
665 rpcargs
.args
[2] = (ULONG_PTR
)sizeof(ibuf
);
666 rpcargs
.args
[3] = (ULONG_PTR
)&readden
;
667 rpcargs
.args
[4] = (ULONG_PTR
)NULL
;
669 thread
= CreateThread(NULL
, 0, rpcThreadMain
, (void *)&rpcargs
, 0, &threadId
);
670 ok(thread
!= NULL
, "CreateThread failed. %d\n", GetLastError());
671 ret
= WaitForSingleObject(thread
, 200);
673 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject returned %d instead of %d.\n", ret
, WAIT_OBJECT_0
);
674 if (ret
== WAIT_TIMEOUT
)
676 ok(WriteFile(hFile
, obuf
, 0, &written
, NULL
), "WriteFile\n");
677 ok(written
== 0, "write file len\n");
678 ret
= WaitForSingleObject(thread
, 200);
679 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject returned %d instead of %d.\n", ret
, WAIT_OBJECT_0
);
682 ok((BOOL
)rpcargs
.returnValue
, "ReadFile\n");
683 ok(readden
== 0, "read got %d bytes\n", readden
);
686 /* similar to above, but now with PeekNamedPipe and multiple messages */
687 memset(ibuf
, 0, sizeof(ibuf
));
688 ok(WriteFile(hnp
, obuf
, 0, &written
, NULL
), "WriteFile\n");
689 ok(written
== 0, "write file len\n");
690 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile\n");
691 ok(written
== sizeof(obuf
), "write file len\n");
692 ok(PeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, &leftmsg
), "Peek\n");
693 ok(readden
== sizeof(obuf
), "peek got %d bytes\n", readden
);
694 ok(leftmsg
== 0, "peek got %d bytes left in msg\n", leftmsg
);
695 ok(PeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, &leftmsg
), "Peek\n");
696 ok(readden
== sizeof(obuf
), "peek got %d bytes\n", readden
);
698 ok(leftmsg
== 0, "peek got %d bytes left in msg\n", leftmsg
);
699 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
701 ok(readden
== 0, "read got %d bytes\n", readden
);
703 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
704 ok(readden
== sizeof(obuf
), "read got %d bytes\n", readden
);
705 ok(memcmp(obuf
, ibuf
, sizeof(obuf
)) == 0, "content check\n");
707 memset(ibuf
, 0, sizeof(ibuf
));
708 ok(WriteFile(hFile
, obuf2
, 0, &written
, NULL
), "WriteFile\n");
709 ok(written
== 0, "write file len\n");
710 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile\n");
711 ok(written
== sizeof(obuf2
), "write file len\n");
712 ok(PeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, &leftmsg
), "Peek\n");
713 ok(readden
== sizeof(obuf2
), "peek got %d bytes\n", readden
);
714 ok(leftmsg
== 0, "peek got %d bytes left in msg\n", leftmsg
);
715 ok(PeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, &leftmsg
), "Peek\n");
716 ok(readden
== sizeof(obuf2
), "peek got %d bytes\n", readden
);
718 ok(leftmsg
== 0, "peek got %d bytes left in msg\n", leftmsg
);
719 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
721 ok(readden
== 0, "read got %d bytes\n", readden
);
723 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
724 ok(readden
== sizeof(obuf2
), "read got %d bytes\n", readden
);
725 ok(memcmp(obuf2
, ibuf
, sizeof(obuf2
)) == 0, "content check\n");
727 /* Test how ReadFile behaves when the buffer is not big enough for the whole message */
728 memset(ibuf
, 0, sizeof(ibuf
));
729 ok(WriteFile(hnp
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile 7\n");
730 ok(written
== sizeof(obuf2
), "write file len 7\n");
731 SetLastError(0xdeadbeef);
732 ok(!ReadFile(hFile
, ibuf
, 4, &readden
, NULL
), "ReadFile 7\n");
733 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 7\n");
734 ok(readden
== 4, "read got %d bytes 7\n", readden
);
735 ok(ReadFile(hFile
, ibuf
+ 4, sizeof(ibuf
) - 4, &readden
, NULL
), "ReadFile 7\n");
736 ok(readden
== sizeof(obuf2
) - 4, "read got %d bytes 7\n", readden
);
737 ok(memcmp(obuf2
, ibuf
, written
) == 0, "content check 7\n");
739 memset(ibuf
, 0, sizeof(ibuf
));
740 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile 8\n");
741 ok(written
== sizeof(obuf
), "write file len 8\n");
742 SetLastError(0xdeadbeef);
743 ok(!ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile 8\n");
744 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 8\n");
745 ok(readden
== 4, "read got %d bytes 8\n", readden
);
746 ok(ReadFile(hnp
, ibuf
+ 4, sizeof(ibuf
) - 4, &readden
, NULL
), "ReadFile 8\n");
747 ok(readden
== sizeof(obuf
) - 4, "read got %d bytes 8\n", readden
);
748 ok(memcmp(obuf
, ibuf
, written
) == 0, "content check 8\n");
750 /* The following test shows that when doing a partial read of a message, the rest
751 * is still in the pipe, and can be received from a second thread. This shows
752 * especially that the content is _not_ stored in thread-local-storage until it is
753 * completely transmitted. The same method works even across multiple processes. */
754 memset(ibuf
, 0, sizeof(ibuf
));
755 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile 9\n");
756 ok(written
== sizeof(obuf
), "write file len 9\n");
757 ok(WriteFile(hnp
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile 9\n");
758 ok(written
== sizeof(obuf2
), "write file len 9\n");
759 readden
= leftmsg
= -1;
760 ok(PeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, &leftmsg
), "PeekNamedPipe 9\n");
761 ok(readden
== sizeof(obuf
) + sizeof(obuf2
), "peek got %d bytes total 9\n", readden
);
762 ok(leftmsg
== sizeof(obuf
), "peek got %d bytes left in message 9\n", leftmsg
);
763 readden
= leftmsg
= -1;
764 ok(RpcPeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, &leftmsg
), "RpcPeekNamedPipe 9\n");
765 ok(readden
== sizeof(obuf
) + sizeof(obuf2
), "peek got %d bytes total 9\n", readden
);
766 ok(leftmsg
== sizeof(obuf
), "peek got %d bytes left in message 9\n", leftmsg
);
767 SetLastError(0xdeadbeef);
768 ok(!ReadFile(hFile
, ibuf
, 4, &readden
, NULL
), "ReadFile 9\n");
769 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 9\n");
770 ok(readden
== 4, "read got %d bytes 9\n", readden
);
771 SetLastError(0xdeadbeef);
772 ret
= RpcReadFile(hFile
, ibuf
+ 4, 4, &readden
, NULL
);
773 ok(!ret
, "RpcReadFile 9\n");
774 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 9\n");
775 ok(readden
== 4, "read got %d bytes 9\n", readden
);
776 readden
= leftmsg
= -1;
777 ok(PeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, &leftmsg
), "PeekNamedPipe 9\n");
778 ok(readden
== sizeof(obuf
) - 8 + sizeof(obuf2
), "peek got %d bytes total 9\n", readden
);
779 ok(leftmsg
== sizeof(obuf
) - 8, "peek got %d bytes left in message 9\n", leftmsg
);
780 readden
= leftmsg
= -1;
781 ok(RpcPeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, &leftmsg
), "RpcPeekNamedPipe 9\n");
782 ok(readden
== sizeof(obuf
) - 8 + sizeof(obuf2
), "peek got %d bytes total 9\n", readden
);
783 ok(leftmsg
== sizeof(obuf
) - 8, "peek got %d bytes left in message 9\n", leftmsg
);
784 ret
= RpcReadFile(hFile
, ibuf
+ 8, sizeof(ibuf
), &readden
, NULL
);
785 ok(ret
, "RpcReadFile 9\n");
786 ok(readden
== sizeof(obuf
) - 8, "read got %d bytes 9\n", readden
);
787 ok(memcmp(obuf
, ibuf
, sizeof(obuf
)) == 0, "content check 9\n");
788 if (readden
<= sizeof(obuf
) - 8) /* blocks forever if second part was already received */
790 memset(ibuf
, 0, sizeof(ibuf
));
791 readden
= leftmsg
= -1;
792 ok(PeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, &leftmsg
), "PeekNamedPipe 9\n");
793 ok(readden
== sizeof(obuf2
), "peek got %d bytes total 9\n", readden
);
794 ok(leftmsg
== sizeof(obuf2
), "peek got %d bytes left in message 9\n", leftmsg
);
795 readden
= leftmsg
= -1;
796 ok(RpcPeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, &leftmsg
), "RpcPeekNamedPipe 9\n");
797 ok(readden
== sizeof(obuf2
), "peek got %d bytes total 9\n", readden
);
798 ok(leftmsg
== sizeof(obuf2
), "peek got %d bytes left in message 9\n", leftmsg
);
799 SetLastError(0xdeadbeef);
800 ret
= RpcReadFile(hFile
, ibuf
, 4, &readden
, NULL
);
801 ok(!ret
, "RpcReadFile 9\n");
802 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 9\n");
803 ok(readden
== 4, "read got %d bytes 9\n", readden
);
804 SetLastError(0xdeadbeef);
805 ok(!ReadFile(hFile
, ibuf
+ 4, 4, &readden
, NULL
), "ReadFile 9\n");
806 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 9\n");
807 ok(readden
== 4, "read got %d bytes 9\n", readden
);
808 readden
= leftmsg
= -1;
809 ok(PeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, &leftmsg
), "PeekNamedPipe 9\n");
810 ok(readden
== sizeof(obuf2
) - 8, "peek got %d bytes total 9\n", readden
);
811 ok(leftmsg
== sizeof(obuf2
) - 8, "peek got %d bytes left in message 9\n", leftmsg
);
812 readden
= leftmsg
= -1;
813 ok(RpcPeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, &leftmsg
), "RpcPeekNamedPipe 9\n");
814 ok(readden
== sizeof(obuf2
) - 8, "peek got %d bytes total 9\n", readden
);
815 ok(leftmsg
== sizeof(obuf2
) - 8, "peek got %d bytes left in message 9\n", leftmsg
);
816 ret
= RpcReadFile(hFile
, ibuf
+ 8, sizeof(ibuf
), &readden
, NULL
);
817 ok(ret
, "RpcReadFile 9\n");
818 ok(readden
== sizeof(obuf2
) - 8, "read got %d bytes 9\n", readden
);
819 ok(memcmp(obuf2
, ibuf
, sizeof(obuf2
)) == 0, "content check 9\n");
821 readden
= leftmsg
= -1;
822 ok(PeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, &leftmsg
), "PeekNamedPipe 9\n");
823 ok(readden
== 0, "peek got %d bytes total 9\n", readden
);
824 ok(leftmsg
== 0, "peek got %d bytes left in message 9\n", leftmsg
);
825 readden
= leftmsg
= -1;
826 ok(RpcPeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, &leftmsg
), "RpcPeekNamedPipe 9\n");
827 ok(readden
== 0, "peek got %d bytes total 9\n", readden
);
828 ok(leftmsg
== 0, "peek got %d bytes left in message 9\n", leftmsg
);
830 /* Now the reverse direction */
831 memset(ibuf
, 0, sizeof(ibuf
));
832 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile 10\n");
833 ok(written
== sizeof(obuf2
), "write file len 10\n");
834 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile 10\n");
835 ok(written
== sizeof(obuf
), "write file len 10\n");
836 readden
= leftmsg
= -1;
837 ok(PeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, &leftmsg
), "PeekNamedPipe 10\n");
838 ok(readden
== sizeof(obuf
) + sizeof(obuf2
), "peek got %d bytes total 10\n", readden
);
839 ok(leftmsg
== sizeof(obuf2
), "peek got %d bytes left in message 10\n", leftmsg
);
840 readden
= leftmsg
= -1;
841 ok(RpcPeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, &leftmsg
), "RpcPeekNamedPipe 10\n");
842 ok(readden
== sizeof(obuf
) + sizeof(obuf2
), "peek got %d bytes total 10\n", readden
);
843 ok(leftmsg
== sizeof(obuf2
), "peek got %d bytes left in message 10\n", leftmsg
);
844 SetLastError(0xdeadbeef);
845 ok(!ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile 10\n");
846 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 10\n");
847 ok(readden
== 4, "read got %d bytes 10\n", readden
);
848 SetLastError(0xdeadbeef);
849 ret
= RpcReadFile(hnp
, ibuf
+ 4, 4, &readden
, NULL
);
850 ok(!ret
, "RpcReadFile 10\n");
851 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 10\n");
852 ok(readden
== 4, "read got %d bytes 10\n", readden
);
853 readden
= leftmsg
= -1;
854 ok(PeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, &leftmsg
), "PeekNamedPipe 10\n");
855 ok(readden
== sizeof(obuf2
) - 8 + sizeof(obuf
), "peek got %d bytes total 10\n", readden
);
856 ok(leftmsg
== sizeof(obuf2
) - 8, "peek got %d bytes left in message 10\n", leftmsg
);
857 readden
= leftmsg
= -1;
858 ok(RpcPeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, &leftmsg
), "RpcPeekNamedPipe 10\n");
859 ok(readden
== sizeof(obuf2
) - 8 + sizeof(obuf
), "peek got %d bytes total 10\n", readden
);
860 ok(leftmsg
== sizeof(obuf2
) - 8, "peek got %d bytes left in message 10\n", leftmsg
);
861 ret
= RpcReadFile(hnp
, ibuf
+ 8, sizeof(ibuf
), &readden
, NULL
);
862 ok(ret
, "RpcReadFile 10\n");
863 ok(readden
== sizeof(obuf2
) - 8, "read got %d bytes 10\n", readden
);
864 ok(memcmp(obuf2
, ibuf
, sizeof(obuf2
)) == 0, "content check 10\n");
865 if (readden
<= sizeof(obuf2
) - 8) /* blocks forever if second part was already received */
867 memset(ibuf
, 0, sizeof(ibuf
));
868 readden
= leftmsg
= -1;
869 ok(PeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, &leftmsg
), "PeekNamedPipe 10\n");
870 ok(readden
== sizeof(obuf
), "peek got %d bytes total 10\n", readden
);
871 ok(leftmsg
== sizeof(obuf
), "peek got %d bytes left in message 10\n", leftmsg
);
872 readden
= leftmsg
= -1;
873 ok(RpcPeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, &leftmsg
), "RpcPeekNamedPipe 10\n");
874 ok(readden
== sizeof(obuf
), "peek got %d bytes total 10\n", readden
);
875 ok(leftmsg
== sizeof(obuf
), "peek got %d bytes left in message 10\n", leftmsg
);
876 SetLastError(0xdeadbeef);
877 ret
= RpcReadFile(hnp
, ibuf
, 4, &readden
, NULL
);
878 ok(!ret
, "RpcReadFile 10\n");
879 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 10\n");
880 ok(readden
== 4, "read got %d bytes 10\n", readden
);
881 SetLastError(0xdeadbeef);
882 ok(!ReadFile(hnp
, ibuf
+ 4, 4, &readden
, NULL
), "ReadFile 10\n");
883 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 10\n");
884 ok(readden
== 4, "read got %d bytes 10\n", readden
);
885 readden
= leftmsg
= -1;
886 ok(PeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, &leftmsg
), "PeekNamedPipe 10\n");
887 ok(readden
== sizeof(obuf
) - 8, "peek got %d bytes total 10\n", readden
);
888 ok(leftmsg
== sizeof(obuf
) - 8, "peek got %d bytes left in message 10\n", leftmsg
);
889 readden
= leftmsg
= -1;
890 ok(RpcPeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, &leftmsg
), "RpcPeekNamedPipe 10\n");
891 ok(readden
== sizeof(obuf
) - 8, "peek got %d bytes total 10\n", readden
);
892 ok(leftmsg
== sizeof(obuf
) - 8, "peek got %d bytes left in message 10\n", leftmsg
);
893 ret
= RpcReadFile(hnp
, ibuf
+ 8, sizeof(ibuf
), &readden
, NULL
);
894 ok(ret
, "RpcReadFile 10\n");
895 ok(readden
== sizeof(obuf
) - 8, "read got %d bytes 10\n", readden
);
896 ok(memcmp(obuf
, ibuf
, sizeof(obuf
)) == 0, "content check 10\n");
898 readden
= leftmsg
= -1;
899 ok(PeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, &leftmsg
), "PeekNamedPipe 10\n");
900 ok(readden
== 0, "peek got %d bytes total 10\n", readden
);
901 ok(leftmsg
== 0, "peek got %d bytes left in message 10\n", leftmsg
);
902 readden
= leftmsg
= -1;
903 ok(RpcPeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, &leftmsg
), "RpcPeekNamedPipe 10\n");
904 ok(readden
== 0, "peek got %d bytes total 10\n", readden
);
905 ok(leftmsg
== 0, "peek got %d bytes left in message 10\n", leftmsg
);
909 /* Test behaviour for very huge messages (which don't fit completely in the buffer) */
911 static char big_obuf
[512 * 1024];
912 static char big_ibuf
[512 * 1024];
913 struct rpcThreadArgs rpcargs
;
916 memset(big_obuf
, 0xAA, sizeof(big_obuf
));
918 /* Ensure that both pipes are empty before we continue with the next test */
919 while (PeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, NULL
) && readden
> 0)
920 ok(ReadFile(hFile
, big_ibuf
, sizeof(big_ibuf
), &readden
, NULL
) ||
921 GetLastError() == ERROR_MORE_DATA
, "ReadFile\n");
923 while (PeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, NULL
) && readden
> 0)
924 ok(ReadFile(hnp
, big_ibuf
, sizeof(big_ibuf
), &readden
, NULL
) ||
925 GetLastError() == ERROR_MORE_DATA
, "ReadFile\n");
927 readden
= leftmsg
= -1;
928 ok(PeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, &leftmsg
), "PeekNamedPipe\n");
929 ok(readden
== 0, "peek got %d bytes total\n", readden
);
930 ok(leftmsg
== 0, "peek got %d bytes left in message\n", leftmsg
);
932 /* transmit big message, receive with buffer of equal size */
933 memset(big_ibuf
, 0, sizeof(big_ibuf
));
934 rpcargs
.returnValue
= 0;
935 rpcargs
.lastError
= GetLastError();
936 rpcargs
.op
= RPC_WRITEFILE
;
937 rpcargs
.args
[0] = (ULONG_PTR
)hnp
;
938 rpcargs
.args
[1] = (ULONG_PTR
)big_obuf
;
939 rpcargs
.args
[2] = (ULONG_PTR
)sizeof(big_obuf
);
940 rpcargs
.args
[3] = (ULONG_PTR
)&written
;
941 rpcargs
.args
[4] = (ULONG_PTR
)NULL
;
943 thread
= CreateThread(NULL
, 0, rpcThreadMain
, (void *)&rpcargs
, 0, &threadId
);
944 ok(thread
!= NULL
, "CreateThread failed. %d\n", GetLastError());
945 ret
= WaitForSingleObject(thread
, 200);
946 ok(ret
== WAIT_TIMEOUT
, "WaitForSingleObject returned %d instead of %d.\n", ret
, WAIT_TIMEOUT
);
947 ok(ReadFile(hFile
, big_ibuf
, sizeof(big_ibuf
), &readden
, NULL
), "ReadFile\n");
949 ok(readden
== sizeof(big_obuf
), "read got %d bytes\n", readden
);
951 ok(memcmp(big_ibuf
, big_obuf
, sizeof(big_obuf
)) == 0, "content check\n");
954 ret
= WaitForSingleObject(thread
, 1);
955 while (PeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, NULL
) && readden
> 0)
956 ok(ReadFile(hFile
, big_ibuf
, sizeof(big_ibuf
), &readden
, NULL
) ||
957 GetLastError() == ERROR_MORE_DATA
, "ReadFile\n");
959 while (ret
== WAIT_TIMEOUT
);
960 ok(WaitForSingleObject(thread
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed with %d.\n", GetLastError());
961 ok((BOOL
)rpcargs
.returnValue
, "WriteFile\n");
962 ok(written
== sizeof(big_obuf
), "write file len\n");
965 readden
= leftmsg
= -1;
966 ok(PeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, &leftmsg
), "PeekNamedPipe\n");
967 ok(readden
== 0, "peek got %d bytes total\n", readden
);
968 ok(leftmsg
== 0, "peek got %d bytes left in message\n", leftmsg
);
970 /* same as above, but receive as multiple parts */
971 memset(big_ibuf
, 0, sizeof(big_ibuf
));
972 rpcargs
.returnValue
= 0;
973 rpcargs
.lastError
= GetLastError();
975 thread
= CreateThread(NULL
, 0, rpcThreadMain
, (void *)&rpcargs
, 0, &threadId
);
976 ok(thread
!= NULL
, "CreateThread failed. %d\n", GetLastError());
977 ret
= WaitForSingleObject(thread
, 200);
978 ok(ret
== WAIT_TIMEOUT
, "WaitForSingleObject returned %d instead of %d.\n", ret
, WAIT_TIMEOUT
);
979 if (pipemode
== PIPE_TYPE_BYTE
)
981 ok(ReadFile(hFile
, big_ibuf
, 32, &readden
, NULL
), "ReadFile\n");
982 ok(readden
== 32, "read got %d bytes\n", readden
);
983 ok(ReadFile(hFile
, big_ibuf
+ 32, 32, &readden
, NULL
), "ReadFile\n");
987 SetLastError(0xdeadbeef);
988 ok(!ReadFile(hFile
, big_ibuf
, 32, &readden
, NULL
), "ReadFile\n");
989 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error\n");
990 ok(readden
== 32, "read got %d bytes\n", readden
);
991 SetLastError(0xdeadbeef);
992 ok(!ReadFile(hFile
, big_ibuf
+ 32, 32, &readden
, NULL
), "ReadFile\n");
993 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error\n");
995 ok(readden
== 32, "read got %d bytes\n", readden
);
996 ok(ReadFile(hFile
, big_ibuf
+ 64, sizeof(big_ibuf
) - 64, &readden
, NULL
), "ReadFile\n");
998 ok(readden
== sizeof(big_obuf
) - 64, "read got %d bytes\n", readden
);
1000 ok(memcmp(big_ibuf
, big_obuf
, sizeof(big_obuf
)) == 0, "content check\n");
1003 ret
= WaitForSingleObject(thread
, 1);
1004 while (PeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, NULL
) && readden
> 0)
1005 ok(ReadFile(hFile
, big_ibuf
, sizeof(big_ibuf
), &readden
, NULL
) ||
1006 GetLastError() == ERROR_MORE_DATA
, "ReadFile\n");
1008 while (ret
== WAIT_TIMEOUT
);
1009 ok(WaitForSingleObject(thread
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed with %d.\n", GetLastError());
1010 ok((BOOL
)rpcargs
.returnValue
, "WriteFile\n");
1011 ok(written
== sizeof(big_obuf
), "write file len\n");
1012 CloseHandle(thread
);
1014 readden
= leftmsg
= -1;
1015 ok(PeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, &leftmsg
), "PeekNamedPipe\n");
1016 ok(readden
== 0, "peek got %d bytes total\n", readden
);
1017 ok(leftmsg
== 0, "peek got %d bytes left in message\n", leftmsg
);
1020 /* Picky conformance tests */
1022 /* Verify that you can't connect to pipe again
1023 * until server calls DisconnectNamedPipe+ConnectNamedPipe
1024 * or creates a new pipe
1025 * case 1: other client not yet closed
1027 hFile2
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1028 ok(hFile2
== INVALID_HANDLE_VALUE
,
1029 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n");
1030 ok(GetLastError() == ERROR_PIPE_BUSY
,
1031 "connecting to named pipe before other client closes should fail with ERROR_PIPE_BUSY\n");
1033 ok(CloseHandle(hFile
), "CloseHandle\n");
1035 /* case 2: other client already closed */
1036 hFile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1037 ok(hFile
== INVALID_HANDLE_VALUE
,
1038 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n");
1039 ok(GetLastError() == ERROR_PIPE_BUSY
,
1040 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail with ERROR_PIPE_BUSY\n");
1042 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe\n");
1044 /* case 3: server has called DisconnectNamedPipe but not ConnectNamed Pipe */
1045 hFile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1046 ok(hFile
== INVALID_HANDLE_VALUE
,
1047 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n");
1048 ok(GetLastError() == ERROR_PIPE_BUSY
,
1049 "connecting to named pipe after other client closes but before ConnectNamedPipe should fail with ERROR_PIPE_BUSY\n");
1051 /* to be complete, we'd call ConnectNamedPipe here and loop,
1052 * but by default that's blocking, so we'd either have
1053 * to turn on the uncommon nonblocking mode, or
1054 * use another thread.
1058 ok(CloseHandle(hnp
), "CloseHandle\n");
1060 hnp
= CreateNamedPipeA(PIPENAME_SPECIAL
, PIPE_ACCESS_DUPLEX
, pipemode
| PIPE_WAIT
,
1061 /* nMaxInstances */ 1,
1062 /* nOutBufSize */ 1024,
1063 /* nInBufSize */ 1024,
1064 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1065 /* lpSecurityAttrib */ NULL
);
1066 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe with special characters failed\n");
1067 ok(CloseHandle(hnp
), "CloseHandle\n");
1069 trace("test_CreateNamedPipe returning\n");
1072 static void test_CreateNamedPipe_instances_must_match(void)
1076 /* Check no mismatch */
1077 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
1078 /* nMaxInstances */ 2,
1079 /* nOutBufSize */ 1024,
1080 /* nInBufSize */ 1024,
1081 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1082 /* lpSecurityAttrib */ NULL
);
1083 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
1085 hnp2
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
1086 /* nMaxInstances */ 2,
1087 /* nOutBufSize */ 1024,
1088 /* nInBufSize */ 1024,
1089 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1090 /* lpSecurityAttrib */ NULL
);
1091 ok(hnp2
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
1093 ok(CloseHandle(hnp
), "CloseHandle\n");
1094 ok(CloseHandle(hnp2
), "CloseHandle\n");
1096 /* Check nMaxInstances */
1097 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
1098 /* nMaxInstances */ 1,
1099 /* nOutBufSize */ 1024,
1100 /* nInBufSize */ 1024,
1101 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1102 /* lpSecurityAttrib */ NULL
);
1103 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
1105 hnp2
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
1106 /* nMaxInstances */ 1,
1107 /* nOutBufSize */ 1024,
1108 /* nInBufSize */ 1024,
1109 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1110 /* lpSecurityAttrib */ NULL
);
1111 ok(hnp2
== INVALID_HANDLE_VALUE
1112 && GetLastError() == ERROR_PIPE_BUSY
, "nMaxInstances not obeyed\n");
1114 ok(CloseHandle(hnp
), "CloseHandle\n");
1116 /* Check PIPE_ACCESS_* */
1117 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
1118 /* nMaxInstances */ 2,
1119 /* nOutBufSize */ 1024,
1120 /* nInBufSize */ 1024,
1121 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1122 /* lpSecurityAttrib */ NULL
);
1123 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
1125 hnp2
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_INBOUND
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
1126 /* nMaxInstances */ 2,
1127 /* nOutBufSize */ 1024,
1128 /* nInBufSize */ 1024,
1129 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1130 /* lpSecurityAttrib */ NULL
);
1131 ok(hnp2
== INVALID_HANDLE_VALUE
1132 && GetLastError() == ERROR_ACCESS_DENIED
, "PIPE_ACCESS_* mismatch allowed\n");
1134 ok(CloseHandle(hnp
), "CloseHandle\n");
1136 /* check everything else */
1137 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
1138 /* nMaxInstances */ 4,
1139 /* nOutBufSize */ 1024,
1140 /* nInBufSize */ 1024,
1141 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1142 /* lpSecurityAttrib */ NULL
);
1143 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
1145 hnp2
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_MESSAGE
,
1146 /* nMaxInstances */ 3,
1147 /* nOutBufSize */ 102,
1148 /* nInBufSize */ 24,
1149 /* nDefaultWait */ 1234,
1150 /* lpSecurityAttrib */ NULL
);
1151 ok(hnp2
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
1153 ok(CloseHandle(hnp
), "CloseHandle\n");
1154 ok(CloseHandle(hnp2
), "CloseHandle\n");
1157 /** implementation of alarm() */
1158 static DWORD CALLBACK
alarmThreadMain(LPVOID arg
)
1160 DWORD_PTR timeout
= (DWORD_PTR
) arg
;
1161 trace("alarmThreadMain\n");
1162 if (WaitForSingleObject( alarm_event
, timeout
) == WAIT_TIMEOUT
)
1164 ok(FALSE
, "alarm\n");
1170 static HANDLE hnp
= INVALID_HANDLE_VALUE
;
1172 /** Trivial byte echo server - disconnects after each session */
1173 static DWORD CALLBACK
serverThreadMain1(LPVOID arg
)
1177 trace("serverThreadMain1 start\n");
1178 /* Set up a simple echo server */
1179 hnp
= CreateNamedPipeA(PIPENAME
"serverThreadMain1", PIPE_ACCESS_DUPLEX
,
1180 PIPE_TYPE_BYTE
| PIPE_WAIT
,
1181 /* nMaxInstances */ 1,
1182 /* nOutBufSize */ 1024,
1183 /* nInBufSize */ 1024,
1184 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1185 /* lpSecurityAttrib */ NULL
);
1187 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
1188 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
1194 /* Wait for client to connect */
1195 trace("Server calling ConnectNamedPipe...\n");
1196 ok(ConnectNamedPipe(hnp
, NULL
)
1197 || GetLastError() == ERROR_PIPE_CONNECTED
, "ConnectNamedPipe\n");
1198 trace("ConnectNamedPipe returned.\n");
1200 /* Echo bytes once */
1201 memset(buf
, 0, sizeof(buf
));
1203 trace("Server reading...\n");
1204 success
= ReadFile(hnp
, buf
, sizeof(buf
), &readden
, NULL
);
1205 trace("Server done reading.\n");
1206 ok(success
, "ReadFile\n");
1207 ok(readden
, "short read\n");
1209 trace("Server writing...\n");
1210 ok(WriteFile(hnp
, buf
, readden
, &written
, NULL
), "WriteFile\n");
1211 trace("Server done writing.\n");
1212 ok(written
== readden
, "write file len\n");
1214 /* finish this connection, wait for next one */
1215 ok(FlushFileBuffers(hnp
), "FlushFileBuffers\n");
1216 trace("Server done flushing.\n");
1217 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe\n");
1218 trace("Server done disconnecting.\n");
1223 /** Trivial byte echo server - closes after each connection */
1224 static DWORD CALLBACK
serverThreadMain2(LPVOID arg
)
1229 trace("serverThreadMain2\n");
1230 /* Set up a simple echo server */
1231 hnp
= CreateNamedPipeA(PIPENAME
"serverThreadMain2", PIPE_ACCESS_DUPLEX
,
1232 PIPE_TYPE_BYTE
| PIPE_WAIT
,
1233 /* nMaxInstances */ 2,
1234 /* nOutBufSize */ 1024,
1235 /* nInBufSize */ 1024,
1236 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1237 /* lpSecurityAttrib */ NULL
);
1238 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
1240 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
1248 user_apc_ran
= FALSE
;
1249 if (i
== 0 && pQueueUserAPC
) {
1250 trace("Queueing an user APC\n"); /* verify the pipe is non alerable */
1251 ret
= pQueueUserAPC(&user_apc
, GetCurrentThread(), 0);
1252 ok(ret
, "QueueUserAPC failed: %d\n", GetLastError());
1255 /* Wait for client to connect */
1256 trace("Server calling ConnectNamedPipe...\n");
1257 ok(ConnectNamedPipe(hnp
, NULL
)
1258 || GetLastError() == ERROR_PIPE_CONNECTED
, "ConnectNamedPipe\n");
1259 trace("ConnectNamedPipe returned.\n");
1261 /* Echo bytes once */
1262 memset(buf
, 0, sizeof(buf
));
1264 trace("Server reading...\n");
1265 success
= ReadFile(hnp
, buf
, sizeof(buf
), &readden
, NULL
);
1266 trace("Server done reading.\n");
1267 ok(success
, "ReadFile\n");
1269 trace("Server writing...\n");
1270 ok(WriteFile(hnp
, buf
, readden
, &written
, NULL
), "WriteFile\n");
1271 trace("Server done writing.\n");
1272 ok(written
== readden
, "write file len\n");
1274 /* finish this connection, wait for next one */
1275 ok(FlushFileBuffers(hnp
), "FlushFileBuffers\n");
1276 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe\n");
1278 ok(user_apc_ran
== FALSE
, "UserAPC ran, pipe using alertable io mode\n");
1280 if (i
== 0 && pQueueUserAPC
)
1281 SleepEx(0, TRUE
); /* get rid of apc */
1283 /* Set up next echo server */
1285 CreateNamedPipeA(PIPENAME
"serverThreadMain2", PIPE_ACCESS_DUPLEX
,
1286 PIPE_TYPE_BYTE
| PIPE_WAIT
,
1287 /* nMaxInstances */ 2,
1288 /* nOutBufSize */ 1024,
1289 /* nInBufSize */ 1024,
1290 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1291 /* lpSecurityAttrib */ NULL
);
1293 ok(hnpNext
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
1295 ok(CloseHandle(hnp
), "CloseHandle\n");
1301 /** Trivial byte echo server - uses overlapped named pipe calls */
1302 static DWORD CALLBACK
serverThreadMain3(LPVOID arg
)
1307 trace("serverThreadMain3\n");
1308 /* Set up a simple echo server */
1309 hnp
= CreateNamedPipeA(PIPENAME
"serverThreadMain3", PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
1310 PIPE_TYPE_BYTE
| PIPE_WAIT
,
1311 /* nMaxInstances */ 1,
1312 /* nOutBufSize */ 1024,
1313 /* nInBufSize */ 1024,
1314 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1315 /* lpSecurityAttrib */ NULL
);
1316 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
1318 hEvent
= CreateEventW(NULL
, /* security attribute */
1319 TRUE
, /* manual reset event */
1320 FALSE
, /* initial state */
1322 ok(hEvent
!= NULL
, "CreateEvent\n");
1324 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
1330 OVERLAPPED oOverlap
;
1331 int letWFSOEwait
= (i
& 2);
1332 int letGORwait
= (i
& 1);
1335 memset(&oOverlap
, 0, sizeof(oOverlap
));
1336 oOverlap
.hEvent
= hEvent
;
1338 /* Wait for client to connect */
1340 trace("Server calling non-overlapped ConnectNamedPipe on overlapped pipe...\n");
1341 success
= ConnectNamedPipe(hnp
, NULL
);
1342 err
= GetLastError();
1343 ok(success
|| (err
== ERROR_PIPE_CONNECTED
), "ConnectNamedPipe failed: %d\n", err
);
1344 trace("ConnectNamedPipe operation complete.\n");
1346 trace("Server calling overlapped ConnectNamedPipe...\n");
1347 success
= ConnectNamedPipe(hnp
, &oOverlap
);
1348 err
= GetLastError();
1349 ok(!success
&& (err
== ERROR_IO_PENDING
|| err
== ERROR_PIPE_CONNECTED
), "overlapped ConnectNamedPipe\n");
1350 trace("overlapped ConnectNamedPipe returned.\n");
1351 if (!success
&& (err
== ERROR_IO_PENDING
)) {
1356 ret
= WaitForSingleObjectEx(hEvent
, INFINITE
, TRUE
);
1357 } while (ret
== WAIT_IO_COMPLETION
);
1358 ok(ret
== 0, "wait ConnectNamedPipe returned %x\n", ret
);
1360 success
= GetOverlappedResult(hnp
, &oOverlap
, &dummy
, letGORwait
);
1361 if (!letGORwait
&& !letWFSOEwait
&& !success
) {
1362 ok(GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult\n");
1363 success
= GetOverlappedResult(hnp
, &oOverlap
, &dummy
, TRUE
);
1366 ok(success
|| (err
== ERROR_PIPE_CONNECTED
), "GetOverlappedResult ConnectNamedPipe\n");
1367 trace("overlapped ConnectNamedPipe operation complete.\n");
1370 /* Echo bytes once */
1371 memset(buf
, 0, sizeof(buf
));
1373 trace("Server reading...\n");
1374 success
= ReadFile(hnp
, buf
, sizeof(buf
), &readden
, &oOverlap
);
1375 trace("Server ReadFile returned...\n");
1376 err
= GetLastError();
1377 ok(success
|| err
== ERROR_IO_PENDING
, "overlapped ReadFile\n");
1378 trace("overlapped ReadFile returned.\n");
1379 if (!success
&& (err
== ERROR_IO_PENDING
)) {
1384 ret
= WaitForSingleObjectEx(hEvent
, INFINITE
, TRUE
);
1385 } while (ret
== WAIT_IO_COMPLETION
);
1386 ok(ret
== 0, "wait ReadFile returned %x\n", ret
);
1388 success
= GetOverlappedResult(hnp
, &oOverlap
, &readden
, letGORwait
);
1389 if (!letGORwait
&& !letWFSOEwait
&& !success
) {
1390 ok(GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult\n");
1391 success
= GetOverlappedResult(hnp
, &oOverlap
, &readden
, TRUE
);
1394 trace("Server done reading.\n");
1395 ok(success
, "overlapped ReadFile\n");
1397 trace("Server writing...\n");
1398 success
= WriteFile(hnp
, buf
, readden
, &written
, &oOverlap
);
1399 trace("Server WriteFile returned...\n");
1400 err
= GetLastError();
1401 ok(success
|| err
== ERROR_IO_PENDING
, "overlapped WriteFile\n");
1402 trace("overlapped WriteFile returned.\n");
1403 if (!success
&& (err
== ERROR_IO_PENDING
)) {
1408 ret
= WaitForSingleObjectEx(hEvent
, INFINITE
, TRUE
);
1409 } while (ret
== WAIT_IO_COMPLETION
);
1410 ok(ret
== 0, "wait WriteFile returned %x\n", ret
);
1412 success
= GetOverlappedResult(hnp
, &oOverlap
, &written
, letGORwait
);
1413 if (!letGORwait
&& !letWFSOEwait
&& !success
) {
1414 ok(GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult\n");
1415 success
= GetOverlappedResult(hnp
, &oOverlap
, &written
, TRUE
);
1418 trace("Server done writing.\n");
1419 ok(success
, "overlapped WriteFile\n");
1420 ok(written
== readden
, "write file len\n");
1422 /* finish this connection, wait for next one */
1423 ok(FlushFileBuffers(hnp
), "FlushFileBuffers\n");
1424 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe\n");
1429 /** Trivial byte echo server - uses i/o completion ports */
1430 static DWORD CALLBACK
serverThreadMain4(LPVOID arg
)
1436 trace("serverThreadMain4\n");
1437 /* Set up a simple echo server */
1438 hnp
= CreateNamedPipeA(PIPENAME
"serverThreadMain4", PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
1439 PIPE_TYPE_BYTE
| PIPE_WAIT
,
1440 /* nMaxInstances */ 1,
1441 /* nOutBufSize */ 1024,
1442 /* nInBufSize */ 1024,
1443 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1444 /* lpSecurityAttrib */ NULL
);
1445 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
1447 hcompletion
= CreateIoCompletionPort(hnp
, NULL
, 12345, 1);
1448 ok(hcompletion
!= NULL
, "CreateIoCompletionPort failed, error=%i\n", GetLastError());
1450 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
1456 OVERLAPPED oConnect
;
1459 OVERLAPPED
*oResult
;
1463 memset(&oConnect
, 0, sizeof(oConnect
));
1464 memset(&oRead
, 0, sizeof(oRead
));
1465 memset(&oWrite
, 0, sizeof(oWrite
));
1467 /* Wait for client to connect */
1468 trace("Server calling overlapped ConnectNamedPipe...\n");
1469 success
= ConnectNamedPipe(hnp
, &oConnect
);
1470 err
= GetLastError();
1471 ok(!success
&& (err
== ERROR_IO_PENDING
|| err
== ERROR_PIPE_CONNECTED
),
1472 "overlapped ConnectNamedPipe got %u err %u\n", success
, err
);
1473 if (!success
&& err
== ERROR_IO_PENDING
) {
1474 trace("ConnectNamedPipe GetQueuedCompletionStatus\n");
1475 success
= GetQueuedCompletionStatus(hcompletion
, &dummy
, &compkey
, &oResult
, 0);
1478 ok( GetLastError() == WAIT_TIMEOUT
,
1479 "ConnectNamedPipe GetQueuedCompletionStatus wrong error %u\n", GetLastError());
1480 success
= GetQueuedCompletionStatus(hcompletion
, &dummy
, &compkey
, &oResult
, 10000);
1482 ok(success
, "ConnectNamedPipe GetQueuedCompletionStatus failed, errno=%i\n", GetLastError());
1485 ok(compkey
== 12345, "got completion key %i instead of 12345\n", (int)compkey
);
1486 ok(oResult
== &oConnect
, "got overlapped pointer %p instead of %p\n", oResult
, &oConnect
);
1489 trace("overlapped ConnectNamedPipe operation complete.\n");
1491 /* Echo bytes once */
1492 memset(buf
, 0, sizeof(buf
));
1494 trace("Server reading...\n");
1495 success
= ReadFile(hnp
, buf
, sizeof(buf
), &readden
, &oRead
);
1496 trace("Server ReadFile returned...\n");
1497 err
= GetLastError();
1498 ok(success
|| err
== ERROR_IO_PENDING
, "overlapped ReadFile, err=%i\n", err
);
1499 success
= GetQueuedCompletionStatus(hcompletion
, &readden
, &compkey
,
1501 ok(success
, "ReadFile GetQueuedCompletionStatus failed, errno=%i\n", GetLastError());
1504 ok(compkey
== 12345, "got completion key %i instead of 12345\n", (int)compkey
);
1505 ok(oResult
== &oRead
, "got overlapped pointer %p instead of %p\n", oResult
, &oRead
);
1507 trace("Server done reading.\n");
1509 trace("Server writing...\n");
1510 success
= WriteFile(hnp
, buf
, readden
, &written
, &oWrite
);
1511 trace("Server WriteFile returned...\n");
1512 err
= GetLastError();
1513 ok(success
|| err
== ERROR_IO_PENDING
, "overlapped WriteFile failed, err=%u\n", err
);
1514 success
= GetQueuedCompletionStatus(hcompletion
, &written
, &compkey
,
1516 ok(success
, "WriteFile GetQueuedCompletionStatus failed, errno=%i\n", GetLastError());
1519 ok(compkey
== 12345, "got completion key %i instead of 12345\n", (int)compkey
);
1520 ok(oResult
== &oWrite
, "got overlapped pointer %p instead of %p\n", oResult
, &oWrite
);
1521 ok(written
== readden
, "write file len\n");
1523 trace("Server done writing.\n");
1525 /* finish this connection, wait for next one */
1526 ok(FlushFileBuffers(hnp
), "FlushFileBuffers\n");
1527 success
= DisconnectNamedPipe(hnp
);
1528 ok(success
, "DisconnectNamedPipe failed, err %u\n", GetLastError());
1531 ret
= CloseHandle(hnp
);
1532 ok(ret
, "CloseHandle named pipe failed, err=%i\n", GetLastError());
1533 ret
= CloseHandle(hcompletion
);
1534 ok(ret
, "CloseHandle completion failed, err=%i\n", GetLastError());
1539 static int completion_called
;
1540 static DWORD completion_errorcode
;
1541 static DWORD completion_num_bytes
;
1542 static LPOVERLAPPED completion_lpoverlapped
;
1544 static VOID WINAPI
completion_routine(DWORD errorcode
, DWORD num_bytes
, LPOVERLAPPED lpoverlapped
)
1546 completion_called
++;
1547 completion_errorcode
= errorcode
;
1548 completion_num_bytes
= num_bytes
;
1549 completion_lpoverlapped
= lpoverlapped
;
1550 SetEvent(lpoverlapped
->hEvent
);
1553 /** Trivial byte echo server - uses ReadFileEx/WriteFileEx */
1554 static DWORD CALLBACK
serverThreadMain5(LPVOID arg
)
1559 trace("serverThreadMain5\n");
1560 /* Set up a simple echo server */
1561 hnp
= CreateNamedPipeA(PIPENAME
"serverThreadMain5", PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
1562 PIPE_TYPE_BYTE
| PIPE_WAIT
,
1563 /* nMaxInstances */ 1,
1564 /* nOutBufSize */ 1024,
1565 /* nInBufSize */ 1024,
1566 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1567 /* lpSecurityAttrib */ NULL
);
1568 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
1570 hEvent
= CreateEventW(NULL
, /* security attribute */
1571 TRUE
, /* manual reset event */
1572 FALSE
, /* initial state */
1574 ok(hEvent
!= NULL
, "CreateEvent\n");
1576 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
1580 OVERLAPPED oOverlap
;
1583 memset(&oOverlap
, 0, sizeof(oOverlap
));
1584 oOverlap
.hEvent
= hEvent
;
1586 /* Wait for client to connect */
1587 trace("Server calling ConnectNamedPipe...\n");
1588 success
= ConnectNamedPipe(hnp
, NULL
);
1589 err
= GetLastError();
1590 ok(success
|| (err
== ERROR_PIPE_CONNECTED
), "ConnectNamedPipe failed: %d\n", err
);
1591 trace("ConnectNamedPipe operation complete.\n");
1593 /* Echo bytes once */
1594 memset(buf
, 0, sizeof(buf
));
1596 trace("Server reading...\n");
1597 completion_called
= 0;
1599 success
= ReadFileEx(hnp
, buf
, sizeof(buf
), &oOverlap
, completion_routine
);
1600 trace("Server ReadFileEx returned...\n");
1601 ok(success
, "ReadFileEx failed, err=%i\n", GetLastError());
1602 ok(completion_called
== 0, "completion routine called before ReadFileEx return\n");
1603 trace("ReadFileEx returned.\n");
1607 ret
= WaitForSingleObjectEx(hEvent
, INFINITE
, TRUE
);
1608 } while (ret
== WAIT_IO_COMPLETION
);
1609 ok(ret
== 0, "wait ReadFileEx returned %x\n", ret
);
1611 ok(completion_called
== 1, "completion routine called %i times\n", completion_called
);
1612 ok(completion_errorcode
== ERROR_SUCCESS
, "completion routine got error %d\n", completion_errorcode
);
1613 ok(completion_num_bytes
!= 0, "read 0 bytes\n");
1614 ok(completion_lpoverlapped
== &oOverlap
, "got wrong overlapped pointer %p\n", completion_lpoverlapped
);
1615 readden
= completion_num_bytes
;
1616 trace("Server done reading.\n");
1618 trace("Server writing...\n");
1619 completion_called
= 0;
1621 success
= WriteFileEx(hnp
, buf
, readden
, &oOverlap
, completion_routine
);
1622 trace("Server WriteFileEx returned...\n");
1623 ok(success
, "WriteFileEx failed, err=%i\n", GetLastError());
1624 ok(completion_called
== 0, "completion routine called before ReadFileEx return\n");
1625 trace("overlapped WriteFile returned.\n");
1629 ret
= WaitForSingleObjectEx(hEvent
, INFINITE
, TRUE
);
1630 } while (ret
== WAIT_IO_COMPLETION
);
1631 ok(ret
== 0, "wait WriteFileEx returned %x\n", ret
);
1633 trace("Server done writing.\n");
1634 ok(completion_called
== 1, "completion routine called %i times\n", completion_called
);
1635 ok(completion_errorcode
== ERROR_SUCCESS
, "completion routine got error %d\n", completion_errorcode
);
1636 ok(completion_num_bytes
== readden
, "read %i bytes wrote %i\n", readden
, completion_num_bytes
);
1637 ok(completion_lpoverlapped
== &oOverlap
, "got wrong overlapped pointer %p\n", completion_lpoverlapped
);
1639 /* finish this connection, wait for next one */
1640 ok(FlushFileBuffers(hnp
), "FlushFileBuffers\n");
1641 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe\n");
1646 static void exercizeServer(const char *pipename
, HANDLE serverThread
)
1650 trace("exercizeServer starting\n");
1651 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
1652 HANDLE hFile
=INVALID_HANDLE_VALUE
;
1653 static const char obuf
[] = "Bit Bucket";
1659 for (loop
= 0; loop
< 3; loop
++) {
1661 trace("Client connecting...\n");
1662 /* Connect to the server */
1663 hFile
= CreateFileA(pipename
, GENERIC_READ
| GENERIC_WRITE
, 0,
1664 NULL
, OPEN_EXISTING
, 0, 0);
1665 if (hFile
!= INVALID_HANDLE_VALUE
)
1667 err
= GetLastError();
1669 ok(err
== ERROR_PIPE_BUSY
|| err
== ERROR_FILE_NOT_FOUND
, "connecting to pipe\n");
1671 ok(err
== ERROR_PIPE_BUSY
, "connecting to pipe\n");
1672 trace("connect failed, retrying\n");
1675 ok(hFile
!= INVALID_HANDLE_VALUE
, "client opening named pipe\n");
1677 /* Make sure it can echo */
1678 memset(ibuf
, 0, sizeof(ibuf
));
1679 trace("Client writing...\n");
1680 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile to client end of pipe\n");
1681 ok(written
== sizeof(obuf
), "write file len\n");
1682 trace("Client reading...\n");
1683 ok(ReadFile(hFile
, ibuf
, sizeof(obuf
), &readden
, NULL
), "ReadFile from client end of pipe\n");
1684 ok(readden
== sizeof(obuf
), "read file len\n");
1685 ok(memcmp(obuf
, ibuf
, written
) == 0, "content check\n");
1687 trace("Client closing...\n");
1688 ok(CloseHandle(hFile
), "CloseHandle\n");
1691 ok(WaitForSingleObject(serverThread
,INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject\n");
1693 trace("exercizeServer returning\n");
1696 static void test_NamedPipe_2(void)
1698 HANDLE serverThread
;
1699 DWORD serverThreadId
;
1701 DWORD alarmThreadId
;
1703 trace("test_NamedPipe_2 starting\n");
1704 /* Set up a twenty second timeout */
1705 alarm_event
= CreateEventW( NULL
, TRUE
, FALSE
, NULL
);
1706 SetLastError(0xdeadbeef);
1707 alarmThread
= CreateThread(NULL
, 0, alarmThreadMain
, (void *) 20000, 0, &alarmThreadId
);
1708 ok(alarmThread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1710 /* The servers we're about to exercise do try to clean up carefully,
1711 * but to reduce the chance of a test failure due to a pipe handle
1712 * leak in the test code, we'll use a different pipe name for each server.
1716 SetLastError(0xdeadbeef);
1717 serverThread
= CreateThread(NULL
, 0, serverThreadMain1
, (void *)8, 0, &serverThreadId
);
1718 ok(serverThread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1719 exercizeServer(PIPENAME
"serverThreadMain1", serverThread
);
1722 SetLastError(0xdeadbeef);
1723 serverThread
= CreateThread(NULL
, 0, serverThreadMain2
, 0, 0, &serverThreadId
);
1724 ok(serverThread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1725 exercizeServer(PIPENAME
"serverThreadMain2", serverThread
);
1728 SetLastError(0xdeadbeef);
1729 serverThread
= CreateThread(NULL
, 0, serverThreadMain3
, 0, 0, &serverThreadId
);
1730 ok(serverThread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1731 exercizeServer(PIPENAME
"serverThreadMain3", serverThread
);
1734 SetLastError(0xdeadbeef);
1735 serverThread
= CreateThread(NULL
, 0, serverThreadMain4
, 0, 0, &serverThreadId
);
1736 ok(serverThread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1737 exercizeServer(PIPENAME
"serverThreadMain4", serverThread
);
1740 SetLastError(0xdeadbeef);
1741 serverThread
= CreateThread(NULL
, 0, serverThreadMain5
, 0, 0, &serverThreadId
);
1742 ok(serverThread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1743 exercizeServer(PIPENAME
"serverThreadMain5", serverThread
);
1745 ok(SetEvent( alarm_event
), "SetEvent\n");
1746 CloseHandle( alarm_event
);
1747 trace("test_NamedPipe_2 returning\n");
1750 static int test_DisconnectNamedPipe(void)
1754 static const char obuf
[] = "Bit Bucket";
1760 SetLastError(0xdeadbeef);
1761 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
1762 /* nMaxInstances */ 1,
1763 /* nOutBufSize */ 1024,
1764 /* nInBufSize */ 1024,
1765 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1766 /* lpSecurityAttrib */ NULL
);
1767 if ((hnp
== INVALID_HANDLE_VALUE
/* Win98 */ || !hnp
/* Win95 */)
1768 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
) {
1770 win_skip("Named pipes are not implemented\n");
1774 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
) == 0
1775 && GetLastError() == ERROR_PIPE_LISTENING
, "WriteFile to not-yet-connected pipe\n");
1776 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
) == 0
1777 && GetLastError() == ERROR_PIPE_LISTENING
, "ReadFile from not-yet-connected pipe\n");
1779 hFile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1780 ok(hFile
!= INVALID_HANDLE_VALUE
, "CreateFile failed\n");
1782 /* don't try to do i/o if one side couldn't be opened, as it hangs */
1783 if (hFile
!= INVALID_HANDLE_VALUE
) {
1785 /* see what happens if server calls DisconnectNamedPipe
1786 * when there are bytes in the pipe
1789 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile\n");
1790 ok(written
== sizeof(obuf
), "write file len\n");
1791 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe while messages waiting\n");
1792 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
) == 0
1793 && GetLastError() == ERROR_PIPE_NOT_CONNECTED
, "WriteFile to disconnected pipe\n");
1794 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
) == 0
1795 && GetLastError() == ERROR_PIPE_NOT_CONNECTED
,
1796 "ReadFile from disconnected pipe with bytes waiting\n");
1797 ok(!DisconnectNamedPipe(hnp
) && GetLastError() == ERROR_PIPE_NOT_CONNECTED
,
1798 "DisconnectNamedPipe worked twice\n");
1799 ret
= WaitForSingleObject(hFile
, 0);
1800 ok(ret
== WAIT_TIMEOUT
, "WaitForSingleObject returned %X\n", ret
);
1801 ok(CloseHandle(hFile
), "CloseHandle\n");
1804 ok(CloseHandle(hnp
), "CloseHandle\n");
1808 static void test_CreatePipe(void)
1810 SECURITY_ATTRIBUTES pipe_attr
;
1811 HANDLE piperead
, pipewrite
;
1818 user_apc_ran
= FALSE
;
1820 ok(pQueueUserAPC(user_apc
, GetCurrentThread(), 0), "couldn't create user apc\n");
1822 pipe_attr
.nLength
= sizeof(SECURITY_ATTRIBUTES
);
1823 pipe_attr
.bInheritHandle
= TRUE
;
1824 pipe_attr
.lpSecurityDescriptor
= NULL
;
1825 ok(CreatePipe(&piperead
, &pipewrite
, &pipe_attr
, 0) != 0, "CreatePipe failed\n");
1826 ok(WriteFile(pipewrite
,PIPENAME
,sizeof(PIPENAME
), &written
, NULL
), "Write to anonymous pipe failed\n");
1827 ok(written
== sizeof(PIPENAME
), "Write to anonymous pipe wrote %d bytes\n", written
);
1828 ok(ReadFile(piperead
,readbuf
,sizeof(readbuf
),&read
, NULL
), "Read from non empty pipe failed\n");
1829 ok(read
== sizeof(PIPENAME
), "Read from anonymous pipe got %d bytes\n", read
);
1830 ok(CloseHandle(pipewrite
), "CloseHandle for the write pipe failed\n");
1831 ok(CloseHandle(piperead
), "CloseHandle for the read pipe failed\n");
1833 /* Now write another chunk*/
1834 ok(CreatePipe(&piperead
, &pipewrite
, &pipe_attr
, 0) != 0, "CreatePipe failed\n");
1835 ok(WriteFile(pipewrite
,PIPENAME
,sizeof(PIPENAME
), &written
, NULL
), "Write to anonymous pipe failed\n");
1836 ok(written
== sizeof(PIPENAME
), "Write to anonymous pipe wrote %d bytes\n", written
);
1837 /* and close the write end, read should still succeed*/
1838 ok(CloseHandle(pipewrite
), "CloseHandle for the Write Pipe failed\n");
1839 ok(ReadFile(piperead
,readbuf
,sizeof(readbuf
),&read
, NULL
), "Read from broken pipe withe with pending data failed\n");
1840 ok(read
== sizeof(PIPENAME
), "Read from anonymous pipe got %d bytes\n", read
);
1841 /* But now we need to get informed that the pipe is closed */
1842 ok(ReadFile(piperead
,readbuf
,sizeof(readbuf
),&read
, NULL
) == 0, "Broken pipe not detected\n");
1843 ok(CloseHandle(piperead
), "CloseHandle for the read pipe failed\n");
1845 /* Try bigger chunks */
1847 buffer
= HeapAlloc( GetProcessHeap(), 0, size
);
1848 for (i
= 0; i
< size
; i
++) buffer
[i
] = i
;
1849 ok(CreatePipe(&piperead
, &pipewrite
, &pipe_attr
, (size
+ 24)) != 0, "CreatePipe failed\n");
1850 ok(WriteFile(pipewrite
, buffer
, size
, &written
, NULL
), "Write to anonymous pipe failed\n");
1851 ok(written
== size
, "Write to anonymous pipe wrote %d bytes\n", written
);
1852 /* and close the write end, read should still succeed*/
1853 ok(CloseHandle(pipewrite
), "CloseHandle for the Write Pipe failed\n");
1854 memset( buffer
, 0, size
);
1855 ok(ReadFile(piperead
, buffer
, size
, &read
, NULL
), "Read from broken pipe withe with pending data failed\n");
1856 ok(read
== size
, "Read from anonymous pipe got %d bytes\n", read
);
1857 for (i
= 0; i
< size
; i
++) ok( buffer
[i
] == (BYTE
)i
, "invalid data %x at %x\n", buffer
[i
], i
);
1858 /* But now we need to get informed that the pipe is closed */
1859 ok(ReadFile(piperead
,readbuf
,sizeof(readbuf
),&read
, NULL
) == 0, "Broken pipe not detected\n");
1860 ok(CloseHandle(piperead
), "CloseHandle for the read pipe failed\n");
1861 HeapFree(GetProcessHeap(), 0, buffer
);
1863 ok(user_apc_ran
== FALSE
, "user apc ran, pipe using alertable io mode\n");
1864 SleepEx(0, TRUE
); /* get rid of apc */
1867 static void test_CloseHandle(void)
1869 static const char testdata
[] = "Hello World";
1870 DWORD state
, numbytes
;
1871 HANDLE hpipe
, hfile
;
1875 hpipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
1876 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1877 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1878 ok(hpipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %u\n", GetLastError());
1880 hfile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1881 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %u\n", GetLastError());
1883 numbytes
= 0xdeadbeef;
1884 ret
= WriteFile(hpipe
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1885 ok(ret
, "WriteFile failed with %u\n", GetLastError());
1886 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1888 numbytes
= 0xdeadbeef;
1889 ret
= PeekNamedPipe(hfile
, NULL
, 0, NULL
, &numbytes
, NULL
);
1890 ok(ret
, "PeekNamedPipe failed with %u\n", GetLastError());
1891 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1893 ret
= CloseHandle(hpipe
);
1894 ok(ret
, "CloseHandle failed with %u\n", GetLastError());
1896 numbytes
= 0xdeadbeef;
1897 memset(buffer
, 0, sizeof(buffer
));
1898 ret
= ReadFile(hfile
, buffer
, 0, &numbytes
, NULL
);
1899 ok(ret
, "ReadFile failed with %u\n", GetLastError());
1900 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
1902 numbytes
= 0xdeadbeef;
1903 memset(buffer
, 0, sizeof(buffer
));
1904 ret
= ReadFile(hfile
, buffer
, sizeof(buffer
), &numbytes
, NULL
);
1905 ok(ret
, "ReadFile failed with %u\n", GetLastError());
1906 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1908 ret
= GetNamedPipeHandleStateA(hfile
, &state
, NULL
, NULL
, NULL
, NULL
, 0);
1909 ok(ret
, "GetNamedPipeHandleState failed with %u\n", GetLastError());
1910 state
= PIPE_READMODE_MESSAGE
| PIPE_WAIT
;
1911 ret
= SetNamedPipeHandleState(hfile
, &state
, NULL
, NULL
);
1912 ok(ret
, "SetNamedPipeHandleState failed with %u\n", GetLastError());
1914 SetLastError(0xdeadbeef);
1915 ret
= ReadFile(hfile
, buffer
, 0, &numbytes
, NULL
);
1916 ok(!ret
, "ReadFile unexpectedly succeeded\n");
1917 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1919 SetLastError(0xdeadbeef);
1920 ret
= WriteFile(hfile
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1921 ok(!ret
, "WriteFile unexpectedly succeeded\n");
1922 ok(GetLastError() == ERROR_NO_DATA
, "expected ERROR_NO_DATA, got %u\n", GetLastError());
1926 hpipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
1927 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1928 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1929 ok(hpipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %u\n", GetLastError());
1931 hfile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1932 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %u\n", GetLastError());
1934 numbytes
= 0xdeadbeef;
1935 ret
= WriteFile(hpipe
, testdata
, 0, &numbytes
, NULL
);
1936 ok(ret
, "WriteFile failed with %u\n", GetLastError());
1937 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
1939 ret
= CloseHandle(hpipe
);
1940 ok(ret
, "CloseHandle failed with %u\n", GetLastError());
1942 numbytes
= 0xdeadbeef;
1943 memset(buffer
, 0, sizeof(buffer
));
1944 ret
= ReadFile(hfile
, buffer
, sizeof(buffer
), &numbytes
, NULL
);
1945 todo_wine
ok(ret
, "ReadFile failed with %u\n", GetLastError());
1946 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
1948 ret
= GetNamedPipeHandleStateA(hfile
, &state
, NULL
, NULL
, NULL
, NULL
, 0);
1949 ok(ret
, "GetNamedPipeHandleState failed with %u\n", GetLastError());
1950 state
= PIPE_READMODE_MESSAGE
| PIPE_WAIT
;
1951 ret
= SetNamedPipeHandleState(hfile
, &state
, NULL
, NULL
);
1952 ok(ret
, "SetNamedPipeHandleState failed with %u\n", GetLastError());
1954 SetLastError(0xdeadbeef);
1955 ret
= ReadFile(hfile
, buffer
, 0, &numbytes
, NULL
);
1956 ok(!ret
, "ReadFile unexpectedly succeeded\n");
1957 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1959 SetLastError(0xdeadbeef);
1960 ret
= WriteFile(hfile
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1961 ok(!ret
, "WriteFile unexpectedly succeeded\n");
1962 ok(GetLastError() == ERROR_NO_DATA
, "expected ERROR_NO_DATA, got %u\n", GetLastError());
1966 /* repeat test with hpipe <-> hfile swapped */
1968 hpipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
1969 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1970 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1971 ok(hpipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %u\n", GetLastError());
1973 hfile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1974 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %u\n", GetLastError());
1976 numbytes
= 0xdeadbeef;
1977 ret
= WriteFile(hfile
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1978 ok(ret
, "WriteFile failed with %u\n", GetLastError());
1979 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1981 numbytes
= 0xdeadbeef;
1982 ret
= PeekNamedPipe(hpipe
, NULL
, 0, NULL
, &numbytes
, NULL
);
1983 ok(ret
, "PeekNamedPipe failed with %u\n", GetLastError());
1984 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1986 ret
= CloseHandle(hfile
);
1987 ok(ret
, "CloseHandle failed with %u\n", GetLastError());
1989 numbytes
= 0xdeadbeef;
1990 memset(buffer
, 0, sizeof(buffer
));
1991 ret
= ReadFile(hpipe
, buffer
, 0, &numbytes
, NULL
);
1992 ok(ret
|| broken(GetLastError() == ERROR_MORE_DATA
) /* >= Win 8 */,
1993 "ReadFile failed with %u\n", GetLastError());
1994 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
1996 numbytes
= 0xdeadbeef;
1997 memset(buffer
, 0, sizeof(buffer
));
1998 ret
= ReadFile(hpipe
, buffer
, sizeof(buffer
), &numbytes
, NULL
);
1999 ok(ret
, "ReadFile failed with %u\n", GetLastError());
2000 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
2002 ret
= GetNamedPipeHandleStateA(hpipe
, &state
, NULL
, NULL
, NULL
, NULL
, 0);
2003 ok(ret
, "GetNamedPipeHandleState failed with %u\n", GetLastError());
2004 state
= PIPE_READMODE_MESSAGE
| PIPE_WAIT
;
2005 ret
= SetNamedPipeHandleState(hpipe
, &state
, NULL
, NULL
);
2006 ok(ret
, "SetNamedPipeHandleState failed with %u\n", GetLastError());
2008 SetLastError(0xdeadbeef);
2009 ret
= ReadFile(hpipe
, buffer
, 0, &numbytes
, NULL
);
2010 ok(!ret
, "ReadFile unexpectedly succeeded\n");
2011 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
2013 SetLastError(0xdeadbeef);
2014 ret
= WriteFile(hpipe
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
2015 ok(!ret
, "WriteFile unexpectedly succeeded\n");
2016 todo_wine
ok(GetLastError() == ERROR_NO_DATA
, "expected ERROR_NO_DATA, got %u\n", GetLastError());
2020 hpipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
2021 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
2022 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
2023 ok(hpipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %u\n", GetLastError());
2025 hfile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
2026 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %u\n", GetLastError());
2028 numbytes
= 0xdeadbeef;
2029 ret
= WriteFile(hfile
, testdata
, 0, &numbytes
, NULL
);
2030 ok(ret
, "WriteFile failed with %u\n", GetLastError());
2031 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
2033 ret
= CloseHandle(hfile
);
2034 ok(ret
, "CloseHandle failed with %u\n", GetLastError());
2036 numbytes
= 0xdeadbeef;
2037 memset(buffer
, 0, sizeof(buffer
));
2038 ret
= ReadFile(hpipe
, buffer
, sizeof(buffer
), &numbytes
, NULL
);
2039 todo_wine
ok(ret
, "ReadFile failed with %u\n", GetLastError());
2040 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
2042 ret
= GetNamedPipeHandleStateA(hpipe
, &state
, NULL
, NULL
, NULL
, NULL
, 0);
2043 ok(ret
, "GetNamedPipeHandleState failed with %u\n", GetLastError());
2044 state
= PIPE_READMODE_MESSAGE
| PIPE_WAIT
;
2045 ret
= SetNamedPipeHandleState(hpipe
, &state
, NULL
, NULL
);
2046 ok(ret
, "SetNamedPipeHandleState failed with %u\n", GetLastError());
2048 SetLastError(0xdeadbeef);
2049 ret
= ReadFile(hpipe
, buffer
, 0, &numbytes
, NULL
);
2050 ok(!ret
, "ReadFile unexpectedly succeeded\n");
2051 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
2053 SetLastError(0xdeadbeef);
2054 ret
= WriteFile(hpipe
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
2055 ok(!ret
, "WriteFile unexpectedly succeeded\n");
2056 todo_wine
ok(GetLastError() == ERROR_NO_DATA
, "expected ERROR_NO_DATA, got %u\n", GetLastError());
2061 struct named_pipe_client_params
2063 DWORD security_flags
;
2068 #define PIPE_NAME "\\\\.\\pipe\\named_pipe_test"
2070 static DWORD CALLBACK
named_pipe_client_func(LPVOID p
)
2072 struct named_pipe_client_params
*params
= p
;
2075 const char message
[] = "Test";
2076 DWORD bytes_read
, bytes_written
;
2078 TOKEN_PRIVILEGES
*Privileges
= NULL
;
2084 /* modify the token so we can tell if the pipe impersonation
2085 * token reverts to the process token */
2086 ret
= AdjustTokenPrivileges(params
->token
, TRUE
, NULL
, 0, NULL
, NULL
);
2087 ok(ret
, "AdjustTokenPrivileges failed with error %d\n", GetLastError());
2089 ret
= SetThreadToken(NULL
, params
->token
);
2090 ok(ret
, "SetThreadToken failed with error %d\n", GetLastError());
2095 HANDLE process_token
;
2097 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
|TOKEN_ADJUST_PRIVILEGES
, &process_token
);
2098 ok(ret
, "OpenProcessToken failed with error %d\n", GetLastError());
2100 ret
= GetTokenInformation(process_token
, TokenPrivileges
, NULL
, 0, &Size
);
2101 ok(!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "GetTokenInformation(TokenPrivileges) failed with %d\n", GetLastError());
2102 Privileges
= HeapAlloc(GetProcessHeap(), 0, Size
);
2103 ret
= GetTokenInformation(process_token
, TokenPrivileges
, Privileges
, Size
, &Size
);
2104 ok(ret
, "GetTokenInformation(TokenPrivileges) failed with %d\n", GetLastError());
2106 ret
= AdjustTokenPrivileges(process_token
, TRUE
, NULL
, 0, NULL
, NULL
);
2107 ok(ret
, "AdjustTokenPrivileges failed with error %d\n", GetLastError());
2109 CloseHandle(process_token
);
2112 pipe
= CreateFileA(PIPE_NAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, params
->security_flags
, NULL
);
2113 ok(pipe
!= INVALID_HANDLE_VALUE
, "CreateFile for pipe failed with error %d\n", GetLastError());
2115 ret
= WriteFile(pipe
, message
, sizeof(message
), &bytes_written
, NULL
);
2116 ok(ret
, "WriteFile failed with error %d\n", GetLastError());
2118 ret
= ReadFile(pipe
, &dummy
, sizeof(dummy
), &bytes_read
, NULL
);
2119 ok(ret
, "ReadFile failed with error %d\n", GetLastError());
2125 ret
= RevertToSelf();
2126 ok(ret
, "RevertToSelf failed with error %d\n", GetLastError());
2130 ret
= AdjustTokenPrivileges(params
->token
, TRUE
, NULL
, 0, NULL
, NULL
);
2131 ok(ret
, "AdjustTokenPrivileges failed with error %d\n", GetLastError());
2136 HANDLE process_token
;
2138 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES
, &process_token
);
2139 ok(ret
, "OpenProcessToken failed with error %d\n", GetLastError());
2141 ret
= AdjustTokenPrivileges(process_token
, FALSE
, Privileges
, 0, NULL
, NULL
);
2142 ok(ret
, "AdjustTokenPrivileges failed with error %d\n", GetLastError());
2144 HeapFree(GetProcessHeap(), 0, Privileges
);
2146 CloseHandle(process_token
);
2149 ret
= WriteFile(pipe
, message
, sizeof(message
), &bytes_written
, NULL
);
2150 ok(ret
, "WriteFile failed with error %d\n", GetLastError());
2152 ret
= ReadFile(pipe
, &dummy
, sizeof(dummy
), &bytes_read
, NULL
);
2153 ok(ret
, "ReadFile failed with error %d\n", GetLastError());
2160 static HANDLE
make_impersonation_token(DWORD Access
, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
2162 HANDLE ProcessToken
;
2163 HANDLE Token
= NULL
;
2166 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE
, &ProcessToken
);
2167 ok(ret
, "OpenProcessToken failed with error %d\n", GetLastError());
2169 ret
= pDuplicateTokenEx(ProcessToken
, Access
, NULL
, ImpersonationLevel
, TokenImpersonation
, &Token
);
2170 ok(ret
, "DuplicateToken failed with error %d\n", GetLastError());
2172 CloseHandle(ProcessToken
);
2177 static void test_ImpersonateNamedPipeClient(HANDLE hClientToken
, DWORD security_flags
, BOOL revert
, void (*test_func
)(int, HANDLE
))
2186 struct named_pipe_client_params params
;
2188 DWORD dwBytesWritten
;
2189 HANDLE hToken
= NULL
;
2190 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
;
2193 hPipeServer
= CreateNamedPipeA(PIPE_NAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_READMODE_BYTE
| PIPE_WAIT
, 1, 100, 100, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
2194 ok(hPipeServer
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with error %d\n", GetLastError());
2196 params
.security_flags
= security_flags
;
2197 params
.token
= hClientToken
;
2198 params
.revert
= revert
;
2199 hThread
= CreateThread(NULL
, 0, named_pipe_client_func
, ¶ms
, 0, &dwTid
);
2200 ok(hThread
!= NULL
, "CreateThread failed with error %d\n", GetLastError());
2202 SetLastError(0xdeadbeef);
2203 ret
= ImpersonateNamedPipeClient(hPipeServer
);
2204 error
= GetLastError();
2205 ok(ret
/* win2k3 */ || (error
== ERROR_CANNOT_IMPERSONATE
),
2206 "ImpersonateNamedPipeClient should have failed with ERROR_CANNOT_IMPERSONATE instead of %d\n", GetLastError());
2208 ret
= ConnectNamedPipe(hPipeServer
, NULL
);
2209 ok(ret
|| (GetLastError() == ERROR_PIPE_CONNECTED
), "ConnectNamedPipe failed with error %d\n", GetLastError());
2211 ret
= ReadFile(hPipeServer
, buffer
, sizeof(buffer
), &dwBytesRead
, NULL
);
2212 ok(ret
, "ReadFile failed with error %d\n", GetLastError());
2214 ret
= ImpersonateNamedPipeClient(hPipeServer
);
2215 ok(ret
, "ImpersonateNamedPipeClient failed with error %d\n", GetLastError());
2217 ret
= OpenThreadToken(GetCurrentThread(), TOKEN_QUERY
, FALSE
, &hToken
);
2218 ok(ret
, "OpenThreadToken failed with error %d\n", GetLastError());
2220 (*test_func
)(0, hToken
);
2222 ImpersonationLevel
= 0xdeadbeef; /* to avoid false positives */
2223 ret
= GetTokenInformation(hToken
, TokenImpersonationLevel
, &ImpersonationLevel
, sizeof(ImpersonationLevel
), &size
);
2224 ok(ret
, "GetTokenInformation(TokenImpersonationLevel) failed with error %d\n", GetLastError());
2225 ok(ImpersonationLevel
== SecurityImpersonation
, "ImpersonationLevel should have been SecurityImpersonation(%d) instead of %d\n", SecurityImpersonation
, ImpersonationLevel
);
2227 CloseHandle(hToken
);
2231 ret
= WriteFile(hPipeServer
, &dummy
, sizeof(dummy
), &dwBytesWritten
, NULL
);
2232 ok(ret
, "WriteFile failed with error %d\n", GetLastError());
2234 ret
= ReadFile(hPipeServer
, buffer
, sizeof(buffer
), &dwBytesRead
, NULL
);
2235 ok(ret
, "ReadFile failed with error %d\n", GetLastError());
2237 ret
= ImpersonateNamedPipeClient(hPipeServer
);
2238 ok(ret
, "ImpersonateNamedPipeClient failed with error %d\n", GetLastError());
2240 ret
= OpenThreadToken(GetCurrentThread(), TOKEN_QUERY
, FALSE
, &hToken
);
2241 ok(ret
, "OpenThreadToken failed with error %d\n", GetLastError());
2243 (*test_func
)(1, hToken
);
2245 CloseHandle(hToken
);
2249 ret
= WriteFile(hPipeServer
, &dummy
, sizeof(dummy
), &dwBytesWritten
, NULL
);
2250 ok(ret
, "WriteFile failed with error %d\n", GetLastError());
2252 WaitForSingleObject(hThread
, INFINITE
);
2254 ret
= ImpersonateNamedPipeClient(hPipeServer
);
2255 ok(ret
, "ImpersonateNamedPipeClient failed with error %d\n", GetLastError());
2259 CloseHandle(hThread
);
2260 CloseHandle(hPipeServer
);
2263 static BOOL
are_all_privileges_disabled(HANDLE hToken
)
2266 TOKEN_PRIVILEGES
*Privileges
= NULL
;
2268 BOOL all_privs_disabled
= TRUE
;
2271 ret
= GetTokenInformation(hToken
, TokenPrivileges
, NULL
, 0, &Size
);
2272 if (!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
2274 Privileges
= HeapAlloc(GetProcessHeap(), 0, Size
);
2275 ret
= GetTokenInformation(hToken
, TokenPrivileges
, Privileges
, Size
, &Size
);
2278 HeapFree(GetProcessHeap(), 0, Privileges
);
2285 for (i
= 0; i
< Privileges
->PrivilegeCount
; i
++)
2287 if (Privileges
->Privileges
[i
].Attributes
& SE_PRIVILEGE_ENABLED
)
2289 all_privs_disabled
= FALSE
;
2294 HeapFree(GetProcessHeap(), 0, Privileges
);
2296 return all_privs_disabled
;
2299 static DWORD
get_privilege_count(HANDLE hToken
)
2301 TOKEN_STATISTICS Statistics
;
2302 DWORD Size
= sizeof(Statistics
);
2305 ret
= GetTokenInformation(hToken
, TokenStatistics
, &Statistics
, Size
, &Size
);
2306 ok(ret
, "GetTokenInformation(TokenStatistics)\n");
2307 if (!ret
) return -1;
2309 return Statistics
.PrivilegeCount
;
2312 static void test_no_sqos_no_token(int call_index
, HANDLE hToken
)
2319 priv_count
= get_privilege_count(hToken
);
2321 ok(priv_count
== 0, "privilege count should have been 0 instead of %d\n", priv_count
);
2324 priv_count
= get_privilege_count(hToken
);
2325 ok(priv_count
> 0, "privilege count should now be > 0 instead of 0\n");
2326 ok(!are_all_privileges_disabled(hToken
), "impersonated token should not have been modified\n");
2329 ok(0, "shouldn't happen\n");
2333 static void test_no_sqos(int call_index
, HANDLE hToken
)
2338 ok(!are_all_privileges_disabled(hToken
), "token should be a copy of the process one\n");
2342 ok(are_all_privileges_disabled(hToken
), "impersonated token should have been modified\n");
2345 ok(0, "shouldn't happen\n");
2349 static void test_static_context(int call_index
, HANDLE hToken
)
2354 ok(!are_all_privileges_disabled(hToken
), "token should be a copy of the process one\n");
2357 ok(!are_all_privileges_disabled(hToken
), "impersonated token should not have been modified\n");
2360 ok(0, "shouldn't happen\n");
2364 static void test_dynamic_context(int call_index
, HANDLE hToken
)
2369 ok(!are_all_privileges_disabled(hToken
), "token should be a copy of the process one\n");
2373 ok(are_all_privileges_disabled(hToken
), "impersonated token should have been modified\n");
2376 ok(0, "shouldn't happen\n");
2380 static void test_dynamic_context_no_token(int call_index
, HANDLE hToken
)
2385 ok(are_all_privileges_disabled(hToken
), "token should be a copy of the process one\n");
2388 ok(!are_all_privileges_disabled(hToken
), "process token modification should have been detected and impersonation token updated\n");
2391 ok(0, "shouldn't happen\n");
2395 static void test_no_sqos_revert(int call_index
, HANDLE hToken
)
2401 priv_count
= get_privilege_count(hToken
);
2403 ok(priv_count
== 0, "privilege count should have been 0 instead of %d\n", priv_count
);
2406 priv_count
= get_privilege_count(hToken
);
2407 ok(priv_count
> 0, "privilege count should now be > 0 instead of 0\n");
2408 ok(!are_all_privileges_disabled(hToken
), "impersonated token should not have been modified\n");
2411 ok(0, "shouldn't happen\n");
2415 static void test_static_context_revert(int call_index
, HANDLE hToken
)
2421 ok(are_all_privileges_disabled(hToken
), "privileges should have been disabled\n");
2425 ok(are_all_privileges_disabled(hToken
), "impersonated token should not have been modified\n");
2428 ok(0, "shouldn't happen\n");
2432 static void test_dynamic_context_revert(int call_index
, HANDLE hToken
)
2438 ok(are_all_privileges_disabled(hToken
), "privileges should have been disabled\n");
2441 ok(!are_all_privileges_disabled(hToken
), "impersonated token should now be process token\n");
2444 ok(0, "shouldn't happen\n");
2448 static void test_impersonation(void)
2450 HANDLE hClientToken
;
2451 HANDLE hProcessToken
;
2454 if( !pDuplicateTokenEx
) {
2455 skip("DuplicateTokenEx not found\n");
2459 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
, &hProcessToken
);
2462 skip("couldn't open process token, skipping impersonation tests\n");
2466 if (!get_privilege_count(hProcessToken
) || are_all_privileges_disabled(hProcessToken
))
2468 skip("token didn't have any privileges or they were all disabled. token not suitable for impersonation tests\n");
2469 CloseHandle(hProcessToken
);
2472 CloseHandle(hProcessToken
);
2474 test_ImpersonateNamedPipeClient(NULL
, 0, FALSE
, test_no_sqos_no_token
);
2475 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2476 test_ImpersonateNamedPipeClient(hClientToken
, 0, FALSE
, test_no_sqos
);
2477 CloseHandle(hClientToken
);
2478 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2479 test_ImpersonateNamedPipeClient(hClientToken
,
2480 SECURITY_SQOS_PRESENT
| SECURITY_IMPERSONATION
, FALSE
,
2481 test_static_context
);
2482 CloseHandle(hClientToken
);
2483 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2484 test_ImpersonateNamedPipeClient(hClientToken
,
2485 SECURITY_SQOS_PRESENT
| SECURITY_CONTEXT_TRACKING
| SECURITY_IMPERSONATION
,
2486 FALSE
, test_dynamic_context
);
2487 CloseHandle(hClientToken
);
2488 test_ImpersonateNamedPipeClient(NULL
,
2489 SECURITY_SQOS_PRESENT
| SECURITY_CONTEXT_TRACKING
| SECURITY_IMPERSONATION
,
2490 FALSE
, test_dynamic_context_no_token
);
2492 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2493 test_ImpersonateNamedPipeClient(hClientToken
, 0, TRUE
, test_no_sqos_revert
);
2494 CloseHandle(hClientToken
);
2495 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2496 test_ImpersonateNamedPipeClient(hClientToken
,
2497 SECURITY_SQOS_PRESENT
| SECURITY_IMPERSONATION
, TRUE
,
2498 test_static_context_revert
);
2499 CloseHandle(hClientToken
);
2500 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2501 test_ImpersonateNamedPipeClient(hClientToken
,
2502 SECURITY_SQOS_PRESENT
| SECURITY_CONTEXT_TRACKING
| SECURITY_IMPERSONATION
,
2503 TRUE
, test_dynamic_context_revert
);
2504 CloseHandle(hClientToken
);
2507 struct overlapped_server_args
2509 HANDLE pipe_created
;
2512 static DWORD CALLBACK
overlapped_server(LPVOID arg
)
2517 struct overlapped_server_args
*a
= arg
;
2521 pipe
= CreateNamedPipeA("\\\\.\\pipe\\my pipe", FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
, PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
, 1, 0, 0, 100000, NULL
);
2522 ok(pipe
!= NULL
, "pipe NULL\n");
2524 ol
.hEvent
= CreateEventA(0, 1, 0, 0);
2525 ok(ol
.hEvent
!= NULL
, "event NULL\n");
2526 ret
= ConnectNamedPipe(pipe
, &ol
);
2527 err
= GetLastError();
2528 ok(ret
== 0, "ret %d\n", ret
);
2529 ok(err
== ERROR_IO_PENDING
, "gle %d\n", err
);
2530 SetEvent(a
->pipe_created
);
2532 ret
= WaitForSingleObjectEx(ol
.hEvent
, INFINITE
, 1);
2533 ok(ret
== WAIT_OBJECT_0
, "ret %x\n", ret
);
2535 ret
= GetOverlappedResult(pipe
, &ol
, &num
, 1);
2536 ok(ret
== 1, "ret %d\n", ret
);
2538 /* This should block */
2539 ret
= ReadFile(pipe
, buf
, sizeof(buf
), &num
, NULL
);
2540 ok(ret
== 1, "ret %d\n", ret
);
2542 DisconnectNamedPipe(pipe
);
2543 CloseHandle(ol
.hEvent
);
2548 static void test_overlapped(void)
2551 HANDLE thread
, pipe
;
2553 struct overlapped_server_args args
;
2555 args
.pipe_created
= CreateEventA(0, 1, 0, 0);
2556 thread
= CreateThread(NULL
, 0, overlapped_server
, &args
, 0, &tid
);
2558 WaitForSingleObject(args
.pipe_created
, INFINITE
);
2559 pipe
= CreateFileA("\\\\.\\pipe\\my pipe", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
2560 ok(pipe
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2562 /* Sleep to try to get the ReadFile in the server to occur before the following WriteFile */
2565 ret
= WriteFile(pipe
, "x", 1, &num
, NULL
);
2566 ok(ret
, "WriteFile failed with error %d\n", GetLastError());
2568 WaitForSingleObject(thread
, INFINITE
);
2570 CloseHandle(args
.pipe_created
);
2571 CloseHandle(thread
);
2574 static void test_overlapped_error(void)
2576 HANDLE pipe
, file
, event
;
2577 DWORD err
, numbytes
;
2578 OVERLAPPED overlapped
;
2581 event
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
2582 ok(event
!= NULL
, "CreateEventA failed with %u\n", GetLastError());
2584 pipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
2585 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
2586 1, 1024, 1024, NMPWAIT_WAIT_FOREVER
, NULL
);
2587 ok(pipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %u\n", GetLastError());
2589 memset(&overlapped
, 0, sizeof(overlapped
));
2590 overlapped
.hEvent
= event
;
2591 ret
= ConnectNamedPipe(pipe
, &overlapped
);
2592 err
= GetLastError();
2593 ok(ret
== FALSE
, "ConnectNamedPipe succeeded\n");
2594 ok(err
== ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %u\n", err
);
2596 file
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
,
2597 OPEN_EXISTING
, FILE_FLAG_OVERLAPPED
, 0);
2598 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %u\n", GetLastError());
2600 numbytes
= 0xdeadbeef;
2601 ret
= GetOverlappedResult(pipe
, &overlapped
, &numbytes
, TRUE
);
2602 ok(ret
== TRUE
, "GetOverlappedResult failed\n");
2603 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
2604 ok(overlapped
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08lx\n", overlapped
.Internal
);
2609 pipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
2610 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
2611 1, 1024, 1024, NMPWAIT_WAIT_FOREVER
, NULL
);
2612 ok(pipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %u\n", GetLastError());
2614 file
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
,
2615 OPEN_EXISTING
, FILE_FLAG_OVERLAPPED
, 0);
2616 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %u\n", GetLastError());
2618 memset(&overlapped
, 0, sizeof(overlapped
));
2619 overlapped
.hEvent
= event
;
2620 ret
= ConnectNamedPipe(pipe
, &overlapped
);
2621 err
= GetLastError();
2622 ok(ret
== FALSE
, "ConnectNamedPipe succeeded\n");
2623 ok(err
== ERROR_PIPE_CONNECTED
, "expected ERROR_PIPE_CONNECTED, got %u\n", err
);
2624 ok(overlapped
.Internal
== STATUS_PENDING
, "expected STATUS_PENDING, got %08lx\n", overlapped
.Internal
);
2632 static void test_nowait(int pipemode
)
2636 static const char obuf
[] = "Bit Bucket";
2642 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
2643 pipemode
| PIPE_NOWAIT
,
2644 /* nMaxInstances */ 1,
2645 /* nOutBufSize */ 1024,
2646 /* nInBufSize */ 1024,
2647 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2648 /* lpSecurityAttrib */ NULL
);
2649 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
2651 hFile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
2652 ok(hFile
!= INVALID_HANDLE_VALUE
, "CreateFile failed (%d)\n", GetLastError());
2654 /* don't try to do i/o if one side couldn't be opened, as it hangs */
2655 if (hFile
!= INVALID_HANDLE_VALUE
)
2657 /* send message from client to server */
2658 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile\n");
2659 ok(written
== sizeof(obuf
), "write file len\n");
2660 ok(PeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, NULL
), "Peek\n");
2661 ok(readden
== sizeof(obuf
), "got %d bytes\n", readden
);
2663 memset(ibuf
, 0, sizeof(ibuf
));
2664 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile() failed: %08x\n", GetLastError());
2665 ok(readden
== sizeof(obuf
), "got %d bytes\n", readden
);
2666 ok(memcmp(obuf
, ibuf
, sizeof(obuf
)) == 0, "content check\n");
2668 readden
= 0xdeadbeef;
2669 SetLastError(0xdeadbeef);
2670 ok(!ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile() succeeded\n");
2671 ok(readden
== 0, "got %d bytes\n", readden
);
2672 ok(GetLastError() == ERROR_NO_DATA
, "GetLastError() returned %08x, expected ERROR_NO_DATA\n", GetLastError());
2674 lpmode
= (pipemode
& PIPE_READMODE_MESSAGE
) | PIPE_NOWAIT
;
2675 ok(SetNamedPipeHandleState(hFile
, &lpmode
, NULL
, NULL
), "Change mode\n");
2677 /* send message from server to client */
2678 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile\n");
2679 ok(written
== sizeof(obuf
), "write file len\n");
2680 ok(PeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, NULL
), "Peek\n");
2681 ok(readden
== sizeof(obuf
), "got %d bytes\n", readden
);
2683 memset(ibuf
, 0, sizeof(ibuf
));
2684 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile() failed: %08x\n", GetLastError());
2685 ok(readden
== sizeof(obuf
), "got %d bytes\n", readden
);
2686 ok(memcmp(obuf
, ibuf
, sizeof(obuf
)) == 0, "content check\n");
2688 readden
= 0xdeadbeef;
2689 SetLastError(0xdeadbeef);
2690 ok(!ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile() succeeded\n");
2691 ok(readden
== 0, "got %d bytes\n", readden
);
2692 ok(GetLastError() == ERROR_NO_DATA
, "GetLastError() returned %08x, expected ERROR_NO_DATA\n", GetLastError());
2694 /* now again the bad zero byte message test */
2695 ok(WriteFile(hFile
, obuf
, 0, &written
, NULL
), "WriteFile\n");
2696 ok(written
== 0, "write file len\n");
2698 if (pipemode
!= PIPE_TYPE_BYTE
)
2700 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile() failed: %08x\n", GetLastError());
2701 ok(readden
== 0, "got %d bytes\n", readden
);
2705 SetLastError(0xdeadbeef);
2706 ok(!ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile() succeeded\n");
2707 ok(readden
== 0, "got %d bytes\n", readden
);
2708 ok(GetLastError() == ERROR_NO_DATA
, "GetLastError() returned %08x, expected ERROR_NO_DATA\n", GetLastError());
2711 readden
= 0xdeadbeef;
2712 SetLastError(0xdeadbeef);
2713 ok(!ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile() succeeded\n");
2714 ok(readden
== 0, "got %d bytes\n", readden
);
2715 ok(GetLastError() == ERROR_NO_DATA
, "GetLastError() returned %08x, expected ERROR_NO_DATA\n", GetLastError());
2717 /* and the same for the reverse direction */
2718 ok(WriteFile(hnp
, obuf
, 0, &written
, NULL
), "WriteFile\n");
2719 ok(written
== 0, "write file len\n");
2721 if (pipemode
!= PIPE_TYPE_BYTE
)
2723 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile() failed: %08x\n", GetLastError());
2724 ok(readden
== 0, "got %d bytes\n", readden
);
2728 SetLastError(0xdeadbeef);
2729 ok(!ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile() succeeded\n");
2730 ok(readden
== 0, "got %d bytes\n", readden
);
2731 ok(GetLastError() == ERROR_NO_DATA
, "GetLastError() returned %08x, expected ERROR_NO_DATA\n", GetLastError());
2734 readden
= 0xdeadbeef;
2735 SetLastError(0xdeadbeef);
2736 ok(!ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile() succeeded\n");
2737 ok(readden
== 0, "got %d bytes\n", readden
);
2738 ok(GetLastError() == ERROR_NO_DATA
, "GetLastError() returned %08x, expected ERROR_NO_DATA\n", GetLastError());
2740 ok(CloseHandle(hFile
), "CloseHandle\n");
2743 ok(CloseHandle(hnp
), "CloseHandle\n");
2747 static void test_NamedPipeHandleState(void)
2749 HANDLE server
, client
;
2751 DWORD state
, instances
, maxCollectionCount
, collectDataTimeout
;
2752 char userName
[MAX_PATH
];
2754 server
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
2755 /* dwOpenMode */ PIPE_TYPE_BYTE
| PIPE_WAIT
,
2756 /* nMaxInstances */ 1,
2757 /* nOutBufSize */ 1024,
2758 /* nInBufSize */ 1024,
2759 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2760 /* lpSecurityAttrib */ NULL
);
2761 ok(server
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2762 ret
= GetNamedPipeHandleStateA(server
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
2763 ok(ret
, "GetNamedPipeHandleState failed: %d\n", GetLastError());
2764 ret
= GetNamedPipeHandleStateA(server
, &state
, &instances
, NULL
, NULL
, NULL
,
2766 ok(ret
, "GetNamedPipeHandleState failed: %d\n", GetLastError());
2769 ok(state
== 0, "unexpected state %08x\n", state
);
2770 ok(instances
== 1, "expected 1 instances, got %d\n", instances
);
2772 /* Some parameters have no meaning, and therefore can't be retrieved,
2775 SetLastError(0xdeadbeef);
2776 ret
= GetNamedPipeHandleStateA(server
, &state
, &instances
,
2777 &maxCollectionCount
, &collectDataTimeout
, userName
,
2778 sizeof(userName
) / sizeof(userName
[0]));
2780 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2781 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2782 /* A byte-mode pipe server can't be changed to message mode. */
2783 state
= PIPE_READMODE_MESSAGE
;
2784 SetLastError(0xdeadbeef);
2785 ret
= SetNamedPipeHandleState(server
, &state
, NULL
, NULL
);
2786 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2787 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2789 client
= CreateFileA(PIPENAME
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
2790 OPEN_EXISTING
, 0, NULL
);
2791 ok(client
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2793 state
= PIPE_READMODE_BYTE
;
2794 ret
= SetNamedPipeHandleState(client
, &state
, NULL
, NULL
);
2795 ok(ret
, "SetNamedPipeHandleState failed: %d\n", GetLastError());
2796 /* A byte-mode pipe client can't be changed to message mode, either. */
2797 state
= PIPE_READMODE_MESSAGE
;
2798 SetLastError(0xdeadbeef);
2799 ret
= SetNamedPipeHandleState(server
, &state
, NULL
, NULL
);
2800 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2801 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2803 CloseHandle(client
);
2804 CloseHandle(server
);
2806 server
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
2807 /* dwOpenMode */ PIPE_TYPE_MESSAGE
| PIPE_WAIT
,
2808 /* nMaxInstances */ 1,
2809 /* nOutBufSize */ 1024,
2810 /* nInBufSize */ 1024,
2811 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2812 /* lpSecurityAttrib */ NULL
);
2813 ok(server
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2814 ret
= GetNamedPipeHandleStateA(server
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
2815 ok(ret
, "GetNamedPipeHandleState failed: %d\n", GetLastError());
2816 ret
= GetNamedPipeHandleStateA(server
, &state
, &instances
, NULL
, NULL
, NULL
,
2818 ok(ret
, "GetNamedPipeHandleState failed: %d\n", GetLastError());
2821 ok(state
== 0, "unexpected state %08x\n", state
);
2822 ok(instances
== 1, "expected 1 instances, got %d\n", instances
);
2824 /* In contrast to byte-mode pipes, a message-mode pipe server can be
2825 * changed to byte mode.
2827 state
= PIPE_READMODE_BYTE
;
2828 ret
= SetNamedPipeHandleState(server
, &state
, NULL
, NULL
);
2829 ok(ret
, "SetNamedPipeHandleState failed: %d\n", GetLastError());
2831 client
= CreateFileA(PIPENAME
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
2832 OPEN_EXISTING
, 0, NULL
);
2833 ok(client
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2835 state
= PIPE_READMODE_MESSAGE
;
2836 ret
= SetNamedPipeHandleState(client
, &state
, NULL
, NULL
);
2837 ok(ret
, "SetNamedPipeHandleState failed: %d\n", GetLastError());
2838 /* A message-mode pipe client can also be changed to byte mode.
2840 state
= PIPE_READMODE_BYTE
;
2841 ret
= SetNamedPipeHandleState(client
, &state
, NULL
, NULL
);
2842 ok(ret
, "SetNamedPipeHandleState failed: %d\n", GetLastError());
2844 CloseHandle(client
);
2845 CloseHandle(server
);
2848 static void test_readfileex_pending(void)
2850 HANDLE server
, client
, event
;
2852 DWORD err
, wait
, num_bytes
, lpmode
;
2853 OVERLAPPED overlapped
;
2854 char read_buf
[1024];
2855 char write_buf
[1024];
2856 const char long_test_string
[] = "12test3456ab";
2857 const char test_string
[] = "test";
2860 server
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
,
2861 /* dwOpenMode */ PIPE_TYPE_BYTE
| PIPE_WAIT
,
2862 /* nMaxInstances */ 1,
2863 /* nOutBufSize */ 1024,
2864 /* nInBufSize */ 1024,
2865 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2866 /* lpSecurityAttrib */ NULL
);
2867 ok(server
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2869 event
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
2870 ok(event
!= NULL
, "CreateEventA failed\n");
2872 memset(&overlapped
, 0, sizeof(overlapped
));
2873 overlapped
.hEvent
= event
;
2875 ret
= ConnectNamedPipe(server
, &overlapped
);
2876 err
= GetLastError();
2877 ok(ret
== FALSE
, "ConnectNamedPipe succeeded\n");
2878 ok(err
== ERROR_IO_PENDING
, "ConnectNamedPipe set error %i\n", err
);
2880 wait
= WaitForSingleObject(event
, 0);
2881 ok(wait
== WAIT_TIMEOUT
, "WaitForSingleObject returned %x\n", wait
);
2883 client
= CreateFileA(PIPENAME
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
2884 OPEN_EXISTING
, 0, NULL
);
2885 ok(client
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2887 wait
= WaitForSingleObject(event
, 0);
2888 ok(wait
== WAIT_OBJECT_0
, "WaitForSingleObject returned %x\n", wait
);
2890 /* Start a read that can't complete immediately. */
2891 completion_called
= 0;
2893 ret
= ReadFileEx(server
, read_buf
, sizeof(read_buf
), &overlapped
, completion_routine
);
2894 ok(ret
== TRUE
, "ReadFileEx failed, err=%i\n", GetLastError());
2895 ok(completion_called
== 0, "completion routine called before ReadFileEx returned\n");
2896 wait
= WaitForSingleObject(event
, 100);
2897 ok(wait
== WAIT_TIMEOUT
, "WaitForSingleObjectEx returned %x\n", wait
);
2898 ok(completion_called
== 0, "completion routine called before WriteFile started\n");
2900 ret
= WriteFile(client
, test_string
, strlen(test_string
), &num_bytes
, NULL
);
2901 ok(ret
== TRUE
, "WriteFile failed\n");
2902 ok(num_bytes
== strlen(test_string
), "only %i bytes written\n", num_bytes
);
2904 ok(completion_called
== 0, "completion routine called during WriteFile\n");
2906 wait
= WaitForSingleObjectEx(event
, 0, TRUE
);
2907 ok(wait
== WAIT_IO_COMPLETION
|| wait
== WAIT_OBJECT_0
, "WaitForSingleObjectEx returned %x\n", wait
);
2909 ok(completion_called
== 1, "completion not called after writing pipe\n");
2910 ok(completion_errorcode
== 0, "completion called with error %x\n", completion_errorcode
);
2911 ok(completion_num_bytes
== strlen(test_string
), "ReadFileEx returned only %d bytes\n", completion_num_bytes
);
2912 ok(completion_lpoverlapped
== &overlapped
, "completion called with wrong overlapped pointer\n");
2913 ok(!memcmp(test_string
, read_buf
, strlen(test_string
)), "ReadFileEx read wrong bytes\n");
2915 /* Make writes until the pipe is full and the write fails */
2916 memset(write_buf
, 0xaa, sizeof(write_buf
));
2917 for (i
=0; i
<256; i
++)
2919 completion_called
= 0;
2921 ret
= WriteFileEx(server
, write_buf
, sizeof(write_buf
), &overlapped
, completion_routine
);
2922 err
= GetLastError();
2924 ok(completion_called
== 0, "completion routine called during WriteFileEx\n");
2926 wait
= WaitForSingleObjectEx(event
, 0, TRUE
);
2928 if (wait
== WAIT_TIMEOUT
)
2929 /* write couldn't complete immediately, presumably the pipe is full */
2932 ok(wait
== WAIT_IO_COMPLETION
|| wait
== WAIT_OBJECT_0
, "WaitForSingleObject returned %x\n", wait
);
2934 ok(ret
== TRUE
, "WriteFileEx failed, err=%i\n", err
);
2935 ok(completion_errorcode
== 0, "completion called with error %x\n", completion_errorcode
);
2936 ok(completion_lpoverlapped
== &overlapped
, "completion called with wrong overlapped pointer\n");
2939 ok(ret
== TRUE
, "WriteFileEx failed, err=%i\n", err
);
2940 ok(completion_called
== 0, "completion routine called but wait timed out\n");
2941 ok(completion_errorcode
== 0, "completion called with error %x\n", completion_errorcode
);
2942 ok(completion_lpoverlapped
== &overlapped
, "completion called with wrong overlapped pointer\n");
2944 /* free up some space in the pipe */
2945 for (i
=0; i
<256; i
++)
2947 ret
= ReadFile(client
, read_buf
, sizeof(read_buf
), &num_bytes
, NULL
);
2948 ok(ret
== TRUE
, "ReadFile failed\n");
2950 ok(completion_called
== 0, "completion routine called during ReadFile\n");
2952 wait
= WaitForSingleObjectEx(event
, 0, TRUE
);
2953 ok(wait
== WAIT_IO_COMPLETION
|| wait
== WAIT_OBJECT_0
|| wait
== WAIT_TIMEOUT
,
2954 "WaitForSingleObject returned %x\n", wait
);
2955 if (wait
!= WAIT_TIMEOUT
) break;
2958 ok(completion_called
== 1, "completion routine not called\n");
2959 ok(completion_errorcode
== 0, "completion called with error %x\n", completion_errorcode
);
2960 ok(completion_lpoverlapped
== &overlapped
, "completion called with wrong overlapped pointer\n");
2962 num_bytes
= 0xdeadbeef;
2963 SetLastError(0xdeadbeef);
2964 ret
= ReadFile(INVALID_HANDLE_VALUE
, read_buf
, 0, &num_bytes
, NULL
);
2965 ok(!ret
, "ReadFile should fail\n");
2966 ok(GetLastError() == ERROR_INVALID_HANDLE
, "wrong error %u\n", GetLastError());
2967 ok(num_bytes
== 0, "expected 0, got %u\n", num_bytes
);
2969 S(U(overlapped
)).Offset
= 0;
2970 S(U(overlapped
)).OffsetHigh
= 0;
2971 overlapped
.Internal
= -1;
2972 overlapped
.InternalHigh
= -1;
2973 overlapped
.hEvent
= event
;
2974 num_bytes
= 0xdeadbeef;
2975 SetLastError(0xdeadbeef);
2976 ret
= ReadFile(server
, read_buf
, 0, &num_bytes
, &overlapped
);
2977 ok(!ret
, "ReadFile should fail\n");
2978 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
2979 ok(num_bytes
== 0, "bytes %u\n", num_bytes
);
2980 ok((NTSTATUS
)overlapped
.Internal
== STATUS_PENDING
, "expected STATUS_PENDING, got %#lx\n", overlapped
.Internal
);
2982 ok(overlapped
.InternalHigh
== -1, "expected -1, got %lu\n", overlapped
.InternalHigh
);
2984 wait
= WaitForSingleObject(event
, 100);
2985 ok(wait
== WAIT_TIMEOUT
, "WaitForSingleObject returned %x\n", wait
);
2987 num_bytes
= 0xdeadbeef;
2988 ret
= WriteFile(client
, test_string
, 1, &num_bytes
, NULL
);
2989 ok(ret
, "WriteFile failed\n");
2990 ok(num_bytes
== 1, "bytes %u\n", num_bytes
);
2992 wait
= WaitForSingleObject(event
, 100);
2993 ok(wait
== WAIT_OBJECT_0
, "WaitForSingleObject returned %x\n", wait
);
2995 ok(num_bytes
== 1, "bytes %u\n", num_bytes
);
2996 ok((NTSTATUS
)overlapped
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", overlapped
.Internal
);
2997 ok(overlapped
.InternalHigh
== 0, "expected 0, got %lu\n", overlapped
.InternalHigh
);
2999 /* read the pending byte and clear the pipe */
3000 num_bytes
= 0xdeadbeef;
3001 ret
= ReadFile(server
, read_buf
, 1, &num_bytes
, &overlapped
);
3002 ok(ret
, "ReadFile failed\n");
3003 ok(num_bytes
== 1, "bytes %u\n", num_bytes
);
3005 CloseHandle(client
);
3006 CloseHandle(server
);
3008 /* On Windows versions > 2000 it is not possible to add PIPE_NOWAIT to a byte-mode
3009 * PIPE after creating. Create a new pipe for the following tests. */
3010 server
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
,
3011 /* dwOpenMode */ PIPE_TYPE_BYTE
| PIPE_NOWAIT
,
3012 /* nMaxInstances */ 1,
3013 /* nOutBufSize */ 1024,
3014 /* nInBufSize */ 1024,
3015 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
3016 /* lpSecurityAttrib */ NULL
);
3017 ok(server
!= INVALID_HANDLE_VALUE
, "cf failed\n");
3019 client
= CreateFileA(PIPENAME
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
3020 OPEN_EXISTING
, 0, NULL
);
3021 ok(client
!= INVALID_HANDLE_VALUE
, "cf failed\n");
3023 memset(&overlapped
, 0, sizeof(overlapped
));
3024 overlapped
.hEvent
= event
;
3026 /* Initial check with empty pipe */
3027 memset(read_buf
, 0, sizeof(read_buf
));
3028 completion_called
= 0;
3030 ret
= ReadFileEx(server
, read_buf
, 4, &overlapped
, completion_routine
);
3031 ok(ret
== FALSE
, "ReadFileEx succeded\n");
3032 ok(completion_called
== 0, "completion routine called before ReadFileEx returned\n");
3033 ok(GetLastError() == ERROR_NO_DATA
, "expected ERROR_NO_DATA, got %d\n", GetLastError());
3034 wait
= WaitForSingleObjectEx(event
, 0, TRUE
);
3035 ok(wait
== WAIT_TIMEOUT
, "WaitForSingleObjectEx returned %x\n", wait
);
3036 ok(completion_called
== 0, "completion routine called before writing to file\n");
3038 /* Call ReadFileEx after writing content to the pipe */
3039 num_bytes
= 0xdeadbeef;
3040 ret
= WriteFile(client
, long_test_string
, strlen(long_test_string
), &num_bytes
, NULL
);
3041 ok(ret
, "WriteFile failed, err=%i\n", GetLastError());
3042 ok(num_bytes
== strlen(long_test_string
), "bytes %u\n", num_bytes
);
3044 memset(read_buf
, 0, sizeof(read_buf
));
3045 completion_called
= 0;
3047 ret
= ReadFileEx(server
, read_buf
, 4, &overlapped
, completion_routine
);
3048 ok(ret
== TRUE
, "ReadFileEx failed, err=%i\n", GetLastError());
3049 ok(completion_called
== 0, "completion routine called before ReadFileEx returned\n");
3050 wait
= WaitForSingleObjectEx(event
, 0, TRUE
);
3051 ok(wait
== WAIT_IO_COMPLETION
|| wait
== WAIT_OBJECT_0
, "WaitForSingleObjectEx returned %x\n", wait
);
3052 ok(completion_called
== 1, "completion not called after writing pipe\n");
3053 ok(completion_errorcode
== 0, "completion called with error %x\n", completion_errorcode
);
3054 ok(completion_num_bytes
== 4, "ReadFileEx returned only %d bytes\n", completion_num_bytes
);
3055 ok(completion_lpoverlapped
== &overlapped
, "completion called with wrong overlapped pointer\n");
3057 ret
= ReadFile(server
, read_buf
+ 4, sizeof(read_buf
) - 4, &num_bytes
, NULL
);
3058 ok(ret
== TRUE
, "ReadFile succeeded\n");
3059 ok(num_bytes
== strlen(long_test_string
)-4, "ReadFile returned only %d bytes\n", num_bytes
);
3060 ok(!memcmp(long_test_string
, read_buf
, strlen(long_test_string
)), "ReadFile read wrong bytes\n");
3062 /* Same again, but read as a single part */
3063 num_bytes
= 0xdeadbeef;
3064 ret
= WriteFile(client
, long_test_string
, strlen(long_test_string
), &num_bytes
, NULL
);
3065 ok(ret
, "WriteFile failed, err=%i\n", GetLastError());
3066 ok(num_bytes
== strlen(long_test_string
), "bytes %u\n", num_bytes
);
3068 memset(read_buf
, 0, sizeof(read_buf
));
3069 completion_called
= 0;
3071 ret
= ReadFileEx(server
, read_buf
, sizeof(read_buf
), &overlapped
, completion_routine
);
3072 ok(ret
== TRUE
, "ReadFileEx failed, err=%i\n", GetLastError());
3073 ok(completion_called
== 0, "completion routine called before ReadFileEx returned\n");
3074 wait
= WaitForSingleObjectEx(event
, 0, TRUE
);
3075 ok(wait
== WAIT_IO_COMPLETION
|| wait
== WAIT_OBJECT_0
, "WaitForSingleObjectEx returned %x\n", wait
);
3076 ok(completion_called
== 1, "completion not called after writing pipe\n");
3077 ok(completion_errorcode
== 0, "completion called with error %x\n", completion_errorcode
);
3078 ok(completion_num_bytes
== strlen(long_test_string
), "ReadFileEx returned only %d bytes\n", completion_num_bytes
);
3079 ok(completion_lpoverlapped
== &overlapped
, "completion called with wrong overlapped pointer\n");
3080 ok(!memcmp(long_test_string
, read_buf
, strlen(long_test_string
)), "ReadFile read wrong bytes\n");
3082 /* Check content of overlapped structure */
3083 memset(read_buf
, 0, sizeof(read_buf
));
3084 S(U(overlapped
)).Offset
= 0;
3085 S(U(overlapped
)).OffsetHigh
= 0;
3086 overlapped
.Internal
= -1;
3087 overlapped
.InternalHigh
= -1;
3088 overlapped
.hEvent
= event
;
3089 num_bytes
= 0xdeadbeef;
3090 SetLastError(0xdeadbeef);
3091 ret
= ReadFile(server
, read_buf
, 4, &num_bytes
, &overlapped
);
3092 ok(ret
== FALSE
, "ReadFile succeeded\n");
3093 ok(GetLastError() == ERROR_NO_DATA
, "expected ERROR_NO_DATA, got %d\n", GetLastError());
3094 ok(num_bytes
== 0, "bytes %u\n", num_bytes
);
3095 ok((NTSTATUS
)overlapped
.Internal
== STATUS_PENDING
, "expected STATUS_PENDING, got %#lx\n", overlapped
.Internal
);
3097 ok(overlapped
.InternalHigh
== -1, "expected -1, got %lu\n", overlapped
.InternalHigh
);
3098 wait
= WaitForSingleObject(event
, 100);
3099 ok(wait
== WAIT_TIMEOUT
, "WaitForSingleObjectEx returned %x\n", wait
);
3100 ok((NTSTATUS
)overlapped
.Internal
== STATUS_PENDING
, "expected STATUS_PENDING, got %#lx\n", overlapped
.Internal
);
3102 ok(overlapped
.InternalHigh
== -1, "expected -1, got %lu\n", overlapped
.InternalHigh
);
3104 /* Call ReadFile after writing to the pipe */
3105 num_bytes
= 0xdeadbeef;
3106 ret
= WriteFile(client
, long_test_string
, strlen(long_test_string
), &num_bytes
, NULL
);
3107 ok(ret
, "WriteFile failed, err=%i\n", GetLastError());
3108 ok(num_bytes
== strlen(long_test_string
), "bytes %u\n", num_bytes
);
3110 memset(read_buf
, 0, sizeof(read_buf
));
3111 S(U(overlapped
)).Offset
= 0;
3112 S(U(overlapped
)).OffsetHigh
= 0;
3113 overlapped
.Internal
= -1;
3114 overlapped
.InternalHigh
= -1;
3115 overlapped
.hEvent
= event
;
3116 num_bytes
= 0xdeadbeef;
3117 SetLastError(0xdeadbeef);
3118 ret
= ReadFile(server
, read_buf
, 4, &num_bytes
, &overlapped
);
3119 ok(ret
== TRUE
, "ReadFile failed, err=%i\n", GetLastError());
3120 ok(num_bytes
== 4, "bytes %u\n", num_bytes
);
3121 ok((NTSTATUS
)overlapped
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", overlapped
.Internal
);
3122 ok(overlapped
.InternalHigh
== 4, "expected 4, got %lu\n", overlapped
.InternalHigh
);
3123 wait
= WaitForSingleObject(event
, 100);
3124 ok(wait
== WAIT_IO_COMPLETION
|| wait
== WAIT_OBJECT_0
, "WaitForSingleObject returned %x\n", wait
);
3125 ok((NTSTATUS
)overlapped
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", overlapped
.Internal
);
3126 ok(overlapped
.InternalHigh
== 4, "expected 4, got %lu\n", overlapped
.InternalHigh
);
3128 ret
= ReadFile(server
, read_buf
+ 4, sizeof(read_buf
) - 4, &num_bytes
, NULL
);
3129 ok(ret
== TRUE
, "ReadFile failed\n");
3130 ok(num_bytes
== strlen(long_test_string
)-4, "ReadFile returned only %d bytes\n", num_bytes
);
3131 ok(!memcmp(long_test_string
, read_buf
, strlen(long_test_string
)), "ReadFile read wrong bytes\n");
3133 /* Same again, but read as a single part */
3134 num_bytes
= 0xdeadbeef;
3135 ret
= WriteFile(client
, long_test_string
, strlen(long_test_string
), &num_bytes
, NULL
);
3136 ok(ret
, "WriteFile failed, err=%i\n", GetLastError());
3137 ok(num_bytes
== strlen(long_test_string
), "bytes %u\n", num_bytes
);
3139 memset(read_buf
, 0, sizeof(read_buf
));
3140 S(U(overlapped
)).Offset
= 0;
3141 S(U(overlapped
)).OffsetHigh
= 0;
3142 overlapped
.Internal
= -1;
3143 overlapped
.InternalHigh
= -1;
3144 overlapped
.hEvent
= event
;
3145 num_bytes
= 0xdeadbeef;
3146 SetLastError(0xdeadbeef);
3147 ret
= ReadFile(server
, read_buf
, sizeof(read_buf
), &num_bytes
, &overlapped
);
3148 ok(ret
== TRUE
, "ReadFile failed, err=%i\n", GetLastError());
3149 ok(num_bytes
== strlen(long_test_string
), "bytes %u\n", num_bytes
);
3150 ok((NTSTATUS
)overlapped
.Internal
== 0, "expected 0, got %#lx\n", overlapped
.Internal
);
3151 ok(overlapped
.InternalHigh
== strlen(long_test_string
), "expected %u, got %lu\n", (DWORD
)strlen(long_test_string
), overlapped
.InternalHigh
);
3152 wait
= WaitForSingleObject(event
, 100);
3153 ok(wait
== WAIT_IO_COMPLETION
|| wait
== WAIT_OBJECT_0
, "WaitForSingleObject returned %x\n", wait
);
3154 ok((NTSTATUS
)overlapped
.Internal
== 0, "expected 0, got %#lx\n", overlapped
.Internal
);
3155 ok(overlapped
.InternalHigh
== strlen(long_test_string
), "expected %u, got %lu\n", (DWORD
)strlen(long_test_string
), overlapped
.InternalHigh
);
3156 ok(!memcmp(long_test_string
, read_buf
, strlen(long_test_string
)), "ReadFile read wrong bytes\n");
3158 CloseHandle(client
);
3159 CloseHandle(server
);
3161 server
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
,
3162 /* dwOpenMode */ PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
3163 /* nMaxInstances */ 1,
3164 /* nOutBufSize */ 1024,
3165 /* nInBufSize */ 1024,
3166 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
3167 /* lpSecurityAttrib */ NULL
);
3168 ok(server
!= INVALID_HANDLE_VALUE
, "cf failed\n");
3170 client
= CreateFileA(PIPENAME
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
3171 OPEN_EXISTING
, 0, NULL
);
3172 ok(client
!= INVALID_HANDLE_VALUE
, "cf failed\n");
3174 memset(&overlapped
, 0, sizeof(overlapped
));
3175 overlapped
.hEvent
= event
;
3177 /* Start a call to ReadFileEx which cannot complete immediately */
3178 memset(read_buf
, 0, sizeof(read_buf
));
3179 completion_called
= 0;
3181 ret
= ReadFileEx(server
, read_buf
, 4, &overlapped
, completion_routine
);
3182 ok(ret
== TRUE
, "ReadFileEx failed, err=%i\n", GetLastError());
3183 ok(completion_called
== 0, "completion routine called before ReadFileEx returned\n");
3184 wait
= WaitForSingleObject(event
, 100);
3185 ok(wait
== WAIT_TIMEOUT
, "WaitForSingleObject returned %x\n", wait
);
3186 ok(completion_called
== 0, "completion routine called before WriteFile started\n");
3188 ret
= WriteFile(client
, long_test_string
, strlen(long_test_string
), &num_bytes
, NULL
);
3189 ok(ret
== TRUE
, "WriteFile failed\n");
3190 ok(num_bytes
== strlen(long_test_string
), "only %i bytes written\n", num_bytes
);
3191 ok(completion_called
== 0, "completion routine called during WriteFile\n");
3192 wait
= WaitForSingleObjectEx(event
, 0, TRUE
);
3193 ok(wait
== WAIT_IO_COMPLETION
|| wait
== WAIT_OBJECT_0
, "WaitForSingleObjectEx returned %x\n", wait
);
3195 ok(completion_called
== 1, "completion not called after writing pipe\n");
3196 ok(completion_errorcode
== 0, "completion called with error %x\n", completion_errorcode
);
3197 ok(completion_num_bytes
== 4, "ReadFileEx returned only %d bytes\n", completion_num_bytes
);
3198 ok(completion_lpoverlapped
== &overlapped
, "completion called with wrong overlapped pointer\n");
3199 ok(!memcmp(long_test_string
, read_buf
, 4), "ReadFileEx read wrong bytes\n");
3201 ret
= ReadFile(server
, read_buf
+ 4, 4, &num_bytes
, NULL
);
3202 ok(ret
== FALSE
, "ReadFile succeeded\n");
3203 ok(num_bytes
== 4, "ReadFile returned only %d bytes\n", num_bytes
);
3204 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error\n");
3205 ret
= ReadFile(server
, read_buf
+ 8, sizeof(read_buf
) - 8, &num_bytes
, NULL
);
3206 ok(ret
== TRUE
, "ReadFile failed\n");
3207 ok(num_bytes
== strlen(long_test_string
)-8, "ReadFile returned only %d bytes\n", num_bytes
);
3208 ok(!memcmp(long_test_string
, read_buf
, strlen(long_test_string
)), "ReadFile read wrong bytes\n");
3210 /* Call ReadFileEx when there is already some content in the pipe */
3211 ret
= WriteFile(client
, long_test_string
, strlen(long_test_string
), &num_bytes
, NULL
);
3212 ok(ret
== TRUE
, "WriteFile failed\n");
3213 ok(num_bytes
== strlen(long_test_string
), "only %i bytes written\n", num_bytes
);
3215 memset(read_buf
, 0, sizeof(read_buf
));
3216 completion_called
= 0;
3218 ret
= ReadFileEx(server
, read_buf
, 4, &overlapped
, completion_routine
);
3219 ok(ret
== TRUE
, "ReadFileEx failed, err=%i\n", GetLastError());
3220 ok(completion_called
== 0, "completion routine called before ReadFileEx returned\n");
3221 wait
= WaitForSingleObjectEx(event
, 0, TRUE
);
3222 ok(wait
== WAIT_IO_COMPLETION
|| wait
== WAIT_OBJECT_0
, "WaitForSingleObjectEx returned %x\n", wait
);
3223 ok(completion_called
== 1, "completion not called after writing pipe\n");
3224 ok(completion_errorcode
== 0, "completion called with error %x\n", completion_errorcode
);
3225 ok(completion_num_bytes
== 4, "ReadFileEx returned only %d bytes\n", completion_num_bytes
);
3226 ok(completion_lpoverlapped
== &overlapped
, "completion called with wrong overlapped pointer\n");
3227 ok(!memcmp(long_test_string
, read_buf
, 4), "ReadFileEx read wrong bytes\n");
3229 ret
= ReadFile(server
, read_buf
+ 4, sizeof(read_buf
) - 4, &num_bytes
, NULL
);
3230 ok(ret
== TRUE
, "ReadFile failed\n");
3231 ok(num_bytes
== strlen(long_test_string
)-4, "ReadFile returned only %d bytes\n", num_bytes
);
3232 ok(!memcmp(long_test_string
, read_buf
, strlen(long_test_string
)), "ReadFile read wrong bytes\n");
3234 /* Check content of overlapped structure */
3235 memset(read_buf
, 0, sizeof(read_buf
));
3236 S(U(overlapped
)).Offset
= 0;
3237 S(U(overlapped
)).OffsetHigh
= 0;
3238 overlapped
.Internal
= -1;
3239 overlapped
.InternalHigh
= -1;
3240 overlapped
.hEvent
= event
;
3241 num_bytes
= 0xdeadbeef;
3242 SetLastError(0xdeadbeef);
3243 ret
= ReadFile(server
, read_buf
, 4, &num_bytes
, &overlapped
);
3244 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
3245 ok(num_bytes
== 0, "bytes %u\n", num_bytes
);
3246 ok((NTSTATUS
)overlapped
.Internal
== STATUS_PENDING
, "expected STATUS_PENDING, got %#lx\n", overlapped
.Internal
);
3248 ok(overlapped
.InternalHigh
== -1, "expected -1, got %lu\n", overlapped
.InternalHigh
);
3249 wait
= WaitForSingleObject(event
, 100);
3250 ok(wait
== WAIT_TIMEOUT
, "WaitForSingleObject returned %x\n", wait
);
3251 ok((NTSTATUS
)overlapped
.Internal
== STATUS_PENDING
, "expected STATUS_PENDING, got %#lx\n", overlapped
.Internal
);
3253 num_bytes
= 0xdeadbeef;
3254 ret
= WriteFile(client
, long_test_string
, strlen(long_test_string
), &num_bytes
, NULL
);
3255 ok(ret
, "WriteFile failed\n");
3256 ok(num_bytes
== strlen(long_test_string
), "bytes %u\n", num_bytes
);
3257 wait
= WaitForSingleObject(event
, 100);
3258 ok(wait
== WAIT_OBJECT_0
, "WaitForSingleObject returned %x\n", wait
);
3259 ok(num_bytes
== strlen(long_test_string
), "bytes %u\n", num_bytes
);
3260 ok((NTSTATUS
)overlapped
.Internal
== STATUS_BUFFER_OVERFLOW
, "expected STATUS_BUFFER_OVERFLOW, got %#lx\n", overlapped
.Internal
);
3261 ok(overlapped
.InternalHigh
== 4, "expected 4, got %lu\n", overlapped
.InternalHigh
);
3263 ret
= ReadFile(server
, read_buf
+ 4, sizeof(read_buf
) - 4, &num_bytes
, NULL
);
3264 ok(ret
== TRUE
, "ReadFile failed\n");
3265 ok(num_bytes
== strlen(long_test_string
)-4, "ReadFile returned only %d bytes\n", num_bytes
);
3266 ok(!memcmp(long_test_string
, read_buf
, strlen(long_test_string
)), "ReadFile read wrong bytes\n");
3268 /* Call ReadFile when there is already some content in the pipe */
3269 num_bytes
= 0xdeadbeef;
3270 ret
= WriteFile(client
, long_test_string
, strlen(long_test_string
), &num_bytes
, NULL
);
3271 ok(ret
, "WriteFile failed\n");
3272 ok(num_bytes
== strlen(long_test_string
), "bytes %u\n", num_bytes
);
3274 memset(read_buf
, 0, sizeof(read_buf
));
3275 S(U(overlapped
)).Offset
= 0;
3276 S(U(overlapped
)).OffsetHigh
= 0;
3277 overlapped
.Internal
= -1;
3278 overlapped
.InternalHigh
= -1;
3279 overlapped
.hEvent
= event
;
3280 num_bytes
= 0xdeadbeef;
3281 SetLastError(0xdeadbeef);
3282 ret
= ReadFile(server
, read_buf
, 4, &num_bytes
, &overlapped
);
3283 ok(ret
== FALSE
, "ReadFile succeeded\n");
3284 ok(GetLastError() == ERROR_MORE_DATA
, "expected ERROR_MORE_DATA, got %d\n", GetLastError());
3286 ok(num_bytes
== 0, "ReadFile returned %d bytes\n", num_bytes
);
3287 wait
= WaitForSingleObjectEx(event
, 0, TRUE
);
3288 ok(wait
== WAIT_OBJECT_0
, "WaitForSingleObjectEx returned %x\n", wait
);
3290 ok(num_bytes
== 0, "bytes %u\n", num_bytes
);
3291 ok((NTSTATUS
)overlapped
.Internal
== STATUS_BUFFER_OVERFLOW
, "expected STATUS_BUFFER_OVERFLOW, got %#lx\n", overlapped
.Internal
);
3292 ok(overlapped
.InternalHigh
== 4, "expected 4, got %lu\n", overlapped
.InternalHigh
);
3294 ret
= ReadFile(server
, read_buf
+ 4, sizeof(read_buf
) - 4, &num_bytes
, NULL
);
3295 ok(ret
== TRUE
, "ReadFile failed\n");
3296 ok(num_bytes
== strlen(long_test_string
)-4, "ReadFile returned only %d bytes\n", num_bytes
);
3297 ok(!memcmp(long_test_string
, read_buf
, strlen(long_test_string
)), "ReadFile read wrong bytes\n");
3299 /* Tests for PIPE_NOWAIT in message mode */
3300 lpmode
= PIPE_READMODE_MESSAGE
| PIPE_NOWAIT
;
3301 ok(SetNamedPipeHandleState(server
, &lpmode
, NULL
, NULL
), "Change mode\n");
3303 /* Initial check with empty pipe */
3304 memset(read_buf
, 0, sizeof(read_buf
));
3305 completion_called
= 0;
3307 ret
= ReadFileEx(server
, read_buf
, 4, &overlapped
, completion_routine
);
3308 ok(ret
== FALSE
, "ReadFileEx succeded\n");
3309 ok(completion_called
== 0, "completion routine called before ReadFileEx returned\n");
3310 ok(GetLastError() == ERROR_NO_DATA
, "expected ERROR_NO_DATA, got %d\n", GetLastError());
3311 wait
= WaitForSingleObjectEx(event
, 0, TRUE
);
3312 ok(wait
== WAIT_TIMEOUT
, "WaitForSingleObjectEx returned %x\n", wait
);
3313 ok(completion_called
== 0, "completion routine called before writing to file\n");
3315 /* Call ReadFileEx after writing content to the pipe */
3316 num_bytes
= 0xdeadbeef;
3317 ret
= WriteFile(client
, long_test_string
, strlen(long_test_string
), &num_bytes
, NULL
);
3318 ok(ret
, "WriteFile failed, err=%i\n", GetLastError());
3319 ok(num_bytes
== strlen(long_test_string
), "bytes %u\n", num_bytes
);
3321 memset(read_buf
, 0, sizeof(read_buf
));
3322 completion_called
= 0;
3324 ret
= ReadFileEx(server
, read_buf
, 4, &overlapped
, completion_routine
);
3325 ok(ret
== TRUE
, "ReadFileEx failed, err=%i\n", GetLastError());
3326 ok(completion_called
== 0, "completion routine called before ReadFileEx returned\n");
3327 wait
= WaitForSingleObjectEx(event
, 0, TRUE
);
3328 ok(wait
== WAIT_IO_COMPLETION
|| wait
== WAIT_OBJECT_0
, "WaitForSingleObjectEx returned %x\n", wait
);
3329 ok(completion_called
== 1, "completion not called after writing pipe\n");
3330 ok(completion_errorcode
== 0, "completion called with error %x\n", completion_errorcode
);
3331 ok(completion_num_bytes
== 4, "ReadFileEx returned only %d bytes\n", completion_num_bytes
);
3332 ok(completion_lpoverlapped
== &overlapped
, "completion called with wrong overlapped pointer\n");
3334 ret
= ReadFile(server
, read_buf
+ 4, sizeof(read_buf
) - 4, &num_bytes
, NULL
);
3335 ok(ret
== TRUE
, "ReadFile succeeded\n");
3336 ok(num_bytes
== strlen(long_test_string
)-4, "ReadFile returned only %d bytes\n", num_bytes
);
3337 ok(!memcmp(long_test_string
, read_buf
, strlen(long_test_string
)), "ReadFile read wrong bytes\n");
3339 /* Same again, but read as a single part */
3340 num_bytes
= 0xdeadbeef;
3341 ret
= WriteFile(client
, long_test_string
, strlen(long_test_string
), &num_bytes
, NULL
);
3342 ok(ret
, "WriteFile failed, err=%i\n", GetLastError());
3343 ok(num_bytes
== strlen(long_test_string
), "bytes %u\n", num_bytes
);
3345 memset(read_buf
, 0, sizeof(read_buf
));
3346 completion_called
= 0;
3348 ret
= ReadFileEx(server
, read_buf
, sizeof(read_buf
), &overlapped
, completion_routine
);
3349 ok(ret
== TRUE
, "ReadFileEx failed, err=%i\n", GetLastError());
3350 ok(completion_called
== 0, "completion routine called before ReadFileEx returned\n");
3351 wait
= WaitForSingleObjectEx(event
, 0, TRUE
);
3352 ok(wait
== WAIT_IO_COMPLETION
|| wait
== WAIT_OBJECT_0
, "WaitForSingleObjectEx returned %x\n", wait
);
3353 ok(completion_called
== 1, "completion not called after writing pipe\n");
3354 ok(completion_errorcode
== 0, "completion called with error %x\n", completion_errorcode
);
3355 ok(completion_num_bytes
== strlen(long_test_string
), "ReadFileEx returned only %d bytes\n", completion_num_bytes
);
3356 ok(completion_lpoverlapped
== &overlapped
, "completion called with wrong overlapped pointer\n");
3357 ok(!memcmp(long_test_string
, read_buf
, strlen(long_test_string
)), "ReadFile read wrong bytes\n");
3359 /* Check content of overlapped structure */
3360 memset(read_buf
, 0, sizeof(read_buf
));
3361 S(U(overlapped
)).Offset
= 0;
3362 S(U(overlapped
)).OffsetHigh
= 0;
3363 overlapped
.Internal
= -1;
3364 overlapped
.InternalHigh
= -1;
3365 overlapped
.hEvent
= event
;
3366 num_bytes
= 0xdeadbeef;
3367 SetLastError(0xdeadbeef);
3368 ret
= ReadFile(server
, read_buf
, 4, &num_bytes
, &overlapped
);
3369 ok(ret
== FALSE
, "ReadFile succeeded\n");
3370 ok(GetLastError() == ERROR_NO_DATA
, "expected ERROR_NO_DATA, got %d\n", GetLastError());
3371 ok(num_bytes
== 0, "bytes %u\n", num_bytes
);
3372 ok((NTSTATUS
)overlapped
.Internal
== STATUS_PENDING
, "expected STATUS_PENDING, got %#lx\n", overlapped
.Internal
);
3374 ok(overlapped
.InternalHigh
== -1, "expected -1, got %lu\n", overlapped
.InternalHigh
);
3375 wait
= WaitForSingleObject(event
, 100);
3376 ok(wait
== WAIT_TIMEOUT
, "WaitForSingleObjectEx returned %x\n", wait
);
3377 ok((NTSTATUS
)overlapped
.Internal
== STATUS_PENDING
, "expected STATUS_PENDING, got %#lx\n", overlapped
.Internal
);
3379 ok(overlapped
.InternalHigh
== -1, "expected -1, got %lu\n", overlapped
.InternalHigh
);
3381 /* Call ReadFile after writing to the pipe */
3382 num_bytes
= 0xdeadbeef;
3383 ret
= WriteFile(client
, long_test_string
, strlen(long_test_string
), &num_bytes
, NULL
);
3384 ok(ret
, "WriteFile failed, err=%i\n", GetLastError());
3385 ok(num_bytes
== strlen(long_test_string
), "bytes %u\n", num_bytes
);
3387 memset(read_buf
, 0, sizeof(read_buf
));
3388 S(U(overlapped
)).Offset
= 0;
3389 S(U(overlapped
)).OffsetHigh
= 0;
3390 overlapped
.Internal
= -1;
3391 overlapped
.InternalHigh
= -1;
3392 overlapped
.hEvent
= event
;
3393 num_bytes
= 0xdeadbeef;
3394 SetLastError(0xdeadbeef);
3395 ret
= ReadFile(server
, read_buf
, 4, &num_bytes
, &overlapped
);
3396 ok(ret
== FALSE
, "ReadFile succeeded\n");
3397 ok(GetLastError() == ERROR_MORE_DATA
, "expected ERROR_MORE_DATA, got %d\n", GetLastError());
3399 ok(num_bytes
== 0, "bytes %u\n", num_bytes
);
3400 ok((NTSTATUS
)overlapped
.Internal
== STATUS_BUFFER_OVERFLOW
, "expected STATUS_BUFFER_OVERFLOW, got %#lx\n", overlapped
.Internal
);
3401 ok(overlapped
.InternalHigh
== 4, "expected 4, got %lu\n", overlapped
.InternalHigh
);
3402 wait
= WaitForSingleObject(event
, 100);
3403 ok(wait
== WAIT_IO_COMPLETION
|| wait
== WAIT_OBJECT_0
, "WaitForSingleObject returned %x\n", wait
);
3404 ok((NTSTATUS
)overlapped
.Internal
== STATUS_BUFFER_OVERFLOW
, "expected STATUS_BUFFER_OVERFLOW, got %#lx\n", overlapped
.Internal
);
3405 ok(overlapped
.InternalHigh
== 4, "expected 4, got %lu\n", overlapped
.InternalHigh
);
3407 ret
= ReadFile(server
, read_buf
+ 4, sizeof(read_buf
) - 4, &num_bytes
, NULL
);
3408 ok(ret
== TRUE
, "ReadFile failed\n");
3409 ok(num_bytes
== strlen(long_test_string
)-4, "ReadFile returned only %d bytes\n", num_bytes
);
3410 ok(!memcmp(long_test_string
, read_buf
, strlen(long_test_string
)), "ReadFile read wrong bytes\n");
3412 /* Same again, but read as a single part */
3413 num_bytes
= 0xdeadbeef;
3414 ret
= WriteFile(client
, long_test_string
, strlen(long_test_string
), &num_bytes
, NULL
);
3415 ok(ret
, "WriteFile failed, err=%i\n", GetLastError());
3416 ok(num_bytes
== strlen(long_test_string
), "bytes %u\n", num_bytes
);
3418 memset(read_buf
, 0, sizeof(read_buf
));
3419 S(U(overlapped
)).Offset
= 0;
3420 S(U(overlapped
)).OffsetHigh
= 0;
3421 overlapped
.Internal
= -1;
3422 overlapped
.InternalHigh
= -1;
3423 overlapped
.hEvent
= event
;
3424 num_bytes
= 0xdeadbeef;
3425 SetLastError(0xdeadbeef);
3426 ret
= ReadFile(server
, read_buf
, sizeof(read_buf
), &num_bytes
, &overlapped
);
3427 ok(ret
== TRUE
, "ReadFile failed, err=%i\n", GetLastError());
3428 ok(num_bytes
== strlen(long_test_string
), "bytes %u\n", num_bytes
);
3429 ok((NTSTATUS
)overlapped
.Internal
== 0, "expected 0, got %#lx\n", overlapped
.Internal
);
3430 ok(overlapped
.InternalHigh
== strlen(long_test_string
), "expected %u, got %lu\n", (DWORD
)strlen(long_test_string
), overlapped
.InternalHigh
);
3431 wait
= WaitForSingleObject(event
, 100);
3432 ok(wait
== WAIT_IO_COMPLETION
|| wait
== WAIT_OBJECT_0
, "WaitForSingleObject returned %x\n", wait
);
3433 ok((NTSTATUS
)overlapped
.Internal
== 0, "expected 0, got %#lx\n", overlapped
.Internal
);
3434 ok(overlapped
.InternalHigh
== strlen(long_test_string
), "expected %u, got %lu\n", (DWORD
)strlen(long_test_string
), overlapped
.InternalHigh
);
3435 ok(!memcmp(long_test_string
, read_buf
, strlen(long_test_string
)), "ReadFile read wrong bytes\n");
3437 CloseHandle(client
);
3438 CloseHandle(server
);
3446 hmod
= GetModuleHandleA("advapi32.dll");
3447 pDuplicateTokenEx
= (void *) GetProcAddress(hmod
, "DuplicateTokenEx");
3448 hmod
= GetModuleHandleA("kernel32.dll");
3449 pQueueUserAPC
= (void *) GetProcAddress(hmod
, "QueueUserAPC");
3451 if (test_DisconnectNamedPipe())
3453 test_CreateNamedPipe_instances_must_match();
3455 test_CreateNamedPipe(PIPE_TYPE_BYTE
);
3456 test_CreateNamedPipe(PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
);
3459 test_impersonation();
3461 test_overlapped_error();
3462 test_nowait(PIPE_TYPE_BYTE
);
3463 test_nowait(PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
);
3464 test_NamedPipeHandleState();
3465 test_readfileex_pending();