2 * Unit tests for named pipe functions in Wine
4 * Copyright (c) 2002 Dan Kegel
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #define WIN32_NO_STATUS
30 #include "wine/test.h"
32 #define PIPENAME "\\\\.\\PiPe\\tests_pipe.c"
34 #define NB_SERVER_LOOPS 8
36 static HANDLE alarm_event
;
37 static BOOL (WINAPI
*pDuplicateTokenEx
)(HANDLE
,DWORD
,LPSECURITY_ATTRIBUTES
,
38 SECURITY_IMPERSONATION_LEVEL
,TOKEN_TYPE
,PHANDLE
);
39 static BOOL (WINAPI
*pCancelIoEx
)(HANDLE handle
, LPOVERLAPPED lpOverlapped
);
40 static BOOL (WINAPI
*pGetNamedPipeClientProcessId
)(HANDLE
,ULONG
*);
41 static BOOL (WINAPI
*pGetNamedPipeServerProcessId
)(HANDLE
,ULONG
*);
42 static BOOL (WINAPI
*pGetNamedPipeClientSessionId
)(HANDLE
,ULONG
*);
43 static BOOL (WINAPI
*pGetNamedPipeServerSessionId
)(HANDLE
,ULONG
*);
44 static BOOL (WINAPI
*pGetOverlappedResultEx
)(HANDLE
,OVERLAPPED
*,DWORD
*,DWORD
,BOOL
);
46 static BOOL user_apc_ran
;
47 static void CALLBACK
user_apc(ULONG_PTR param
)
60 ULONG_PTR returnValue
;
66 static DWORD CALLBACK
rpcThreadMain(LPVOID arg
)
68 struct rpcThreadArgs
*rpcargs
= (struct rpcThreadArgs
*)arg
;
69 if (winetest_debug
> 1) trace("rpcThreadMain starting\n");
70 SetLastError( rpcargs
->lastError
);
75 rpcargs
->returnValue
= (ULONG_PTR
)ReadFile( (HANDLE
)rpcargs
->args
[0], /* hFile */
76 (LPVOID
)rpcargs
->args
[1], /* buffer */
77 (DWORD
)rpcargs
->args
[2], /* bytesToRead */
78 (LPDWORD
)rpcargs
->args
[3], /* bytesRead */
79 (LPOVERLAPPED
)rpcargs
->args
[4] ); /* overlapped */
83 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
84 rpcargs
->returnValue
= 0;
88 rpcargs
->lastError
= GetLastError();
89 if (winetest_debug
> 1) trace("rpcThreadMain returning\n");
93 /* Runs ReadFile(...) from a different thread */
94 static BOOL
RpcReadFile(HANDLE hFile
, LPVOID buffer
, DWORD bytesToRead
, LPDWORD bytesRead
, LPOVERLAPPED overlapped
)
96 struct rpcThreadArgs rpcargs
;
100 rpcargs
.returnValue
= 0;
101 rpcargs
.lastError
= GetLastError();
102 rpcargs
.op
= RPC_READFILE
;
103 rpcargs
.args
[0] = (ULONG_PTR
)hFile
;
104 rpcargs
.args
[1] = (ULONG_PTR
)buffer
;
105 rpcargs
.args
[2] = (ULONG_PTR
)bytesToRead
;
106 rpcargs
.args
[3] = (ULONG_PTR
)bytesRead
;
107 rpcargs
.args
[4] = (ULONG_PTR
)overlapped
;
109 thread
= CreateThread(NULL
, 0, rpcThreadMain
, (void *)&rpcargs
, 0, &threadId
);
110 ok(thread
!= NULL
, "CreateThread failed. %d\n", GetLastError());
111 ret
= WaitForSingleObject(thread
, INFINITE
);
112 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject failed with %d.\n", GetLastError());
115 SetLastError(rpcargs
.lastError
);
116 return (BOOL
)rpcargs
.returnValue
;
119 #define test_not_signaled(h) _test_not_signaled(__LINE__,h)
120 static void _test_not_signaled(unsigned line
, HANDLE handle
)
122 DWORD res
= WaitForSingleObject(handle
, 0);
123 ok_(__FILE__
,line
)(res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %u (%u)\n", res
, GetLastError());
126 #define test_signaled(h) _test_signaled(__LINE__,h)
127 static void _test_signaled(unsigned line
, HANDLE handle
)
129 DWORD res
= WaitForSingleObject(handle
, 0);
130 ok_(__FILE__
,line
)(res
== WAIT_OBJECT_0
, "WaitForSingleObject returned %u\n", res
);
133 #define test_pipe_info(a,b,c,d,e) _test_pipe_info(__LINE__,a,b,c,d,e)
134 static void _test_pipe_info(unsigned line
, HANDLE pipe
, DWORD ex_flags
, DWORD ex_out_buf_size
, DWORD ex_in_buf_size
, DWORD ex_max_instances
)
136 DWORD flags
= 0xdeadbeef, out_buf_size
= 0xdeadbeef, in_buf_size
= 0xdeadbeef, max_instances
= 0xdeadbeef;
139 res
= GetNamedPipeInfo(pipe
, &flags
, &out_buf_size
, &in_buf_size
, &max_instances
);
140 ok_(__FILE__
,line
)(res
, "GetNamedPipeInfo failed: %x\n", res
);
141 ok_(__FILE__
,line
)(flags
== ex_flags
, "flags = %x, expected %x\n", flags
, ex_flags
);
142 ok_(__FILE__
,line
)(out_buf_size
== ex_out_buf_size
, "out_buf_size = %x, expected %u\n", out_buf_size
, ex_out_buf_size
);
143 ok_(__FILE__
,line
)(in_buf_size
== ex_in_buf_size
, "in_buf_size = %x, expected %u\n", in_buf_size
, ex_in_buf_size
);
144 ok_(__FILE__
,line
)(max_instances
== ex_max_instances
, "max_instances = %x, expected %u\n", max_instances
, ex_max_instances
);
147 #define test_file_access(a,b) _test_file_access(__LINE__,a,b)
148 static void _test_file_access(unsigned line
, HANDLE handle
, DWORD expected_access
)
150 FILE_ACCESS_INFORMATION info
;
154 memset(&info
, 0x11, sizeof(info
));
155 status
= NtQueryInformationFile(handle
, &io
, &info
, sizeof(info
), FileAccessInformation
);
156 ok_(__FILE__
,line
)(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08x\n", status
);
157 ok_(__FILE__
,line
)(info
.AccessFlags
== expected_access
, "got access %08x expected %08x\n",
158 info
.AccessFlags
, expected_access
);
161 static void test_CreateNamedPipe(int pipemode
)
165 static const char obuf
[] = "Bit Bucket";
166 static const char obuf2
[] = "More bits";
167 char ibuf
[32], *pbuf
;
175 if (pipemode
== PIPE_TYPE_BYTE
)
176 trace("test_CreateNamedPipe starting in byte mode\n");
178 trace("test_CreateNamedPipe starting in message mode\n");
180 /* Wait for nonexistent pipe */
181 ret
= WaitNamedPipeA(PIPENAME
, 2000);
182 ok(ret
== 0, "WaitNamedPipe returned %d for nonexistent pipe\n", ret
);
183 ok(GetLastError() == ERROR_FILE_NOT_FOUND
, "wrong error %u\n", GetLastError());
185 /* Bad parameter checks */
186 hnp
= CreateNamedPipeA("not a named pipe", PIPE_ACCESS_DUPLEX
, pipemode
| PIPE_WAIT
,
187 /* nMaxInstances */ 1,
188 /* nOutBufSize */ 1024,
189 /* nInBufSize */ 1024,
190 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
191 /* lpSecurityAttrib */ NULL
);
192 ok(hnp
== INVALID_HANDLE_VALUE
&& GetLastError() == ERROR_INVALID_NAME
,
193 "CreateNamedPipe should fail if name doesn't start with \\\\.\\pipe\n");
195 if (pipemode
== PIPE_TYPE_BYTE
)
197 /* Bad parameter checks */
198 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_READMODE_MESSAGE
,
199 /* nMaxInstances */ 1,
200 /* nOutBufSize */ 1024,
201 /* nInBufSize */ 1024,
202 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
203 /* lpSecurityAttrib */ NULL
);
204 ok(hnp
== INVALID_HANDLE_VALUE
&& GetLastError() == ERROR_INVALID_PARAMETER
,
205 "CreateNamedPipe should fail with PIPE_TYPE_BYTE | PIPE_READMODE_MESSAGE\n");
208 hnp
= CreateNamedPipeA(NULL
,
209 PIPE_ACCESS_DUPLEX
, pipemode
| PIPE_WAIT
,
210 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
211 ok(hnp
== INVALID_HANDLE_VALUE
&& GetLastError() == ERROR_PATH_NOT_FOUND
,
212 "CreateNamedPipe should fail if name is NULL\n");
214 hFile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
215 ok(hFile
== INVALID_HANDLE_VALUE
216 && GetLastError() == ERROR_FILE_NOT_FOUND
,
217 "connecting to nonexistent named pipe should fail with ERROR_FILE_NOT_FOUND\n");
219 /* Functional checks */
221 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, pipemode
| PIPE_WAIT
,
222 /* nMaxInstances */ 1,
223 /* nOutBufSize */ 1024,
224 /* nInBufSize */ 1024,
225 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
226 /* lpSecurityAttrib */ NULL
);
227 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
230 test_file_access(hnp
, SYNCHRONIZE
| READ_CONTROL
| FILE_WRITE_ATTRIBUTES
231 | FILE_READ_ATTRIBUTES
| FILE_WRITE_PROPERTIES
| FILE_READ_PROPERTIES
232 | FILE_APPEND_DATA
| FILE_WRITE_DATA
| FILE_READ_DATA
);
234 ret
= PeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, NULL
);
235 ok(!ret
&& GetLastError() == ERROR_BAD_PIPE
, "PeekNamedPipe returned %x (%u)\n",
236 ret
, GetLastError());
238 ret
= WaitNamedPipeA(PIPENAME
, 2000);
239 ok(ret
, "WaitNamedPipe failed (%d)\n", GetLastError());
241 hFile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
242 ok(hFile
!= INVALID_HANDLE_VALUE
, "CreateFile failed (%d)\n", GetLastError());
244 ok(!WaitNamedPipeA(PIPENAME
, 100), "WaitNamedPipe succeeded\n");
246 ok(GetLastError() == ERROR_SEM_TIMEOUT
, "wrong error %u\n", GetLastError());
248 /* Test ConnectNamedPipe() in both directions */
249 ok(!ConnectNamedPipe(hnp
, NULL
), "ConnectNamedPipe(server) succeeded\n");
250 ok(GetLastError() == ERROR_PIPE_CONNECTED
, "expected ERROR_PIPE_CONNECTED, got %u\n", GetLastError());
251 ok(!ConnectNamedPipe(hFile
, NULL
), "ConnectNamedPipe(client) succeeded\n");
252 ok(GetLastError() == ERROR_INVALID_FUNCTION
, "expected ERROR_INVALID_FUNCTION, got %u\n", GetLastError());
254 /* don't try to do i/o if one side couldn't be opened, as it hangs */
255 if (hFile
!= INVALID_HANDLE_VALUE
) {
258 /* Make sure we can read and write a few bytes in both directions */
259 memset(ibuf
, 0, sizeof(ibuf
));
260 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile\n");
261 ok(written
== sizeof(obuf
), "write file len\n");
262 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
263 ok(readden
== sizeof(obuf
), "read got %d bytes\n", readden
);
264 ok(memcmp(obuf
, ibuf
, written
) == 0, "content check\n");
266 memset(ibuf
, 0, sizeof(ibuf
));
267 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile\n");
268 ok(written
== sizeof(obuf2
), "write file len\n");
269 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
270 ok(readden
== sizeof(obuf2
), "read got %d bytes\n", readden
);
271 ok(memcmp(obuf2
, ibuf
, written
) == 0, "content check\n");
273 /* Now the same again, but with an additional call to PeekNamedPipe */
274 memset(ibuf
, 0, sizeof(ibuf
));
275 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile\n");
276 ok(written
== sizeof(obuf
), "write file len 1\n");
277 ok(PeekNamedPipe(hFile
, NULL
, 0, NULL
, &avail
, &left
), "Peek\n");
278 ok(avail
== sizeof(obuf
), "peek 1 got %d bytes\n", avail
);
279 if (pipemode
== PIPE_TYPE_BYTE
)
280 ok(left
== 0, "peek 1 got %d bytes left\n", left
);
282 ok(left
== sizeof(obuf
), "peek 1 got %d bytes left\n", left
);
283 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
284 ok(readden
== sizeof(obuf
), "read 1 got %d bytes\n", readden
);
285 ok(memcmp(obuf
, ibuf
, written
) == 0, "content 1 check\n");
287 memset(ibuf
, 0, sizeof(ibuf
));
288 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile\n");
289 ok(written
== sizeof(obuf2
), "write file len 2\n");
290 ok(PeekNamedPipe(hnp
, NULL
, 0, NULL
, &avail
, &left
), "Peek\n");
291 ok(avail
== sizeof(obuf2
), "peek 2 got %d bytes\n", avail
);
292 if (pipemode
== PIPE_TYPE_BYTE
)
293 ok(left
== 0, "peek 2 got %d bytes left\n", left
);
295 ok(left
== sizeof(obuf2
), "peek 2 got %d bytes left\n", left
);
296 ok(PeekNamedPipe(hnp
, (LPVOID
)1, 0, NULL
, &avail
, &left
), "Peek\n");
297 ok(avail
== sizeof(obuf2
), "peek 2 got %d bytes\n", avail
);
298 if (pipemode
== PIPE_TYPE_BYTE
)
299 ok(left
== 0, "peek 2 got %d bytes left\n", left
);
301 ok(left
== sizeof(obuf2
), "peek 2 got %d bytes left\n", left
);
302 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
303 ok(readden
== sizeof(obuf2
), "read 2 got %d bytes\n", readden
);
304 ok(memcmp(obuf2
, ibuf
, written
) == 0, "content 2 check\n");
306 /* Test how ReadFile behaves when the buffer is not big enough for the whole message */
307 memset(ibuf
, 0, sizeof(ibuf
));
308 ok(WriteFile(hnp
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile\n");
309 ok(written
== sizeof(obuf2
), "write file len\n");
310 ok(PeekNamedPipe(hFile
, ibuf
, 4, &readden
, &avail
, &left
), "Peek\n");
311 ok(readden
== 4, "peek got %d bytes\n", readden
);
312 ok(avail
== sizeof(obuf2
), "peek got %d bytes available\n", avail
);
313 if (pipemode
== PIPE_TYPE_BYTE
)
314 ok(left
== -4, "peek got %d bytes left\n", left
);
316 ok(left
== sizeof(obuf2
)-4, "peek got %d bytes left\n", left
);
317 ok(ReadFile(hFile
, ibuf
, 4, &readden
, NULL
), "ReadFile\n");
318 ok(readden
== 4, "read got %d bytes\n", readden
);
319 ok(ReadFile(hFile
, ibuf
+ 4, sizeof(ibuf
) - 4, &readden
, NULL
), "ReadFile\n");
320 ok(readden
== sizeof(obuf2
) - 4, "read got %d bytes\n", readden
);
321 ok(memcmp(obuf2
, ibuf
, written
) == 0, "content check\n");
323 memset(ibuf
, 0, sizeof(ibuf
));
324 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile\n");
325 ok(written
== sizeof(obuf
), "write file len\n");
326 ok(PeekNamedPipe(hnp
, ibuf
, 4, &readden
, &avail
, &left
), "Peek\n");
327 ok(readden
== 4, "peek got %d bytes\n", readden
);
328 ok(avail
== sizeof(obuf
), "peek got %d bytes available\n", avail
);
329 if (pipemode
== PIPE_TYPE_BYTE
)
331 ok(left
== -4, "peek got %d bytes left\n", left
);
332 ok(ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile\n");
336 ok(left
== sizeof(obuf
)-4, "peek got %d bytes left\n", left
);
337 SetLastError(0xdeadbeef);
338 ok(!ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile\n");
339 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error\n");
341 ok(readden
== 4, "read got %d bytes\n", readden
);
342 ok(ReadFile(hnp
, ibuf
+ 4, sizeof(ibuf
) - 4, &readden
, NULL
), "ReadFile\n");
343 ok(readden
== sizeof(obuf
) - 4, "read got %d bytes\n", readden
);
344 ok(memcmp(obuf
, ibuf
, written
) == 0, "content check\n");
346 /* Similar to above, but use a read buffer size small enough to read in three parts */
347 memset(ibuf
, 0, sizeof(ibuf
));
348 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile\n");
349 ok(written
== sizeof(obuf2
), "write file len\n");
350 if (pipemode
== PIPE_TYPE_BYTE
)
352 ok(ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile\n");
353 ok(readden
== 4, "read got %d bytes\n", readden
);
354 ok(ReadFile(hnp
, ibuf
+ 4, 4, &readden
, NULL
), "ReadFile\n");
358 SetLastError(0xdeadbeef);
359 ok(!ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile\n");
360 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error\n");
361 ok(readden
== 4, "read got %d bytes\n", readden
);
362 SetLastError(0xdeadbeef);
363 ok(!ReadFile(hnp
, ibuf
+ 4, 4, &readden
, NULL
), "ReadFile\n");
364 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error\n");
366 ok(readden
== 4, "read got %d bytes\n", readden
);
367 ok(ReadFile(hnp
, ibuf
+ 8, sizeof(ibuf
) - 8, &readden
, NULL
), "ReadFile\n");
368 ok(readden
== sizeof(obuf2
) - 8, "read got %d bytes\n", readden
);
369 ok(memcmp(obuf2
, ibuf
, written
) == 0, "content check\n");
371 /* Test reading of multiple writes */
372 memset(ibuf
, 0, sizeof(ibuf
));
373 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile3a\n");
374 ok(written
== sizeof(obuf
), "write file len 3a\n");
375 ok(WriteFile(hnp
, obuf2
, sizeof(obuf2
), &written
, NULL
), " WriteFile3b\n");
376 ok(written
== sizeof(obuf2
), "write file len 3b\n");
377 ok(PeekNamedPipe(hFile
, ibuf
, 4, &readden
, &avail
, &left
), "Peek3\n");
378 ok(readden
== 4, "peek3 got %d bytes\n", readden
);
379 if (pipemode
== PIPE_TYPE_BYTE
)
380 ok(left
== -4, "peek3 got %d bytes left\n", left
);
382 ok(left
== sizeof(obuf
)-4, "peek3 got %d bytes left\n", left
);
383 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek3 got %d bytes available\n", avail
);
384 ok(PeekNamedPipe(hFile
, ibuf
, sizeof(ibuf
), &readden
, &avail
, &left
), "Peek3\n");
385 if (pipemode
== PIPE_TYPE_BYTE
) {
386 ok(readden
== sizeof(obuf
) + sizeof(obuf2
), "peek3 got %d bytes\n", readden
);
387 ok(left
== (DWORD
) -(sizeof(obuf
) + sizeof(obuf2
)), "peek3 got %d bytes left\n", left
);
391 ok(readden
== sizeof(obuf
), "peek3 got %d bytes\n", readden
);
392 ok(left
== 0, "peek3 got %d bytes left\n", left
);
394 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek3 got %d bytes available\n", avail
);
396 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "pipe content 3a check\n");
397 if (pipemode
== PIPE_TYPE_BYTE
&& readden
>= sizeof(obuf
)+sizeof(obuf2
)) {
398 pbuf
+= sizeof(obuf
);
399 ok(memcmp(obuf2
, pbuf
, sizeof(obuf2
)) == 0, "pipe content 3b check\n");
401 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
402 ok(readden
== sizeof(obuf
) + sizeof(obuf2
), "read 3 got %d bytes\n", readden
);
404 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 3a check\n");
405 pbuf
+= sizeof(obuf
);
406 ok(memcmp(obuf2
, pbuf
, sizeof(obuf2
)) == 0, "content 3b check\n");
408 /* Multiple writes in the reverse direction */
409 memset(ibuf
, 0, sizeof(ibuf
));
410 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile4a\n");
411 ok(written
== sizeof(obuf
), "write file len 4a\n");
412 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), " WriteFile4b\n");
413 ok(written
== sizeof(obuf2
), "write file len 4b\n");
414 ok(PeekNamedPipe(hnp
, ibuf
, 4, &readden
, &avail
, &left
), "Peek3\n");
415 ok(readden
== 4, "peek3 got %d bytes\n", readden
);
416 if (pipemode
== PIPE_TYPE_BYTE
)
417 ok(left
== -4, "peek3 got %d bytes left\n", left
);
419 ok(left
== sizeof(obuf
)-4, "peek3 got %d bytes left\n", left
);
420 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek3 got %d bytes available\n", avail
);
421 ok(PeekNamedPipe(hnp
, ibuf
, sizeof(ibuf
), &readden
, &avail
, &left
), "Peek4\n");
422 if (pipemode
== PIPE_TYPE_BYTE
) {
423 ok(readden
== sizeof(obuf
) + sizeof(obuf2
), "peek4 got %d bytes\n", readden
);
424 ok(left
== (DWORD
) -(sizeof(obuf
) + sizeof(obuf2
)), "peek4 got %d bytes left\n", left
);
428 ok(readden
== sizeof(obuf
), "peek4 got %d bytes\n", readden
);
429 ok(left
== 0, "peek4 got %d bytes left\n", left
);
431 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek4 got %d bytes available\n", avail
);
433 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "pipe content 4a check\n");
434 if (pipemode
== PIPE_TYPE_BYTE
&& readden
>= sizeof(obuf
)+sizeof(obuf2
)) {
435 pbuf
+= sizeof(obuf
);
436 ok(memcmp(obuf2
, pbuf
, sizeof(obuf2
)) == 0, "pipe content 4b check\n");
438 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
439 if (pipemode
== PIPE_TYPE_BYTE
) {
440 ok(readden
== sizeof(obuf
) + sizeof(obuf2
), "read 4 got %d bytes\n", readden
);
443 ok(readden
== sizeof(obuf
), "read 4 got %d bytes\n", readden
);
446 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 4a check\n");
447 if (pipemode
== PIPE_TYPE_BYTE
) {
448 pbuf
+= sizeof(obuf
);
449 ok(memcmp(obuf2
, pbuf
, sizeof(obuf2
)) == 0, "content 4b check\n");
452 /* Test reading of multiple writes after a mode change
453 (CreateFile always creates a byte mode pipe) */
454 lpmode
= PIPE_READMODE_MESSAGE
;
455 if (pipemode
== PIPE_TYPE_BYTE
) {
456 /* trying to change the client end of a byte pipe to message mode should fail */
457 ok(!SetNamedPipeHandleState(hFile
, &lpmode
, NULL
, NULL
), "Change mode\n");
460 ok(SetNamedPipeHandleState(hFile
, &lpmode
, NULL
, NULL
), "Change mode\n");
462 memset(ibuf
, 0, sizeof(ibuf
));
463 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile5a\n");
464 ok(written
== sizeof(obuf
), "write file len 3a\n");
465 ok(WriteFile(hnp
, obuf2
, sizeof(obuf2
), &written
, NULL
), " WriteFile5b\n");
466 ok(written
== sizeof(obuf2
), "write file len 3b\n");
467 ok(PeekNamedPipe(hFile
, ibuf
, sizeof(ibuf
), &readden
, &avail
, &left
), "Peek5\n");
468 ok(readden
== sizeof(obuf
), "peek5 got %d bytes\n", readden
);
469 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek5 got %d bytes available\n", avail
);
470 ok(left
== 0, "peek5 got %d bytes left\n", left
);
472 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 5a check\n");
473 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
474 ok(readden
== sizeof(obuf
), "read 5 got %d bytes\n", readden
);
476 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 5a check\n");
477 if (readden
<= sizeof(obuf
))
478 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
480 /* Multiple writes in the reverse direction */
481 /* the write of obuf2 from write4 should still be in the buffer */
482 ok(PeekNamedPipe(hnp
, ibuf
, sizeof(ibuf
), &readden
, &avail
, NULL
), "Peek6a\n");
483 ok(readden
== sizeof(obuf2
), "peek6a got %d bytes\n", readden
);
484 ok(avail
== sizeof(obuf2
), "peek6a got %d bytes available\n", avail
);
486 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
487 ok(readden
== sizeof(obuf2
), "read 6a got %d bytes\n", readden
);
489 ok(memcmp(obuf2
, pbuf
, sizeof(obuf2
)) == 0, "content 6a check\n");
491 memset(ibuf
, 0, sizeof(ibuf
));
492 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile6a\n");
493 ok(written
== sizeof(obuf
), "write file len 6a\n");
494 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), " WriteFile6b\n");
495 ok(written
== sizeof(obuf2
), "write file len 6b\n");
496 ok(PeekNamedPipe(hnp
, ibuf
, sizeof(ibuf
), &readden
, &avail
, NULL
), "Peek6\n");
497 ok(readden
== sizeof(obuf
), "peek6 got %d bytes\n", readden
);
499 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek6b got %d bytes available\n", avail
);
501 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 6a check\n");
502 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
503 ok(readden
== sizeof(obuf
), "read 6b got %d bytes\n", readden
);
505 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 6a check\n");
506 if (readden
<= sizeof(obuf
))
507 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
509 /* Test how ReadFile behaves when the buffer is not big enough for the whole message */
510 memset(ibuf
, 0, sizeof(ibuf
));
511 ok(WriteFile(hnp
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile 7\n");
512 ok(written
== sizeof(obuf2
), "write file len 7\n");
513 SetLastError(0xdeadbeef);
514 ok(!ReadFile(hFile
, ibuf
, 4, &readden
, NULL
), "ReadFile 7\n");
515 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 7\n");
516 ok(readden
== 4, "read got %d bytes 7\n", readden
);
517 ok(ReadFile(hFile
, ibuf
+ 4, sizeof(ibuf
) - 4, &readden
, NULL
), "ReadFile 7\n");
518 ok(readden
== sizeof(obuf2
) - 4, "read got %d bytes 7\n", readden
);
519 ok(memcmp(obuf2
, ibuf
, written
) == 0, "content check 7\n");
521 memset(ibuf
, 0, sizeof(ibuf
));
522 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile 8\n");
523 ok(written
== sizeof(obuf
), "write file len 8\n");
524 SetLastError(0xdeadbeef);
525 ok(!ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile 8\n");
526 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 8\n");
527 ok(readden
== 4, "read got %d bytes 8\n", readden
);
528 ok(ReadFile(hnp
, ibuf
+ 4, sizeof(ibuf
) - 4, &readden
, NULL
), "ReadFile 8\n");
529 ok(readden
== sizeof(obuf
) - 4, "read got %d bytes 8\n", readden
);
530 ok(memcmp(obuf
, ibuf
, written
) == 0, "content check 8\n");
532 /* The following test shows that when doing a partial read of a message, the rest
533 * is still in the pipe, and can be received from a second thread. This shows
534 * especially that the content is _not_ stored in thread-local-storage until it is
535 * completely transmitted. The same method works even across multiple processes. */
536 memset(ibuf
, 0, sizeof(ibuf
));
537 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile 9\n");
538 ok(written
== sizeof(obuf
), "write file len 9\n");
539 ok(WriteFile(hnp
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile 9\n");
540 ok(written
== sizeof(obuf2
), "write file len 9\n");
541 SetLastError(0xdeadbeef);
542 ok(!ReadFile(hFile
, ibuf
, 4, &readden
, NULL
), "ReadFile 9\n");
543 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 9\n");
544 ok(readden
== 4, "read got %d bytes 9\n", readden
);
545 SetLastError(0xdeadbeef);
546 ret
= RpcReadFile(hFile
, ibuf
+ 4, 4, &readden
, NULL
);
547 ok(!ret
, "RpcReadFile 9\n");
548 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 9\n");
549 ok(readden
== 4, "read got %d bytes 9\n", readden
);
550 ret
= RpcReadFile(hFile
, ibuf
+ 8, sizeof(ibuf
), &readden
, NULL
);
551 ok(ret
, "RpcReadFile 9\n");
552 ok(readden
== sizeof(obuf
) - 8, "read got %d bytes 9\n", readden
);
553 ok(memcmp(obuf
, ibuf
, sizeof(obuf
)) == 0, "content check 9\n");
554 if (readden
<= sizeof(obuf
) - 8) /* blocks forever if second part was already received */
556 memset(ibuf
, 0, sizeof(ibuf
));
557 SetLastError(0xdeadbeef);
558 ret
= RpcReadFile(hFile
, ibuf
, 4, &readden
, NULL
);
559 ok(!ret
, "RpcReadFile 9\n");
560 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 9\n");
561 ok(readden
== 4, "read got %d bytes 9\n", readden
);
562 SetLastError(0xdeadbeef);
563 ok(!ReadFile(hFile
, ibuf
+ 4, 4, &readden
, NULL
), "ReadFile 9\n");
564 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 9\n");
565 ok(readden
== 4, "read got %d bytes 9\n", readden
);
566 ret
= RpcReadFile(hFile
, ibuf
+ 8, sizeof(ibuf
), &readden
, NULL
);
567 ok(ret
, "RpcReadFile 9\n");
568 ok(readden
== sizeof(obuf2
) - 8, "read got %d bytes 9\n", readden
);
569 ok(memcmp(obuf2
, ibuf
, sizeof(obuf2
)) == 0, "content check 9\n");
572 /* Now the reverse direction */
573 memset(ibuf
, 0, sizeof(ibuf
));
574 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile 10\n");
575 ok(written
== sizeof(obuf2
), "write file len 10\n");
576 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile 10\n");
577 ok(written
== sizeof(obuf
), "write file len 10\n");
578 SetLastError(0xdeadbeef);
579 ok(!ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile 10\n");
580 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 10\n");
581 ok(readden
== 4, "read got %d bytes 10\n", readden
);
582 SetLastError(0xdeadbeef);
583 ret
= RpcReadFile(hnp
, ibuf
+ 4, 4, &readden
, NULL
);
584 ok(!ret
, "RpcReadFile 10\n");
585 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 10\n");
586 ok(readden
== 4, "read got %d bytes 10\n", readden
);
587 ret
= RpcReadFile(hnp
, ibuf
+ 8, sizeof(ibuf
), &readden
, NULL
);
588 ok(ret
, "RpcReadFile 10\n");
589 ok(readden
== sizeof(obuf2
) - 8, "read got %d bytes 10\n", readden
);
590 ok(memcmp(obuf2
, ibuf
, sizeof(obuf2
)) == 0, "content check 10\n");
591 if (readden
<= sizeof(obuf2
) - 8) /* blocks forever if second part was already received */
593 memset(ibuf
, 0, sizeof(ibuf
));
594 SetLastError(0xdeadbeef);
595 ret
= RpcReadFile(hnp
, ibuf
, 4, &readden
, NULL
);
596 ok(!ret
, "RpcReadFile 10\n");
597 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 10\n");
598 ok(readden
== 4, "read got %d bytes 10\n", readden
);
599 SetLastError(0xdeadbeef);
600 ok(!ReadFile(hnp
, ibuf
+ 4, 4, &readden
, NULL
), "ReadFile 10\n");
601 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 10\n");
602 ok(readden
== 4, "read got %d bytes 10\n", readden
);
603 ret
= RpcReadFile(hnp
, ibuf
+ 8, sizeof(ibuf
), &readden
, NULL
);
604 ok(ret
, "RpcReadFile 10\n");
605 ok(readden
== sizeof(obuf
) - 8, "read got %d bytes 10\n", readden
);
606 ok(memcmp(obuf
, ibuf
, sizeof(obuf
)) == 0, "content check 10\n");
611 /* Picky conformance tests */
613 /* Verify that you can't connect to pipe again
614 * until server calls DisconnectNamedPipe+ConnectNamedPipe
615 * or creates a new pipe
616 * case 1: other client not yet closed
618 hFile2
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
619 ok(hFile2
== INVALID_HANDLE_VALUE
,
620 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n");
621 ok(GetLastError() == ERROR_PIPE_BUSY
,
622 "connecting to named pipe before other client closes should fail with ERROR_PIPE_BUSY\n");
624 ok(CloseHandle(hFile
), "CloseHandle\n");
626 /* case 2: other client already closed */
627 hFile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
628 ok(hFile
== INVALID_HANDLE_VALUE
,
629 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n");
630 ok(GetLastError() == ERROR_PIPE_BUSY
,
631 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail with ERROR_PIPE_BUSY\n");
633 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe\n");
635 /* case 3: server has called DisconnectNamedPipe but not ConnectNamed Pipe */
636 hFile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
637 ok(hFile
== INVALID_HANDLE_VALUE
,
638 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n");
639 ok(GetLastError() == ERROR_PIPE_BUSY
,
640 "connecting to named pipe after other client closes but before ConnectNamedPipe should fail with ERROR_PIPE_BUSY\n");
642 /* to be complete, we'd call ConnectNamedPipe here and loop,
643 * but by default that's blocking, so we'd either have
644 * to turn on the uncommon nonblocking mode, or
645 * use another thread.
649 ok(CloseHandle(hnp
), "CloseHandle\n");
651 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_INBOUND
, pipemode
| PIPE_WAIT
,
652 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
653 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
656 test_file_access(hnp
, SYNCHRONIZE
| READ_CONTROL
| FILE_READ_ATTRIBUTES
| FILE_READ_PROPERTIES
661 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_OUTBOUND
, pipemode
| PIPE_WAIT
,
662 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
663 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
666 test_file_access(hnp
, SYNCHRONIZE
| READ_CONTROL
| FILE_WRITE_ATTRIBUTES
667 | FILE_WRITE_PROPERTIES
| FILE_APPEND_DATA
| FILE_WRITE_DATA
);
669 hFile
= CreateFileA(PIPENAME
, 0, 0, NULL
, OPEN_EXISTING
, 0, 0);
670 ok(hFile
!= INVALID_HANDLE_VALUE
, "CreateFile failed: %u\n", GetLastError());
671 test_file_access(hFile
, SYNCHRONIZE
| FILE_READ_ATTRIBUTES
);
676 if (winetest_debug
> 1) trace("test_CreateNamedPipe returning\n");
679 static void test_CreateNamedPipe_instances_must_match(void)
683 /* Check no mismatch */
684 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
685 /* nMaxInstances */ 2,
686 /* nOutBufSize */ 1024,
687 /* nInBufSize */ 1024,
688 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
689 /* lpSecurityAttrib */ NULL
);
690 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
692 hnp2
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
693 /* nMaxInstances */ 2,
694 /* nOutBufSize */ 1024,
695 /* nInBufSize */ 1024,
696 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
697 /* lpSecurityAttrib */ NULL
);
698 ok(hnp2
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
700 ok(CloseHandle(hnp
), "CloseHandle\n");
701 ok(CloseHandle(hnp2
), "CloseHandle\n");
703 /* Check nMaxInstances */
704 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
705 /* nMaxInstances */ 1,
706 /* nOutBufSize */ 1024,
707 /* nInBufSize */ 1024,
708 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
709 /* lpSecurityAttrib */ NULL
);
710 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
712 hnp2
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
713 /* nMaxInstances */ 1,
714 /* nOutBufSize */ 1024,
715 /* nInBufSize */ 1024,
716 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
717 /* lpSecurityAttrib */ NULL
);
718 ok(hnp2
== INVALID_HANDLE_VALUE
719 && GetLastError() == ERROR_PIPE_BUSY
, "nMaxInstances not obeyed\n");
721 ok(CloseHandle(hnp
), "CloseHandle\n");
723 /* Check PIPE_ACCESS_* */
724 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
725 /* nMaxInstances */ 2,
726 /* nOutBufSize */ 1024,
727 /* nInBufSize */ 1024,
728 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
729 /* lpSecurityAttrib */ NULL
);
730 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
732 hnp2
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_INBOUND
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
733 /* nMaxInstances */ 2,
734 /* nOutBufSize */ 1024,
735 /* nInBufSize */ 1024,
736 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
737 /* lpSecurityAttrib */ NULL
);
738 ok(hnp2
== INVALID_HANDLE_VALUE
739 && GetLastError() == ERROR_ACCESS_DENIED
, "PIPE_ACCESS_* mismatch allowed\n");
741 ok(CloseHandle(hnp
), "CloseHandle\n");
743 /* check everything else */
744 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
745 /* nMaxInstances */ 4,
746 /* nOutBufSize */ 1024,
747 /* nInBufSize */ 1024,
748 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
749 /* lpSecurityAttrib */ NULL
);
750 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
752 hnp2
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_MESSAGE
,
753 /* nMaxInstances */ 3,
754 /* nOutBufSize */ 102,
756 /* nDefaultWait */ 1234,
757 /* lpSecurityAttrib */ NULL
);
758 ok(hnp2
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
760 ok(CloseHandle(hnp
), "CloseHandle\n");
761 ok(CloseHandle(hnp2
), "CloseHandle\n");
764 static void test_ReadFile(void)
766 HANDLE server
, client
;
767 OVERLAPPED overlapped
;
771 static char buf
[512];
773 server
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
774 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
775 1, 1024, 1024, NMPWAIT_WAIT_FOREVER
, NULL
);
776 ok(server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %u\n", GetLastError());
778 client
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
,
779 OPEN_EXISTING
, 0, 0);
780 ok(client
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %u\n", GetLastError());
782 ok(WriteFile(client
, buf
, sizeof(buf
), &size
, NULL
), "WriteFile\n");
784 res
= ReadFile(server
, buf
, 1, &size
, NULL
);
785 ok(!res
&& GetLastError() == ERROR_MORE_DATA
, "ReadFile returned %x(%u)\n", res
, GetLastError());
786 ok(size
== 1, "size = %u\n", size
);
788 /* pass both overlapped and ret read */
789 memset(&overlapped
, 0, sizeof(overlapped
));
790 res
= ReadFile(server
, buf
, 1, &size
, &overlapped
);
791 ok(!res
&& GetLastError() == ERROR_MORE_DATA
, "ReadFile returned %x(%u)\n", res
, GetLastError());
792 ok(size
== 0, "size = %u\n", size
);
793 ok((NTSTATUS
)overlapped
.Internal
== STATUS_BUFFER_OVERFLOW
, "Internal = %lx\n", overlapped
.Internal
);
794 ok(overlapped
.InternalHigh
== 1, "InternalHigh = %lx\n", overlapped
.InternalHigh
);
796 DisconnectNamedPipe(server
);
798 memset(&overlapped
, 0, sizeof(overlapped
));
799 overlapped
.InternalHigh
= 0xdeadbeef;
800 res
= ReadFile(server
, buf
, 1, &size
, &overlapped
);
801 ok(!res
&& GetLastError() == ERROR_PIPE_NOT_CONNECTED
, "ReadFile returned %x(%u)\n", res
, GetLastError());
802 ok(size
== 0, "size = %u\n", size
);
803 ok(overlapped
.Internal
== STATUS_PENDING
, "Internal = %lx\n", overlapped
.Internal
);
804 ok(overlapped
.InternalHigh
== 0xdeadbeef, "InternalHigh = %lx\n", overlapped
.InternalHigh
);
806 memset(&overlapped
, 0, sizeof(overlapped
));
807 overlapped
.InternalHigh
= 0xdeadbeef;
808 res
= WriteFile(server
, buf
, 1, &size
, &overlapped
);
809 ok(!res
&& GetLastError() == ERROR_PIPE_NOT_CONNECTED
, "ReadFile returned %x(%u)\n", res
, GetLastError());
810 ok(size
== 0, "size = %u\n", size
);
811 ok(overlapped
.Internal
== STATUS_PENDING
, "Internal = %lx\n", overlapped
.Internal
);
812 ok(overlapped
.InternalHigh
== 0xdeadbeef, "InternalHigh = %lx\n", overlapped
.InternalHigh
);
818 /** implementation of alarm() */
819 static DWORD CALLBACK
alarmThreadMain(LPVOID arg
)
821 DWORD_PTR timeout
= (DWORD_PTR
) arg
;
822 if (winetest_debug
> 1) trace("alarmThreadMain\n");
823 if (WaitForSingleObject( alarm_event
, timeout
) == WAIT_TIMEOUT
)
825 ok(FALSE
, "alarm\n");
831 static HANDLE hnp
= INVALID_HANDLE_VALUE
;
833 /** Trivial byte echo server - disconnects after each session */
834 static DWORD CALLBACK
serverThreadMain1(LPVOID arg
)
838 if (winetest_debug
> 1) trace("serverThreadMain1 start\n");
839 /* Set up a simple echo server */
840 hnp
= CreateNamedPipeA(PIPENAME
"serverThreadMain1", PIPE_ACCESS_DUPLEX
,
841 PIPE_TYPE_BYTE
| PIPE_WAIT
,
842 /* nMaxInstances */ 1,
843 /* nOutBufSize */ 1024,
844 /* nInBufSize */ 1024,
845 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
846 /* lpSecurityAttrib */ NULL
);
848 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
849 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
855 /* Wait for client to connect */
856 if (winetest_debug
> 1) trace("Server calling ConnectNamedPipe...\n");
857 ok(ConnectNamedPipe(hnp
, NULL
)
858 || GetLastError() == ERROR_PIPE_CONNECTED
, "ConnectNamedPipe\n");
859 if (winetest_debug
> 1) trace("ConnectNamedPipe returned.\n");
861 /* Echo bytes once */
862 memset(buf
, 0, sizeof(buf
));
864 if (winetest_debug
> 1) trace("Server reading...\n");
865 success
= ReadFile(hnp
, buf
, sizeof(buf
), &readden
, NULL
);
866 if (winetest_debug
> 1) trace("Server done reading.\n");
867 ok(success
, "ReadFile\n");
868 ok(readden
, "short read\n");
870 if (winetest_debug
> 1) trace("Server writing...\n");
871 ok(WriteFile(hnp
, buf
, readden
, &written
, NULL
), "WriteFile\n");
872 if (winetest_debug
> 1) trace("Server done writing.\n");
873 ok(written
== readden
, "write file len\n");
875 /* finish this connection, wait for next one */
876 ok(FlushFileBuffers(hnp
), "FlushFileBuffers\n");
877 if (winetest_debug
> 1) trace("Server done flushing.\n");
878 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe\n");
879 if (winetest_debug
> 1) trace("Server done disconnecting.\n");
884 /** Trivial byte echo server - closes after each connection */
885 static DWORD CALLBACK
serverThreadMain2(LPVOID arg
)
890 trace("serverThreadMain2\n");
891 /* Set up a simple echo server */
892 hnp
= CreateNamedPipeA(PIPENAME
"serverThreadMain2", PIPE_ACCESS_DUPLEX
,
893 PIPE_TYPE_BYTE
| PIPE_WAIT
,
894 /* nMaxInstances */ 2,
895 /* nOutBufSize */ 1024,
896 /* nInBufSize */ 1024,
897 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
898 /* lpSecurityAttrib */ NULL
);
899 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
901 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
909 user_apc_ran
= FALSE
;
912 if (winetest_debug
> 1) trace("Queueing an user APC\n"); /* verify the pipe is non alerable */
913 ret
= QueueUserAPC(&user_apc
, GetCurrentThread(), 0);
914 ok(ret
, "QueueUserAPC failed: %d\n", GetLastError());
917 /* Wait for client to connect */
918 if (winetest_debug
> 1) trace("Server calling ConnectNamedPipe...\n");
919 ok(ConnectNamedPipe(hnp
, NULL
)
920 || GetLastError() == ERROR_PIPE_CONNECTED
, "ConnectNamedPipe\n");
921 if (winetest_debug
> 1) trace("ConnectNamedPipe returned.\n");
923 /* Echo bytes once */
924 memset(buf
, 0, sizeof(buf
));
926 if (winetest_debug
> 1) trace("Server reading...\n");
927 success
= ReadFile(hnp
, buf
, sizeof(buf
), &readden
, NULL
);
928 if (winetest_debug
> 1) trace("Server done reading.\n");
929 ok(success
, "ReadFile\n");
931 if (winetest_debug
> 1) trace("Server writing...\n");
932 ok(WriteFile(hnp
, buf
, readden
, &written
, NULL
), "WriteFile\n");
933 if (winetest_debug
> 1) trace("Server done writing.\n");
934 ok(written
== readden
, "write file len\n");
936 /* finish this connection, wait for next one */
937 ok(FlushFileBuffers(hnp
), "FlushFileBuffers\n");
938 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe\n");
940 ok(user_apc_ran
== FALSE
, "UserAPC ran, pipe using alertable io mode\n");
943 SleepEx(0, TRUE
); /* get rid of apc */
945 /* Set up next echo server */
947 CreateNamedPipeA(PIPENAME
"serverThreadMain2", PIPE_ACCESS_DUPLEX
,
948 PIPE_TYPE_BYTE
| PIPE_WAIT
,
949 /* nMaxInstances */ 2,
950 /* nOutBufSize */ 1024,
951 /* nInBufSize */ 1024,
952 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
953 /* lpSecurityAttrib */ NULL
);
955 ok(hnpNext
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
957 ok(CloseHandle(hnp
), "CloseHandle\n");
963 /** Trivial byte echo server - uses overlapped named pipe calls */
964 static DWORD CALLBACK
serverThreadMain3(LPVOID arg
)
969 if (winetest_debug
> 1) trace("serverThreadMain3\n");
970 /* Set up a simple echo server */
971 hnp
= CreateNamedPipeA(PIPENAME
"serverThreadMain3", PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
972 PIPE_TYPE_BYTE
| PIPE_WAIT
,
973 /* nMaxInstances */ 1,
974 /* nOutBufSize */ 1024,
975 /* nInBufSize */ 1024,
976 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
977 /* lpSecurityAttrib */ NULL
);
978 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
980 hEvent
= CreateEventW(NULL
, /* security attribute */
981 TRUE
, /* manual reset event */
982 FALSE
, /* initial state */
984 ok(hEvent
!= NULL
, "CreateEvent\n");
986 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
993 int letWFSOEwait
= (i
& 2);
994 int letGORwait
= (i
& 1);
997 memset(&oOverlap
, 0, sizeof(oOverlap
));
998 oOverlap
.hEvent
= hEvent
;
1000 /* Wait for client to connect */
1002 if (winetest_debug
> 1) trace("Server calling non-overlapped ConnectNamedPipe on overlapped pipe...\n");
1003 success
= ConnectNamedPipe(hnp
, NULL
);
1004 err
= GetLastError();
1005 ok(success
|| (err
== ERROR_PIPE_CONNECTED
), "ConnectNamedPipe failed: %d\n", err
);
1006 if (winetest_debug
> 1) trace("ConnectNamedPipe operation complete.\n");
1008 if (winetest_debug
> 1) trace("Server calling overlapped ConnectNamedPipe...\n");
1009 success
= ConnectNamedPipe(hnp
, &oOverlap
);
1010 err
= GetLastError();
1011 ok(!success
&& (err
== ERROR_IO_PENDING
|| err
== ERROR_PIPE_CONNECTED
), "overlapped ConnectNamedPipe\n");
1012 if (winetest_debug
> 1) trace("overlapped ConnectNamedPipe returned.\n");
1013 if (!success
&& (err
== ERROR_IO_PENDING
)) {
1018 ret
= WaitForSingleObjectEx(hEvent
, INFINITE
, TRUE
);
1019 } while (ret
== WAIT_IO_COMPLETION
);
1020 ok(ret
== 0, "wait ConnectNamedPipe returned %x\n", ret
);
1022 success
= GetOverlappedResult(hnp
, &oOverlap
, &dummy
, letGORwait
);
1023 if (!letGORwait
&& !letWFSOEwait
&& !success
) {
1024 ok(GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult\n");
1025 success
= GetOverlappedResult(hnp
, &oOverlap
, &dummy
, TRUE
);
1028 ok(success
|| (err
== ERROR_PIPE_CONNECTED
), "GetOverlappedResult ConnectNamedPipe\n");
1029 if (winetest_debug
> 1) trace("overlapped ConnectNamedPipe operation complete.\n");
1032 /* Echo bytes once */
1033 memset(buf
, 0, sizeof(buf
));
1035 if (winetest_debug
> 1) trace("Server reading...\n");
1036 success
= ReadFile(hnp
, buf
, sizeof(buf
), &readden
, &oOverlap
);
1037 if (winetest_debug
> 1) trace("Server ReadFile returned...\n");
1038 err
= GetLastError();
1039 ok(success
|| err
== ERROR_IO_PENDING
, "overlapped ReadFile\n");
1040 if (winetest_debug
> 1) trace("overlapped ReadFile returned.\n");
1041 if (!success
&& (err
== ERROR_IO_PENDING
)) {
1046 ret
= WaitForSingleObjectEx(hEvent
, INFINITE
, TRUE
);
1047 } while (ret
== WAIT_IO_COMPLETION
);
1048 ok(ret
== 0, "wait ReadFile returned %x\n", ret
);
1050 success
= GetOverlappedResult(hnp
, &oOverlap
, &readden
, letGORwait
);
1051 if (!letGORwait
&& !letWFSOEwait
&& !success
) {
1052 ok(GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult\n");
1053 success
= GetOverlappedResult(hnp
, &oOverlap
, &readden
, TRUE
);
1056 if (winetest_debug
> 1) trace("Server done reading.\n");
1057 ok(success
, "overlapped ReadFile\n");
1059 if (winetest_debug
> 1) trace("Server writing...\n");
1060 success
= WriteFile(hnp
, buf
, readden
, &written
, &oOverlap
);
1061 if (winetest_debug
> 1) trace("Server WriteFile returned...\n");
1062 err
= GetLastError();
1063 ok(success
|| err
== ERROR_IO_PENDING
, "overlapped WriteFile\n");
1064 if (winetest_debug
> 1) trace("overlapped WriteFile returned.\n");
1065 if (!success
&& (err
== ERROR_IO_PENDING
)) {
1070 ret
= WaitForSingleObjectEx(hEvent
, INFINITE
, TRUE
);
1071 } while (ret
== WAIT_IO_COMPLETION
);
1072 ok(ret
== 0, "wait WriteFile returned %x\n", ret
);
1074 success
= GetOverlappedResult(hnp
, &oOverlap
, &written
, letGORwait
);
1075 if (!letGORwait
&& !letWFSOEwait
&& !success
) {
1076 ok(GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult\n");
1077 success
= GetOverlappedResult(hnp
, &oOverlap
, &written
, TRUE
);
1080 if (winetest_debug
> 1) trace("Server done writing.\n");
1081 ok(success
, "overlapped WriteFile\n");
1082 ok(written
== readden
, "write file len\n");
1084 /* finish this connection, wait for next one */
1085 ok(FlushFileBuffers(hnp
), "FlushFileBuffers\n");
1086 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe\n");
1091 /** Trivial byte echo server - uses i/o completion ports */
1092 static DWORD CALLBACK
serverThreadMain4(LPVOID arg
)
1098 if (winetest_debug
> 1) trace("serverThreadMain4\n");
1099 /* Set up a simple echo server */
1100 hnp
= CreateNamedPipeA(PIPENAME
"serverThreadMain4", PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
1101 PIPE_TYPE_BYTE
| PIPE_WAIT
,
1102 /* nMaxInstances */ 1,
1103 /* nOutBufSize */ 1024,
1104 /* nInBufSize */ 1024,
1105 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1106 /* lpSecurityAttrib */ NULL
);
1107 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
1109 hcompletion
= CreateIoCompletionPort(hnp
, NULL
, 12345, 1);
1110 ok(hcompletion
!= NULL
, "CreateIoCompletionPort failed, error=%i\n", GetLastError());
1112 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
1118 OVERLAPPED oConnect
;
1121 OVERLAPPED
*oResult
;
1125 memset(&oConnect
, 0, sizeof(oConnect
));
1126 memset(&oRead
, 0, sizeof(oRead
));
1127 memset(&oWrite
, 0, sizeof(oWrite
));
1129 /* Wait for client to connect */
1130 if (winetest_debug
> 1) trace("Server calling overlapped ConnectNamedPipe...\n");
1131 success
= ConnectNamedPipe(hnp
, &oConnect
);
1132 err
= GetLastError();
1133 ok(!success
&& (err
== ERROR_IO_PENDING
|| err
== ERROR_PIPE_CONNECTED
),
1134 "overlapped ConnectNamedPipe got %u err %u\n", success
, err
);
1135 if (!success
&& err
== ERROR_IO_PENDING
) {
1136 if (winetest_debug
> 1) trace("ConnectNamedPipe GetQueuedCompletionStatus\n");
1137 success
= GetQueuedCompletionStatus(hcompletion
, &dummy
, &compkey
, &oResult
, 0);
1140 ok( GetLastError() == WAIT_TIMEOUT
,
1141 "ConnectNamedPipe GetQueuedCompletionStatus wrong error %u\n", GetLastError());
1142 success
= GetQueuedCompletionStatus(hcompletion
, &dummy
, &compkey
, &oResult
, 10000);
1144 ok(success
, "ConnectNamedPipe GetQueuedCompletionStatus failed, errno=%i\n", GetLastError());
1147 ok(compkey
== 12345, "got completion key %i instead of 12345\n", (int)compkey
);
1148 ok(oResult
== &oConnect
, "got overlapped pointer %p instead of %p\n", oResult
, &oConnect
);
1151 if (winetest_debug
> 1) trace("overlapped ConnectNamedPipe operation complete.\n");
1153 /* Echo bytes once */
1154 memset(buf
, 0, sizeof(buf
));
1156 if (winetest_debug
> 1) trace("Server reading...\n");
1157 success
= ReadFile(hnp
, buf
, sizeof(buf
), &readden
, &oRead
);
1158 if (winetest_debug
> 1) trace("Server ReadFile returned...\n");
1159 err
= GetLastError();
1160 ok(success
|| err
== ERROR_IO_PENDING
, "overlapped ReadFile, err=%i\n", err
);
1161 success
= GetQueuedCompletionStatus(hcompletion
, &readden
, &compkey
,
1163 ok(success
, "ReadFile GetQueuedCompletionStatus failed, errno=%i\n", GetLastError());
1166 ok(compkey
== 12345, "got completion key %i instead of 12345\n", (int)compkey
);
1167 ok(oResult
== &oRead
, "got overlapped pointer %p instead of %p\n", oResult
, &oRead
);
1169 if (winetest_debug
> 1) trace("Server done reading.\n");
1171 if (winetest_debug
> 1) trace("Server writing...\n");
1172 success
= WriteFile(hnp
, buf
, readden
, &written
, &oWrite
);
1173 if (winetest_debug
> 1) trace("Server WriteFile returned...\n");
1174 err
= GetLastError();
1175 ok(success
|| err
== ERROR_IO_PENDING
, "overlapped WriteFile failed, err=%u\n", err
);
1176 success
= GetQueuedCompletionStatus(hcompletion
, &written
, &compkey
,
1178 ok(success
, "WriteFile GetQueuedCompletionStatus failed, errno=%i\n", GetLastError());
1181 ok(compkey
== 12345, "got completion key %i instead of 12345\n", (int)compkey
);
1182 ok(oResult
== &oWrite
, "got overlapped pointer %p instead of %p\n", oResult
, &oWrite
);
1183 ok(written
== readden
, "write file len\n");
1185 if (winetest_debug
> 1) trace("Server done writing.\n");
1187 /* Client will finish this connection, the following ops will trigger broken pipe errors. */
1189 /* Wait for the pipe to break. */
1190 while (PeekNamedPipe(hnp
, NULL
, 0, NULL
, &written
, &written
));
1192 if (winetest_debug
> 1) trace("Server writing on disconnected pipe...\n");
1193 SetLastError(ERROR_SUCCESS
);
1194 success
= WriteFile(hnp
, buf
, readden
, &written
, &oWrite
);
1195 err
= GetLastError();
1196 ok(!success
&& err
== ERROR_NO_DATA
,
1197 "overlapped WriteFile on disconnected pipe returned %u, err=%i\n", success
, err
);
1199 /* No completion status is queued on immediate error. */
1200 SetLastError(ERROR_SUCCESS
);
1201 oResult
= (OVERLAPPED
*)0xdeadbeef;
1202 success
= GetQueuedCompletionStatus(hcompletion
, &written
, &compkey
,
1204 err
= GetLastError();
1205 ok(!success
&& err
== WAIT_TIMEOUT
&& !oResult
,
1206 "WriteFile GetQueuedCompletionStatus returned %u, err=%i, oResult %p\n",
1207 success
, err
, oResult
);
1209 if (winetest_debug
> 1) trace("Server reading from disconnected pipe...\n");
1210 SetLastError(ERROR_SUCCESS
);
1211 success
= ReadFile(hnp
, buf
, sizeof(buf
), &readden
, &oRead
);
1212 if (winetest_debug
> 1) trace("Server ReadFile from disconnected pipe returned...\n");
1213 err
= GetLastError();
1214 ok(!success
&& err
== ERROR_BROKEN_PIPE
,
1215 "overlapped ReadFile on disconnected pipe returned %u, err=%i\n", success
, err
);
1217 SetLastError(ERROR_SUCCESS
);
1218 oResult
= (OVERLAPPED
*)0xdeadbeef;
1219 success
= GetQueuedCompletionStatus(hcompletion
, &readden
, &compkey
,
1221 err
= GetLastError();
1222 ok(!success
&& err
== WAIT_TIMEOUT
&& !oResult
,
1223 "ReadFile GetQueuedCompletionStatus returned %u, err=%i, oResult %p\n",
1224 success
, err
, oResult
);
1226 /* finish this connection, wait for next one */
1227 ok(FlushFileBuffers(hnp
), "FlushFileBuffers\n");
1228 success
= DisconnectNamedPipe(hnp
);
1229 ok(success
, "DisconnectNamedPipe failed, err %u\n", GetLastError());
1232 ret
= CloseHandle(hnp
);
1233 ok(ret
, "CloseHandle named pipe failed, err=%i\n", GetLastError());
1234 ret
= CloseHandle(hcompletion
);
1235 ok(ret
, "CloseHandle completion failed, err=%i\n", GetLastError());
1240 static int completion_called
;
1241 static DWORD completion_errorcode
;
1242 static DWORD completion_num_bytes
;
1243 static LPOVERLAPPED completion_lpoverlapped
;
1245 static VOID WINAPI
completion_routine(DWORD errorcode
, DWORD num_bytes
, LPOVERLAPPED lpoverlapped
)
1247 completion_called
++;
1248 completion_errorcode
= errorcode
;
1249 completion_num_bytes
= num_bytes
;
1250 completion_lpoverlapped
= lpoverlapped
;
1251 SetEvent(lpoverlapped
->hEvent
);
1254 /** Trivial byte echo server - uses ReadFileEx/WriteFileEx */
1255 static DWORD CALLBACK
serverThreadMain5(LPVOID arg
)
1260 if (winetest_debug
> 1) trace("serverThreadMain5\n");
1261 /* Set up a simple echo server */
1262 hnp
= CreateNamedPipeA(PIPENAME
"serverThreadMain5", PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
1263 PIPE_TYPE_BYTE
| PIPE_WAIT
,
1264 /* nMaxInstances */ 1,
1265 /* nOutBufSize */ 1024,
1266 /* nInBufSize */ 1024,
1267 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1268 /* lpSecurityAttrib */ NULL
);
1269 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
1271 hEvent
= CreateEventW(NULL
, /* security attribute */
1272 TRUE
, /* manual reset event */
1273 FALSE
, /* initial state */
1275 ok(hEvent
!= NULL
, "CreateEvent\n");
1277 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
1281 OVERLAPPED oOverlap
;
1284 memset(&oOverlap
, 0, sizeof(oOverlap
));
1285 oOverlap
.hEvent
= hEvent
;
1287 /* Wait for client to connect */
1288 if (winetest_debug
> 1) trace("Server calling ConnectNamedPipe...\n");
1289 success
= ConnectNamedPipe(hnp
, NULL
);
1290 err
= GetLastError();
1291 ok(success
|| (err
== ERROR_PIPE_CONNECTED
), "ConnectNamedPipe failed: %d\n", err
);
1292 if (winetest_debug
> 1) trace("ConnectNamedPipe operation complete.\n");
1294 /* Echo bytes once */
1295 memset(buf
, 0, sizeof(buf
));
1297 if (winetest_debug
> 1) trace("Server reading...\n");
1298 completion_called
= 0;
1300 success
= ReadFileEx(hnp
, buf
, sizeof(buf
), &oOverlap
, completion_routine
);
1301 if (winetest_debug
> 1) trace("Server ReadFileEx returned...\n");
1302 ok(success
, "ReadFileEx failed, err=%i\n", GetLastError());
1303 ok(completion_called
== 0, "completion routine called before ReadFileEx return\n");
1304 if (winetest_debug
> 1) trace("ReadFileEx returned.\n");
1308 ret
= WaitForSingleObjectEx(hEvent
, INFINITE
, TRUE
);
1309 } while (ret
== WAIT_IO_COMPLETION
);
1310 ok(ret
== 0, "wait ReadFileEx returned %x\n", ret
);
1312 ok(completion_called
== 1, "completion routine called %i times\n", completion_called
);
1313 ok(completion_errorcode
== ERROR_SUCCESS
, "completion routine got error %d\n", completion_errorcode
);
1314 ok(completion_num_bytes
!= 0, "read 0 bytes\n");
1315 ok(completion_lpoverlapped
== &oOverlap
, "got wrong overlapped pointer %p\n", completion_lpoverlapped
);
1316 readden
= completion_num_bytes
;
1317 if (winetest_debug
> 1) trace("Server done reading.\n");
1319 if (winetest_debug
> 1) trace("Server writing...\n");
1320 completion_called
= 0;
1322 success
= WriteFileEx(hnp
, buf
, readden
, &oOverlap
, completion_routine
);
1323 if (winetest_debug
> 1) trace("Server WriteFileEx returned...\n");
1324 ok(success
, "WriteFileEx failed, err=%i\n", GetLastError());
1325 ok(completion_called
== 0, "completion routine called before ReadFileEx return\n");
1326 if (winetest_debug
> 1) trace("overlapped WriteFile returned.\n");
1330 ret
= WaitForSingleObjectEx(hEvent
, INFINITE
, TRUE
);
1331 } while (ret
== WAIT_IO_COMPLETION
);
1332 ok(ret
== 0, "wait WriteFileEx returned %x\n", ret
);
1334 if (winetest_debug
> 1) trace("Server done writing.\n");
1335 ok(completion_called
== 1, "completion routine called %i times\n", completion_called
);
1336 ok(completion_errorcode
== ERROR_SUCCESS
, "completion routine got error %d\n", completion_errorcode
);
1337 ok(completion_num_bytes
== readden
, "read %i bytes wrote %i\n", readden
, completion_num_bytes
);
1338 ok(completion_lpoverlapped
== &oOverlap
, "got wrong overlapped pointer %p\n", completion_lpoverlapped
);
1340 /* finish this connection, wait for next one */
1341 ok(FlushFileBuffers(hnp
), "FlushFileBuffers\n");
1342 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe\n");
1347 static void exerciseServer(const char *pipename
, HANDLE serverThread
)
1351 if (winetest_debug
> 1) trace("exerciseServer starting\n");
1352 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
1353 HANDLE hFile
=INVALID_HANDLE_VALUE
;
1354 static const char obuf
[] = "Bit Bucket";
1360 for (loop
= 0; loop
< 3; loop
++) {
1362 if (winetest_debug
> 1) trace("Client connecting...\n");
1363 /* Connect to the server */
1364 hFile
= CreateFileA(pipename
, GENERIC_READ
| GENERIC_WRITE
, 0,
1365 NULL
, OPEN_EXISTING
, 0, 0);
1366 if (hFile
!= INVALID_HANDLE_VALUE
)
1368 err
= GetLastError();
1370 ok(err
== ERROR_PIPE_BUSY
|| err
== ERROR_FILE_NOT_FOUND
, "connecting to pipe\n");
1372 ok(err
== ERROR_PIPE_BUSY
, "connecting to pipe\n");
1373 if (winetest_debug
> 1) trace("connect failed, retrying\n");
1376 ok(hFile
!= INVALID_HANDLE_VALUE
, "client opening named pipe\n");
1378 /* Make sure it can echo */
1379 memset(ibuf
, 0, sizeof(ibuf
));
1380 if (winetest_debug
> 1) trace("Client writing...\n");
1381 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile to client end of pipe\n");
1382 ok(written
== sizeof(obuf
), "write file len\n");
1383 if (winetest_debug
> 1) trace("Client reading...\n");
1384 ok(ReadFile(hFile
, ibuf
, sizeof(obuf
), &readden
, NULL
), "ReadFile from client end of pipe\n");
1385 ok(readden
== sizeof(obuf
), "read file len\n");
1386 ok(memcmp(obuf
, ibuf
, written
) == 0, "content check\n");
1388 if (winetest_debug
> 1) trace("Client closing...\n");
1389 ok(CloseHandle(hFile
), "CloseHandle\n");
1392 ok(WaitForSingleObject(serverThread
,INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject\n");
1394 if (winetest_debug
> 1) trace("exerciseServer returning\n");
1397 static void test_NamedPipe_2(void)
1399 HANDLE serverThread
;
1400 DWORD serverThreadId
;
1402 DWORD alarmThreadId
;
1404 trace("test_NamedPipe_2 starting\n");
1405 /* Set up a twenty second timeout */
1406 alarm_event
= CreateEventW( NULL
, TRUE
, FALSE
, NULL
);
1407 SetLastError(0xdeadbeef);
1408 alarmThread
= CreateThread(NULL
, 0, alarmThreadMain
, (void *) 20000, 0, &alarmThreadId
);
1409 ok(alarmThread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1411 /* The servers we're about to exercise do try to clean up carefully,
1412 * but to reduce the chance of a test failure due to a pipe handle
1413 * leak in the test code, we'll use a different pipe name for each server.
1417 SetLastError(0xdeadbeef);
1418 serverThread
= CreateThread(NULL
, 0, serverThreadMain1
, (void *)8, 0, &serverThreadId
);
1419 ok(serverThread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1420 exerciseServer(PIPENAME
"serverThreadMain1", serverThread
);
1423 SetLastError(0xdeadbeef);
1424 serverThread
= CreateThread(NULL
, 0, serverThreadMain2
, 0, 0, &serverThreadId
);
1425 ok(serverThread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1426 exerciseServer(PIPENAME
"serverThreadMain2", serverThread
);
1429 SetLastError(0xdeadbeef);
1430 serverThread
= CreateThread(NULL
, 0, serverThreadMain3
, 0, 0, &serverThreadId
);
1431 ok(serverThread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1432 exerciseServer(PIPENAME
"serverThreadMain3", serverThread
);
1435 SetLastError(0xdeadbeef);
1436 serverThread
= CreateThread(NULL
, 0, serverThreadMain4
, 0, 0, &serverThreadId
);
1437 ok(serverThread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1438 exerciseServer(PIPENAME
"serverThreadMain4", serverThread
);
1441 SetLastError(0xdeadbeef);
1442 serverThread
= CreateThread(NULL
, 0, serverThreadMain5
, 0, 0, &serverThreadId
);
1443 ok(serverThread
!= NULL
, "CreateThread failed: %d\n", GetLastError());
1444 exerciseServer(PIPENAME
"serverThreadMain5", serverThread
);
1446 ok(SetEvent( alarm_event
), "SetEvent\n");
1447 CloseHandle( alarm_event
);
1448 if (winetest_debug
> 1) trace("test_NamedPipe_2 returning\n");
1451 static int test_DisconnectNamedPipe(void)
1455 static const char obuf
[] = "Bit Bucket";
1461 SetLastError(0xdeadbeef);
1462 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
1463 /* nMaxInstances */ 1,
1464 /* nOutBufSize */ 1024,
1465 /* nInBufSize */ 1024,
1466 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1467 /* lpSecurityAttrib */ NULL
);
1468 if ((hnp
== INVALID_HANDLE_VALUE
/* Win98 */ || !hnp
/* Win95 */)
1469 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
) {
1471 win_skip("Named pipes are not implemented\n");
1475 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
) == 0
1476 && GetLastError() == ERROR_PIPE_LISTENING
, "WriteFile to not-yet-connected pipe\n");
1477 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
) == 0
1478 && GetLastError() == ERROR_PIPE_LISTENING
, "ReadFile from not-yet-connected pipe\n");
1480 hFile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1481 ok(hFile
!= INVALID_HANDLE_VALUE
, "CreateFile failed\n");
1483 /* don't try to do i/o if one side couldn't be opened, as it hangs */
1484 if (hFile
!= INVALID_HANDLE_VALUE
) {
1486 /* see what happens if server calls DisconnectNamedPipe
1487 * when there are bytes in the pipe
1490 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile\n");
1491 ok(written
== sizeof(obuf
), "write file len\n");
1492 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe while messages waiting\n");
1493 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
) == 0
1494 && GetLastError() == ERROR_PIPE_NOT_CONNECTED
, "WriteFile to disconnected pipe\n");
1495 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
) == 0
1496 && GetLastError() == ERROR_PIPE_NOT_CONNECTED
, "WriteFile to disconnected pipe\n");
1497 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
) == 0
1498 && GetLastError() == ERROR_PIPE_NOT_CONNECTED
,
1499 "ReadFile from disconnected pipe with bytes waiting\n");
1500 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
) == 0
1501 && GetLastError() == ERROR_PIPE_NOT_CONNECTED
,
1502 "ReadFile from disconnected pipe with bytes waiting\n");
1504 ok(!DisconnectNamedPipe(hnp
) && GetLastError() == ERROR_PIPE_NOT_CONNECTED
,
1505 "DisconnectNamedPipe worked twice\n");
1506 ret
= WaitForSingleObject(hFile
, 0);
1507 ok(ret
== WAIT_TIMEOUT
, "WaitForSingleObject returned %X\n", ret
);
1509 ret
= PeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, NULL
);
1510 ok(!ret
&& GetLastError() == ERROR_PIPE_NOT_CONNECTED
, "PeekNamedPipe returned %x (%u)\n",
1511 ret
, GetLastError());
1512 ret
= PeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, NULL
);
1513 ok(!ret
&& GetLastError() == ERROR_BAD_PIPE
, "PeekNamedPipe returned %x (%u)\n",
1514 ret
, GetLastError());
1515 ok(CloseHandle(hFile
), "CloseHandle\n");
1518 ok(CloseHandle(hnp
), "CloseHandle\n");
1522 static void test_CreatePipe(void)
1524 SECURITY_ATTRIBUTES pipe_attr
;
1525 HANDLE piperead
, pipewrite
;
1532 user_apc_ran
= FALSE
;
1533 ok(QueueUserAPC(user_apc
, GetCurrentThread(), 0), "couldn't create user apc\n");
1535 pipe_attr
.nLength
= sizeof(SECURITY_ATTRIBUTES
);
1536 pipe_attr
.bInheritHandle
= TRUE
;
1537 pipe_attr
.lpSecurityDescriptor
= NULL
;
1538 ok(CreatePipe(&piperead
, &pipewrite
, &pipe_attr
, 0) != 0, "CreatePipe failed\n");
1539 test_pipe_info(piperead
, FILE_PIPE_SERVER_END
, 4096, 4096, 1);
1540 test_pipe_info(pipewrite
, 0, 4096, 4096, 1);
1541 test_file_access(piperead
, SYNCHRONIZE
| READ_CONTROL
| FILE_WRITE_ATTRIBUTES
1542 | FILE_READ_ATTRIBUTES
| FILE_READ_PROPERTIES
| FILE_READ_DATA
);
1543 test_file_access(pipewrite
, SYNCHRONIZE
| READ_CONTROL
| FILE_WRITE_ATTRIBUTES
1544 | FILE_READ_ATTRIBUTES
| FILE_WRITE_PROPERTIES
| FILE_APPEND_DATA
1547 ok(WriteFile(pipewrite
,PIPENAME
,sizeof(PIPENAME
), &written
, NULL
), "Write to anonymous pipe failed\n");
1548 ok(written
== sizeof(PIPENAME
), "Write to anonymous pipe wrote %d bytes\n", written
);
1549 ok(ReadFile(piperead
,readbuf
,sizeof(readbuf
),&read
, NULL
), "Read from non empty pipe failed\n");
1550 ok(read
== sizeof(PIPENAME
), "Read from anonymous pipe got %d bytes\n", read
);
1551 ok(CloseHandle(pipewrite
), "CloseHandle for the write pipe failed\n");
1552 ok(CloseHandle(piperead
), "CloseHandle for the read pipe failed\n");
1554 /* Now write another chunk*/
1555 ok(CreatePipe(&piperead
, &pipewrite
, &pipe_attr
, 0) != 0, "CreatePipe failed\n");
1556 ok(WriteFile(pipewrite
,PIPENAME
,sizeof(PIPENAME
), &written
, NULL
), "Write to anonymous pipe failed\n");
1557 ok(written
== sizeof(PIPENAME
), "Write to anonymous pipe wrote %d bytes\n", written
);
1558 /* and close the write end, read should still succeed*/
1559 ok(CloseHandle(pipewrite
), "CloseHandle for the Write Pipe failed\n");
1560 ok(ReadFile(piperead
,readbuf
,sizeof(readbuf
),&read
, NULL
), "Read from broken pipe with pending data failed\n");
1561 ok(read
== sizeof(PIPENAME
), "Read from anonymous pipe got %d bytes\n", read
);
1562 /* But now we need to get informed that the pipe is closed */
1563 ok(ReadFile(piperead
,readbuf
,sizeof(readbuf
),&read
, NULL
) == 0, "Broken pipe not detected\n");
1564 ok(CloseHandle(piperead
), "CloseHandle for the read pipe failed\n");
1566 /* Try bigger chunks */
1568 buffer
= HeapAlloc( GetProcessHeap(), 0, size
);
1569 for (i
= 0; i
< size
; i
++) buffer
[i
] = i
;
1570 ok(CreatePipe(&piperead
, &pipewrite
, &pipe_attr
, (size
+ 24)) != 0, "CreatePipe failed\n");
1571 ok(WriteFile(pipewrite
, buffer
, size
, &written
, NULL
), "Write to anonymous pipe failed\n");
1572 ok(written
== size
, "Write to anonymous pipe wrote %d bytes\n", written
);
1573 /* and close the write end, read should still succeed*/
1574 ok(CloseHandle(pipewrite
), "CloseHandle for the Write Pipe failed\n");
1575 memset( buffer
, 0, size
);
1576 ok(ReadFile(piperead
, buffer
, size
, &read
, NULL
), "Read from broken pipe with pending data failed\n");
1577 ok(read
== size
, "Read from anonymous pipe got %d bytes\n", read
);
1578 for (i
= 0; i
< size
; i
++) ok( buffer
[i
] == (BYTE
)i
, "invalid data %x at %x\n", buffer
[i
], i
);
1579 /* But now we need to get informed that the pipe is closed */
1580 ok(ReadFile(piperead
,readbuf
,sizeof(readbuf
),&read
, NULL
) == 0, "Broken pipe not detected\n");
1581 ok(CloseHandle(piperead
), "CloseHandle for the read pipe failed\n");
1582 HeapFree(GetProcessHeap(), 0, buffer
);
1584 ok(user_apc_ran
== FALSE
, "user apc ran, pipe using alertable io mode\n");
1585 SleepEx(0, TRUE
); /* get rid of apc */
1587 ok(CreatePipe(&piperead
, &pipewrite
, &pipe_attr
, 1) != 0, "CreatePipe failed\n");
1588 test_pipe_info(piperead
, FILE_PIPE_SERVER_END
, 1, 1, 1);
1589 test_pipe_info(pipewrite
, 0, 1, 1, 1);
1590 ok(CloseHandle(pipewrite
), "CloseHandle for the Write Pipe failed\n");
1591 ok(CloseHandle(piperead
), "CloseHandle for the read pipe failed\n");
1594 static void test_CloseHandle(void)
1596 static const char testdata
[] = "Hello World";
1597 DWORD state
, numbytes
;
1598 HANDLE hpipe
, hfile
;
1602 hpipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
1603 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1604 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1605 ok(hpipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %u\n", GetLastError());
1607 hfile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1608 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %u\n", GetLastError());
1610 numbytes
= 0xdeadbeef;
1611 ret
= WriteFile(hpipe
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1612 ok(ret
, "WriteFile failed with %u\n", GetLastError());
1613 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1615 numbytes
= 0xdeadbeef;
1616 ret
= PeekNamedPipe(hfile
, NULL
, 0, NULL
, &numbytes
, NULL
);
1617 ok(ret
, "PeekNamedPipe failed with %u\n", GetLastError());
1618 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1620 ret
= CloseHandle(hpipe
);
1621 ok(ret
, "CloseHandle failed with %u\n", GetLastError());
1623 numbytes
= 0xdeadbeef;
1624 memset(buffer
, 0, sizeof(buffer
));
1625 ret
= ReadFile(hfile
, buffer
, 0, &numbytes
, NULL
);
1626 ok(ret
, "ReadFile failed with %u\n", GetLastError());
1627 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
1629 numbytes
= 0xdeadbeef;
1630 ret
= PeekNamedPipe(hfile
, NULL
, 0, NULL
, &numbytes
, NULL
);
1631 ok(ret
, "PeekNamedPipe failed with %u\n", GetLastError());
1632 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1634 numbytes
= 0xdeadbeef;
1635 memset(buffer
, 0, sizeof(buffer
));
1636 ret
= ReadFile(hfile
, buffer
, sizeof(buffer
), &numbytes
, NULL
);
1637 ok(ret
, "ReadFile failed with %u\n", GetLastError());
1638 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1640 ret
= GetNamedPipeHandleStateA(hfile
, &state
, NULL
, NULL
, NULL
, NULL
, 0);
1641 ok(ret
, "GetNamedPipeHandleState failed with %u\n", GetLastError());
1642 state
= PIPE_READMODE_MESSAGE
| PIPE_WAIT
;
1643 ret
= SetNamedPipeHandleState(hfile
, &state
, NULL
, NULL
);
1644 ok(ret
, "SetNamedPipeHandleState failed with %u\n", GetLastError());
1646 SetLastError(0xdeadbeef);
1647 ret
= ReadFile(hfile
, buffer
, 0, &numbytes
, NULL
);
1648 ok(!ret
, "ReadFile unexpectedly succeeded\n");
1649 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1651 numbytes
= 0xdeadbeef;
1652 ret
= PeekNamedPipe(hfile
, NULL
, 0, NULL
, &numbytes
, NULL
);
1653 ok(!ret
&& GetLastError() == ERROR_BROKEN_PIPE
, "PeekNamedPipe returned %x (%u)\n",
1654 ret
, GetLastError());
1655 ok(numbytes
== 0xdeadbeef, "numbytes = %u\n", numbytes
);
1657 SetLastError(0xdeadbeef);
1658 ret
= WriteFile(hfile
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1659 ok(!ret
, "WriteFile unexpectedly succeeded\n");
1660 ok(GetLastError() == ERROR_NO_DATA
, "expected ERROR_NO_DATA, got %u\n", GetLastError());
1664 hpipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
1665 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1666 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1667 ok(hpipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %u\n", GetLastError());
1669 hfile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1670 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %u\n", GetLastError());
1672 numbytes
= 0xdeadbeef;
1673 ret
= WriteFile(hpipe
, testdata
, 0, &numbytes
, NULL
);
1674 ok(ret
, "WriteFile failed with %u\n", GetLastError());
1675 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
1677 ret
= CloseHandle(hpipe
);
1678 ok(ret
, "CloseHandle failed with %u\n", GetLastError());
1680 numbytes
= 0xdeadbeef;
1681 memset(buffer
, 0, sizeof(buffer
));
1682 ret
= ReadFile(hfile
, buffer
, sizeof(buffer
), &numbytes
, NULL
);
1683 ok(ret
, "ReadFile failed with %u\n", GetLastError());
1684 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
1686 SetLastError(0xdeadbeef);
1687 ret
= ReadFile(hfile
, buffer
, 0, &numbytes
, NULL
);
1688 ok(!ret
, "ReadFile unexpectedly succeeded\n");
1689 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1691 ret
= GetNamedPipeHandleStateA(hfile
, &state
, NULL
, NULL
, NULL
, NULL
, 0);
1692 ok(ret
, "GetNamedPipeHandleState failed with %u\n", GetLastError());
1693 state
= PIPE_READMODE_MESSAGE
| PIPE_WAIT
;
1694 ret
= SetNamedPipeHandleState(hfile
, &state
, NULL
, NULL
);
1695 ok(ret
, "SetNamedPipeHandleState failed with %u\n", GetLastError());
1697 SetLastError(0xdeadbeef);
1698 ret
= ReadFile(hfile
, buffer
, 0, &numbytes
, NULL
);
1699 ok(!ret
, "ReadFile unexpectedly succeeded\n");
1700 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1702 SetLastError(0xdeadbeef);
1703 ret
= WriteFile(hfile
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1704 ok(!ret
, "WriteFile unexpectedly succeeded\n");
1705 ok(GetLastError() == ERROR_NO_DATA
, "expected ERROR_NO_DATA, got %u\n", GetLastError());
1709 /* repeat test with hpipe <-> hfile swapped */
1711 hpipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
1712 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1713 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1714 ok(hpipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %u\n", GetLastError());
1716 hfile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1717 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %u\n", GetLastError());
1719 numbytes
= 0xdeadbeef;
1720 ret
= WriteFile(hfile
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1721 ok(ret
, "WriteFile failed with %u\n", GetLastError());
1722 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1724 numbytes
= 0xdeadbeef;
1725 ret
= PeekNamedPipe(hpipe
, NULL
, 0, NULL
, &numbytes
, NULL
);
1726 ok(ret
, "PeekNamedPipe failed with %u\n", GetLastError());
1727 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1729 ret
= CloseHandle(hfile
);
1730 ok(ret
, "CloseHandle failed with %u\n", GetLastError());
1732 numbytes
= 0xdeadbeef;
1733 memset(buffer
, 0, sizeof(buffer
));
1734 ret
= ReadFile(hpipe
, buffer
, 0, &numbytes
, NULL
);
1735 ok(ret
|| GetLastError() == ERROR_MORE_DATA
/* >= Win 8 */,
1736 "ReadFile failed with %u\n", GetLastError());
1737 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
1739 numbytes
= 0xdeadbeef;
1740 ret
= PeekNamedPipe(hpipe
, NULL
, 0, NULL
, &numbytes
, NULL
);
1741 ok(ret
, "PeekNamedPipe failed with %u\n", GetLastError());
1742 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1744 numbytes
= 0xdeadbeef;
1745 memset(buffer
, 0, sizeof(buffer
));
1746 ret
= ReadFile(hpipe
, buffer
, sizeof(buffer
), &numbytes
, NULL
);
1747 ok(ret
, "ReadFile failed with %u\n", GetLastError());
1748 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %u\n", numbytes
);
1750 ret
= GetNamedPipeHandleStateA(hpipe
, &state
, NULL
, NULL
, NULL
, NULL
, 0);
1751 ok(ret
, "GetNamedPipeHandleState failed with %u\n", GetLastError());
1752 state
= PIPE_READMODE_MESSAGE
| PIPE_WAIT
;
1753 ret
= SetNamedPipeHandleState(hpipe
, &state
, NULL
, NULL
);
1754 ok(ret
, "SetNamedPipeHandleState failed with %u\n", GetLastError());
1756 SetLastError(0xdeadbeef);
1757 ret
= ReadFile(hpipe
, buffer
, 0, &numbytes
, NULL
);
1758 ok(!ret
, "ReadFile unexpectedly succeeded\n");
1759 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1761 numbytes
= 0xdeadbeef;
1762 ret
= PeekNamedPipe(hpipe
, NULL
, 0, NULL
, &numbytes
, NULL
);
1763 ok(!ret
&& GetLastError() == ERROR_BROKEN_PIPE
, "PeekNamedPipe returned %x (%u)\n",
1764 ret
, GetLastError());
1765 ok(numbytes
== 0xdeadbeef, "numbytes = %u\n", numbytes
);
1767 SetLastError(0xdeadbeef);
1768 ret
= WriteFile(hpipe
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1769 ok(!ret
, "WriteFile unexpectedly succeeded\n");
1770 ok(GetLastError() == ERROR_NO_DATA
, "expected ERROR_NO_DATA, got %u\n", GetLastError());
1774 hpipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
1775 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1776 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1777 ok(hpipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %u\n", GetLastError());
1779 hfile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1780 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %u\n", GetLastError());
1782 numbytes
= 0xdeadbeef;
1783 ret
= WriteFile(hfile
, testdata
, 0, &numbytes
, NULL
);
1784 ok(ret
, "WriteFile failed with %u\n", GetLastError());
1785 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
1787 ret
= CloseHandle(hfile
);
1788 ok(ret
, "CloseHandle failed with %u\n", GetLastError());
1790 numbytes
= 0xdeadbeef;
1791 memset(buffer
, 0, sizeof(buffer
));
1792 ret
= ReadFile(hpipe
, buffer
, sizeof(buffer
), &numbytes
, NULL
);
1793 ok(ret
, "ReadFile failed with %u\n", GetLastError());
1794 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
1796 SetLastError(0xdeadbeef);
1797 ret
= ReadFile(hpipe
, buffer
, 0, &numbytes
, NULL
);
1798 ok(!ret
, "ReadFile unexpectedly succeeded\n");
1799 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1801 ret
= GetNamedPipeHandleStateA(hpipe
, &state
, NULL
, NULL
, NULL
, NULL
, 0);
1802 ok(ret
, "GetNamedPipeHandleState failed with %u\n", GetLastError());
1803 state
= PIPE_READMODE_MESSAGE
| PIPE_WAIT
;
1804 ret
= SetNamedPipeHandleState(hpipe
, &state
, NULL
, NULL
);
1805 ok(ret
, "SetNamedPipeHandleState failed with %u\n", GetLastError());
1807 SetLastError(0xdeadbeef);
1808 ret
= ReadFile(hpipe
, buffer
, 0, &numbytes
, NULL
);
1809 ok(!ret
, "ReadFile unexpectedly succeeded\n");
1810 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1812 SetLastError(0xdeadbeef);
1813 ret
= WriteFile(hpipe
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1814 ok(!ret
, "WriteFile unexpectedly succeeded\n");
1815 ok(GetLastError() == ERROR_NO_DATA
, "expected ERROR_NO_DATA, got %u\n", GetLastError());
1820 struct named_pipe_client_params
1822 DWORD security_flags
;
1827 #define PIPE_NAME "\\\\.\\pipe\\named_pipe_test"
1829 static DWORD CALLBACK
named_pipe_client_func(LPVOID p
)
1831 struct named_pipe_client_params
*params
= p
;
1834 const char message
[] = "Test";
1835 DWORD bytes_read
, bytes_written
;
1837 TOKEN_PRIVILEGES
*Privileges
= NULL
;
1843 /* modify the token so we can tell if the pipe impersonation
1844 * token reverts to the process token */
1845 ret
= AdjustTokenPrivileges(params
->token
, TRUE
, NULL
, 0, NULL
, NULL
);
1846 ok(ret
, "AdjustTokenPrivileges failed with error %d\n", GetLastError());
1848 ret
= SetThreadToken(NULL
, params
->token
);
1849 ok(ret
, "SetThreadToken failed with error %d\n", GetLastError());
1854 HANDLE process_token
;
1856 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
|TOKEN_ADJUST_PRIVILEGES
, &process_token
);
1857 ok(ret
, "OpenProcessToken failed with error %d\n", GetLastError());
1859 ret
= GetTokenInformation(process_token
, TokenPrivileges
, NULL
, 0, &Size
);
1860 ok(!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "GetTokenInformation(TokenPrivileges) failed with %d\n", GetLastError());
1861 Privileges
= HeapAlloc(GetProcessHeap(), 0, Size
);
1862 ret
= GetTokenInformation(process_token
, TokenPrivileges
, Privileges
, Size
, &Size
);
1863 ok(ret
, "GetTokenInformation(TokenPrivileges) failed with %d\n", GetLastError());
1865 ret
= AdjustTokenPrivileges(process_token
, TRUE
, NULL
, 0, NULL
, NULL
);
1866 ok(ret
, "AdjustTokenPrivileges failed with error %d\n", GetLastError());
1868 CloseHandle(process_token
);
1871 pipe
= CreateFileA(PIPE_NAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, params
->security_flags
, NULL
);
1872 ok(pipe
!= INVALID_HANDLE_VALUE
, "CreateFile for pipe failed with error %d\n", GetLastError());
1874 ret
= WriteFile(pipe
, message
, sizeof(message
), &bytes_written
, NULL
);
1875 ok(ret
, "WriteFile failed with error %d\n", GetLastError());
1877 ret
= ReadFile(pipe
, &dummy
, sizeof(dummy
), &bytes_read
, NULL
);
1878 ok(ret
, "ReadFile failed with error %d\n", GetLastError());
1884 ret
= RevertToSelf();
1885 ok(ret
, "RevertToSelf failed with error %d\n", GetLastError());
1889 ret
= AdjustTokenPrivileges(params
->token
, TRUE
, NULL
, 0, NULL
, NULL
);
1890 ok(ret
, "AdjustTokenPrivileges failed with error %d\n", GetLastError());
1895 HANDLE process_token
;
1897 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES
, &process_token
);
1898 ok(ret
, "OpenProcessToken failed with error %d\n", GetLastError());
1900 ret
= AdjustTokenPrivileges(process_token
, FALSE
, Privileges
, 0, NULL
, NULL
);
1901 ok(ret
, "AdjustTokenPrivileges failed with error %d\n", GetLastError());
1903 HeapFree(GetProcessHeap(), 0, Privileges
);
1905 CloseHandle(process_token
);
1908 ret
= WriteFile(pipe
, message
, sizeof(message
), &bytes_written
, NULL
);
1909 ok(ret
, "WriteFile failed with error %d\n", GetLastError());
1911 ret
= ReadFile(pipe
, &dummy
, sizeof(dummy
), &bytes_read
, NULL
);
1912 ok(ret
, "ReadFile failed with error %d\n", GetLastError());
1919 static HANDLE
make_impersonation_token(DWORD Access
, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
1921 HANDLE ProcessToken
;
1922 HANDLE Token
= NULL
;
1925 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE
, &ProcessToken
);
1926 ok(ret
, "OpenProcessToken failed with error %d\n", GetLastError());
1928 ret
= pDuplicateTokenEx(ProcessToken
, Access
, NULL
, ImpersonationLevel
, TokenImpersonation
, &Token
);
1929 ok(ret
, "DuplicateToken failed with error %d\n", GetLastError());
1931 CloseHandle(ProcessToken
);
1936 static void test_ImpersonateNamedPipeClient(HANDLE hClientToken
, DWORD security_flags
, BOOL revert
, void (*test_func
)(int, HANDLE
))
1945 struct named_pipe_client_params params
;
1947 DWORD dwBytesWritten
;
1948 HANDLE hToken
= NULL
;
1949 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
;
1952 hPipeServer
= CreateNamedPipeA(PIPE_NAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_READMODE_BYTE
| PIPE_WAIT
, 1, 100, 100, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1953 ok(hPipeServer
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with error %d\n", GetLastError());
1955 params
.security_flags
= security_flags
;
1956 params
.token
= hClientToken
;
1957 params
.revert
= revert
;
1958 hThread
= CreateThread(NULL
, 0, named_pipe_client_func
, ¶ms
, 0, &dwTid
);
1959 ok(hThread
!= NULL
, "CreateThread failed with error %d\n", GetLastError());
1961 SetLastError(0xdeadbeef);
1962 ret
= ImpersonateNamedPipeClient(hPipeServer
);
1963 error
= GetLastError();
1964 ok(ret
/* win2k3 */ || (error
== ERROR_CANNOT_IMPERSONATE
),
1965 "ImpersonateNamedPipeClient should have failed with ERROR_CANNOT_IMPERSONATE instead of %d\n", GetLastError());
1967 ret
= ConnectNamedPipe(hPipeServer
, NULL
);
1968 ok(ret
|| (GetLastError() == ERROR_PIPE_CONNECTED
), "ConnectNamedPipe failed with error %d\n", GetLastError());
1970 ret
= ReadFile(hPipeServer
, buffer
, sizeof(buffer
), &dwBytesRead
, NULL
);
1971 ok(ret
, "ReadFile failed with error %d\n", GetLastError());
1973 ret
= ImpersonateNamedPipeClient(hPipeServer
);
1974 ok(ret
, "ImpersonateNamedPipeClient failed with error %d\n", GetLastError());
1976 ret
= OpenThreadToken(GetCurrentThread(), TOKEN_QUERY
, FALSE
, &hToken
);
1977 ok(ret
, "OpenThreadToken failed with error %d\n", GetLastError());
1979 (*test_func
)(0, hToken
);
1981 ImpersonationLevel
= 0xdeadbeef; /* to avoid false positives */
1982 ret
= GetTokenInformation(hToken
, TokenImpersonationLevel
, &ImpersonationLevel
, sizeof(ImpersonationLevel
), &size
);
1983 ok(ret
, "GetTokenInformation(TokenImpersonationLevel) failed with error %d\n", GetLastError());
1984 ok(ImpersonationLevel
== SecurityImpersonation
, "ImpersonationLevel should have been SecurityImpersonation(%d) instead of %d\n", SecurityImpersonation
, ImpersonationLevel
);
1986 CloseHandle(hToken
);
1990 ret
= WriteFile(hPipeServer
, &dummy
, sizeof(dummy
), &dwBytesWritten
, NULL
);
1991 ok(ret
, "WriteFile failed with error %d\n", GetLastError());
1993 ret
= ReadFile(hPipeServer
, buffer
, sizeof(buffer
), &dwBytesRead
, NULL
);
1994 ok(ret
, "ReadFile failed with error %d\n", GetLastError());
1996 ret
= ImpersonateNamedPipeClient(hPipeServer
);
1997 ok(ret
, "ImpersonateNamedPipeClient failed with error %d\n", GetLastError());
1999 ret
= OpenThreadToken(GetCurrentThread(), TOKEN_QUERY
, FALSE
, &hToken
);
2000 ok(ret
, "OpenThreadToken failed with error %d\n", GetLastError());
2002 (*test_func
)(1, hToken
);
2004 CloseHandle(hToken
);
2008 ret
= WriteFile(hPipeServer
, &dummy
, sizeof(dummy
), &dwBytesWritten
, NULL
);
2009 ok(ret
, "WriteFile failed with error %d\n", GetLastError());
2011 WaitForSingleObject(hThread
, INFINITE
);
2013 ret
= ImpersonateNamedPipeClient(hPipeServer
);
2014 ok(ret
, "ImpersonateNamedPipeClient failed with error %d\n", GetLastError());
2018 CloseHandle(hThread
);
2019 CloseHandle(hPipeServer
);
2022 static BOOL
are_all_privileges_disabled(HANDLE hToken
)
2025 TOKEN_PRIVILEGES
*Privileges
= NULL
;
2027 BOOL all_privs_disabled
= TRUE
;
2030 ret
= GetTokenInformation(hToken
, TokenPrivileges
, NULL
, 0, &Size
);
2031 if (!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
2033 Privileges
= HeapAlloc(GetProcessHeap(), 0, Size
);
2034 ret
= GetTokenInformation(hToken
, TokenPrivileges
, Privileges
, Size
, &Size
);
2037 HeapFree(GetProcessHeap(), 0, Privileges
);
2044 for (i
= 0; i
< Privileges
->PrivilegeCount
; i
++)
2046 if (Privileges
->Privileges
[i
].Attributes
& SE_PRIVILEGE_ENABLED
)
2048 all_privs_disabled
= FALSE
;
2053 HeapFree(GetProcessHeap(), 0, Privileges
);
2055 return all_privs_disabled
;
2058 static DWORD
get_privilege_count(HANDLE hToken
)
2060 TOKEN_STATISTICS Statistics
;
2061 DWORD Size
= sizeof(Statistics
);
2064 ret
= GetTokenInformation(hToken
, TokenStatistics
, &Statistics
, Size
, &Size
);
2065 ok(ret
, "GetTokenInformation(TokenStatistics)\n");
2066 if (!ret
) return -1;
2068 return Statistics
.PrivilegeCount
;
2071 static void test_no_sqos_no_token(int call_index
, HANDLE hToken
)
2078 priv_count
= get_privilege_count(hToken
);
2080 ok(priv_count
== 0, "privilege count should have been 0 instead of %d\n", priv_count
);
2083 priv_count
= get_privilege_count(hToken
);
2084 ok(priv_count
> 0, "privilege count should now be > 0 instead of 0\n");
2085 ok(!are_all_privileges_disabled(hToken
), "impersonated token should not have been modified\n");
2088 ok(0, "shouldn't happen\n");
2092 static void test_no_sqos(int call_index
, HANDLE hToken
)
2097 ok(!are_all_privileges_disabled(hToken
), "token should be a copy of the process one\n");
2101 ok(are_all_privileges_disabled(hToken
), "impersonated token should have been modified\n");
2104 ok(0, "shouldn't happen\n");
2108 static void test_static_context(int call_index
, HANDLE hToken
)
2113 ok(!are_all_privileges_disabled(hToken
), "token should be a copy of the process one\n");
2116 ok(!are_all_privileges_disabled(hToken
), "impersonated token should not have been modified\n");
2119 ok(0, "shouldn't happen\n");
2123 static void test_dynamic_context(int call_index
, HANDLE hToken
)
2128 ok(!are_all_privileges_disabled(hToken
), "token should be a copy of the process one\n");
2132 ok(are_all_privileges_disabled(hToken
), "impersonated token should have been modified\n");
2135 ok(0, "shouldn't happen\n");
2139 static void test_dynamic_context_no_token(int call_index
, HANDLE hToken
)
2144 ok(are_all_privileges_disabled(hToken
), "token should be a copy of the process one\n");
2147 ok(!are_all_privileges_disabled(hToken
), "process token modification should have been detected and impersonation token updated\n");
2150 ok(0, "shouldn't happen\n");
2154 static void test_no_sqos_revert(int call_index
, HANDLE hToken
)
2160 priv_count
= get_privilege_count(hToken
);
2162 ok(priv_count
== 0, "privilege count should have been 0 instead of %d\n", priv_count
);
2165 priv_count
= get_privilege_count(hToken
);
2166 ok(priv_count
> 0, "privilege count should now be > 0 instead of 0\n");
2167 ok(!are_all_privileges_disabled(hToken
), "impersonated token should not have been modified\n");
2170 ok(0, "shouldn't happen\n");
2174 static void test_static_context_revert(int call_index
, HANDLE hToken
)
2180 ok(are_all_privileges_disabled(hToken
), "privileges should have been disabled\n");
2184 ok(are_all_privileges_disabled(hToken
), "impersonated token should not have been modified\n");
2187 ok(0, "shouldn't happen\n");
2191 static void test_dynamic_context_revert(int call_index
, HANDLE hToken
)
2197 ok(are_all_privileges_disabled(hToken
), "privileges should have been disabled\n");
2200 ok(!are_all_privileges_disabled(hToken
), "impersonated token should now be process token\n");
2203 ok(0, "shouldn't happen\n");
2207 static void test_impersonation(void)
2209 HANDLE hClientToken
;
2210 HANDLE hProcessToken
;
2213 if( !pDuplicateTokenEx
) {
2214 skip("DuplicateTokenEx not found\n");
2218 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
, &hProcessToken
);
2221 skip("couldn't open process token, skipping impersonation tests\n");
2225 if (!get_privilege_count(hProcessToken
) || are_all_privileges_disabled(hProcessToken
))
2227 skip("token didn't have any privileges or they were all disabled. token not suitable for impersonation tests\n");
2228 CloseHandle(hProcessToken
);
2231 CloseHandle(hProcessToken
);
2233 test_ImpersonateNamedPipeClient(NULL
, 0, FALSE
, test_no_sqos_no_token
);
2234 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2235 test_ImpersonateNamedPipeClient(hClientToken
, 0, FALSE
, test_no_sqos
);
2236 CloseHandle(hClientToken
);
2237 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2238 test_ImpersonateNamedPipeClient(hClientToken
,
2239 SECURITY_SQOS_PRESENT
| SECURITY_IMPERSONATION
, FALSE
,
2240 test_static_context
);
2241 CloseHandle(hClientToken
);
2242 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2243 test_ImpersonateNamedPipeClient(hClientToken
,
2244 SECURITY_SQOS_PRESENT
| SECURITY_CONTEXT_TRACKING
| SECURITY_IMPERSONATION
,
2245 FALSE
, test_dynamic_context
);
2246 CloseHandle(hClientToken
);
2247 test_ImpersonateNamedPipeClient(NULL
,
2248 SECURITY_SQOS_PRESENT
| SECURITY_CONTEXT_TRACKING
| SECURITY_IMPERSONATION
,
2249 FALSE
, test_dynamic_context_no_token
);
2251 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2252 test_ImpersonateNamedPipeClient(hClientToken
, 0, TRUE
, test_no_sqos_revert
);
2253 CloseHandle(hClientToken
);
2254 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2255 test_ImpersonateNamedPipeClient(hClientToken
,
2256 SECURITY_SQOS_PRESENT
| SECURITY_IMPERSONATION
, TRUE
,
2257 test_static_context_revert
);
2258 CloseHandle(hClientToken
);
2259 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2260 test_ImpersonateNamedPipeClient(hClientToken
,
2261 SECURITY_SQOS_PRESENT
| SECURITY_CONTEXT_TRACKING
| SECURITY_IMPERSONATION
,
2262 TRUE
, test_dynamic_context_revert
);
2263 CloseHandle(hClientToken
);
2266 struct overlapped_server_args
2268 HANDLE pipe_created
;
2271 static DWORD CALLBACK
overlapped_server(LPVOID arg
)
2276 struct overlapped_server_args
*a
= arg
;
2280 pipe
= CreateNamedPipeA("\\\\.\\pipe\\my pipe", FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
, PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
, 1, 0, 0, 100000, NULL
);
2281 ok(pipe
!= NULL
, "pipe NULL\n");
2283 ol
.hEvent
= CreateEventA(0, 1, 0, 0);
2284 ok(ol
.hEvent
!= NULL
, "event NULL\n");
2285 ret
= ConnectNamedPipe(pipe
, &ol
);
2286 err
= GetLastError();
2287 ok(ret
== 0, "ret %d\n", ret
);
2288 ok(err
== ERROR_IO_PENDING
, "gle %d\n", err
);
2289 SetEvent(a
->pipe_created
);
2291 ret
= WaitForSingleObjectEx(ol
.hEvent
, INFINITE
, 1);
2292 ok(ret
== WAIT_OBJECT_0
, "ret %x\n", ret
);
2294 ret
= GetOverlappedResult(pipe
, &ol
, &num
, 1);
2295 ok(ret
== 1, "ret %d\n", ret
);
2297 /* This should block */
2298 ret
= ReadFile(pipe
, buf
, sizeof(buf
), &num
, NULL
);
2299 ok(ret
== 1, "ret %d\n", ret
);
2301 DisconnectNamedPipe(pipe
);
2303 ret
= ConnectNamedPipe(pipe
, &ol
);
2304 err
= GetLastError();
2305 ok(ret
== 0, "ret %d\n", ret
);
2306 ok(err
== ERROR_IO_PENDING
, "gle %d\n", err
);
2308 ret
= WaitForSingleObjectEx(ol
.hEvent
, INFINITE
, 1);
2309 ok(ret
== WAIT_OBJECT_0
, "ret %x\n", ret
);
2311 ret
= GetOverlappedResult(pipe
, &ol
, &num
, 1);
2312 err
= GetLastError();
2313 ok(ret
== 0, "ret %d\n", ret
);
2314 ok(err
== ERROR_OPERATION_ABORTED
, "gle %d\n", err
);
2316 CloseHandle(ol
.hEvent
);
2321 static void test_overlapped(void)
2324 HANDLE thread
, pipe
;
2326 struct overlapped_server_args args
;
2328 args
.pipe_created
= CreateEventA(0, 1, 0, 0);
2329 thread
= CreateThread(NULL
, 0, overlapped_server
, &args
, 0, &tid
);
2331 WaitForSingleObject(args
.pipe_created
, INFINITE
);
2332 pipe
= CreateFileA("\\\\.\\pipe\\my pipe", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
2333 ok(pipe
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2335 /* Sleep to try to get the ReadFile in the server to occur before the following WriteFile */
2338 ret
= WriteFile(pipe
, "x", 1, &num
, NULL
);
2339 ok(ret
, "WriteFile failed with error %d\n", GetLastError());
2341 WaitForSingleObject(thread
, INFINITE
);
2343 CloseHandle(args
.pipe_created
);
2344 CloseHandle(thread
);
2347 static void test_overlapped_error(void)
2349 HANDLE pipe
, file
, event
;
2350 DWORD err
, numbytes
;
2351 OVERLAPPED overlapped
;
2354 event
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
2355 ok(event
!= NULL
, "CreateEventA failed with %u\n", GetLastError());
2357 pipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
2358 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
2359 1, 1024, 1024, NMPWAIT_WAIT_FOREVER
, NULL
);
2360 ok(pipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %u\n", GetLastError());
2362 memset(&overlapped
, 0, sizeof(overlapped
));
2363 overlapped
.hEvent
= event
;
2364 ret
= ConnectNamedPipe(pipe
, &overlapped
);
2365 err
= GetLastError();
2366 ok(ret
== FALSE
, "ConnectNamedPipe succeeded\n");
2367 ok(err
== ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %u\n", err
);
2369 file
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
,
2370 OPEN_EXISTING
, FILE_FLAG_OVERLAPPED
, 0);
2371 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %u\n", GetLastError());
2373 numbytes
= 0xdeadbeef;
2374 ret
= GetOverlappedResult(pipe
, &overlapped
, &numbytes
, TRUE
);
2375 ok(ret
== TRUE
, "GetOverlappedResult failed\n");
2376 ok(numbytes
== 0, "expected 0, got %u\n", numbytes
);
2377 ok(overlapped
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08lx\n", overlapped
.Internal
);
2382 pipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
2383 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
2384 1, 1024, 1024, NMPWAIT_WAIT_FOREVER
, NULL
);
2385 ok(pipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %u\n", GetLastError());
2387 file
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
,
2388 OPEN_EXISTING
, FILE_FLAG_OVERLAPPED
, 0);
2389 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %u\n", GetLastError());
2391 memset(&overlapped
, 0, sizeof(overlapped
));
2392 overlapped
.hEvent
= event
;
2393 ret
= ConnectNamedPipe(pipe
, &overlapped
);
2394 err
= GetLastError();
2395 ok(ret
== FALSE
, "ConnectNamedPipe succeeded\n");
2396 ok(err
== ERROR_PIPE_CONNECTED
, "expected ERROR_PIPE_CONNECTED, got %u\n", err
);
2397 ok(overlapped
.Internal
== STATUS_PENDING
, "expected STATUS_PENDING, got %08lx\n", overlapped
.Internal
);
2405 static void test_NamedPipeHandleState(void)
2407 HANDLE server
, client
;
2409 DWORD state
, instances
, maxCollectionCount
, collectDataTimeout
;
2410 char userName
[MAX_PATH
];
2412 server
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
2413 /* dwOpenMode */ PIPE_TYPE_BYTE
| PIPE_WAIT
,
2414 /* nMaxInstances */ 1,
2415 /* nOutBufSize */ 1024,
2416 /* nInBufSize */ 1024,
2417 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2418 /* lpSecurityAttrib */ NULL
);
2419 ok(server
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2420 ret
= GetNamedPipeHandleStateA(server
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
2421 ok(ret
, "GetNamedPipeHandleState failed: %d\n", GetLastError());
2422 ret
= GetNamedPipeHandleStateA(server
, &state
, &instances
, NULL
, NULL
, NULL
,
2424 ok(ret
, "GetNamedPipeHandleState failed: %d\n", GetLastError());
2427 ok(state
== 0, "unexpected state %08x\n", state
);
2428 ok(instances
== 1, "expected 1 instances, got %d\n", instances
);
2430 /* Some parameters have no meaning, and therefore can't be retrieved,
2433 SetLastError(0xdeadbeef);
2434 ret
= GetNamedPipeHandleStateA(server
, &state
, &instances
, &maxCollectionCount
,
2435 &collectDataTimeout
, userName
, ARRAY_SIZE(userName
));
2437 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2438 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2439 /* A byte-mode pipe server can't be changed to message mode. */
2440 state
= PIPE_READMODE_MESSAGE
;
2441 SetLastError(0xdeadbeef);
2442 ret
= SetNamedPipeHandleState(server
, &state
, NULL
, NULL
);
2443 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2444 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2446 client
= CreateFileA(PIPENAME
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
2447 OPEN_EXISTING
, 0, NULL
);
2448 ok(client
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2450 state
= PIPE_READMODE_BYTE
;
2451 ret
= SetNamedPipeHandleState(client
, &state
, NULL
, NULL
);
2452 ok(ret
, "SetNamedPipeHandleState failed: %d\n", GetLastError());
2453 /* A byte-mode pipe client can't be changed to message mode, either. */
2454 state
= PIPE_READMODE_MESSAGE
;
2455 SetLastError(0xdeadbeef);
2456 ret
= SetNamedPipeHandleState(server
, &state
, NULL
, NULL
);
2457 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2458 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2460 CloseHandle(client
);
2461 CloseHandle(server
);
2463 server
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
2464 /* dwOpenMode */ PIPE_TYPE_MESSAGE
| PIPE_WAIT
,
2465 /* nMaxInstances */ 1,
2466 /* nOutBufSize */ 1024,
2467 /* nInBufSize */ 1024,
2468 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2469 /* lpSecurityAttrib */ NULL
);
2470 ok(server
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2471 ret
= GetNamedPipeHandleStateA(server
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
2472 ok(ret
, "GetNamedPipeHandleState failed: %d\n", GetLastError());
2473 ret
= GetNamedPipeHandleStateA(server
, &state
, &instances
, NULL
, NULL
, NULL
,
2475 ok(ret
, "GetNamedPipeHandleState failed: %d\n", GetLastError());
2478 ok(state
== 0, "unexpected state %08x\n", state
);
2479 ok(instances
== 1, "expected 1 instances, got %d\n", instances
);
2481 /* In contrast to byte-mode pipes, a message-mode pipe server can be
2482 * changed to byte mode.
2484 state
= PIPE_READMODE_BYTE
;
2485 ret
= SetNamedPipeHandleState(server
, &state
, NULL
, NULL
);
2486 ok(ret
, "SetNamedPipeHandleState failed: %d\n", GetLastError());
2488 client
= CreateFileA(PIPENAME
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
2489 OPEN_EXISTING
, 0, NULL
);
2490 ok(client
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2492 state
= PIPE_READMODE_MESSAGE
;
2493 ret
= SetNamedPipeHandleState(client
, &state
, NULL
, NULL
);
2494 ok(ret
, "SetNamedPipeHandleState failed: %d\n", GetLastError());
2495 /* A message-mode pipe client can also be changed to byte mode.
2497 state
= PIPE_READMODE_BYTE
;
2498 ret
= SetNamedPipeHandleState(client
, &state
, NULL
, NULL
);
2499 ok(ret
, "SetNamedPipeHandleState failed: %d\n", GetLastError());
2501 CloseHandle(client
);
2502 CloseHandle(server
);
2505 static void test_GetNamedPipeInfo(void)
2509 server
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
2510 /* dwOpenMode */ PIPE_TYPE_BYTE
| PIPE_WAIT
,
2511 /* nMaxInstances */ 1,
2512 /* nOutBufSize */ 1024,
2513 /* nInBufSize */ 1024,
2514 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2515 /* lpSecurityAttrib */ NULL
);
2516 ok(server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
2518 test_pipe_info(server
, PIPE_SERVER_END
| PIPE_TYPE_BYTE
, 1024, 1024, 1);
2520 CloseHandle(server
);
2522 server
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
2523 /* dwOpenMode */ PIPE_TYPE_MESSAGE
| PIPE_NOWAIT
,
2524 /* nMaxInstances */ 3,
2525 /* nOutBufSize */ 1024,
2526 /* nInBufSize */ 1024,
2527 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2528 /* lpSecurityAttrib */ NULL
);
2529 ok(server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
2531 test_pipe_info(server
, PIPE_SERVER_END
| PIPE_TYPE_MESSAGE
, 1024, 1024, 3);
2533 CloseHandle(server
);
2535 server
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
,
2536 /* dwOpenMode */ PIPE_TYPE_MESSAGE
| PIPE_WAIT
,
2537 /* nMaxInstances */ 1,
2538 /* nOutBufSize */ 0,
2540 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2541 /* lpSecurityAttrib */ NULL
);
2542 ok(server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
2544 test_pipe_info(server
, PIPE_SERVER_END
| PIPE_TYPE_MESSAGE
, 0, 0, 1);
2546 CloseHandle(server
);
2548 server
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
,
2549 /* dwOpenMode */ PIPE_TYPE_MESSAGE
| PIPE_WAIT
,
2550 /* nMaxInstances */ 1,
2551 /* nOutBufSize */ 0xf000,
2552 /* nInBufSize */ 0xf000,
2553 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2554 /* lpSecurityAttrib */ NULL
);
2555 ok(server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
2557 test_pipe_info(server
, PIPE_SERVER_END
| PIPE_TYPE_MESSAGE
, 0xf000, 0xf000, 1);
2559 CloseHandle(server
);
2562 static void test_readfileex_pending(void)
2564 HANDLE server
, client
, event
;
2566 DWORD err
, wait
, num_bytes
;
2567 OVERLAPPED overlapped
;
2568 char read_buf
[1024];
2569 char write_buf
[1024];
2570 const char test_string
[] = "test";
2573 server
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
,
2574 /* dwOpenMode */ PIPE_TYPE_BYTE
| PIPE_WAIT
,
2575 /* nMaxInstances */ 1,
2576 /* nOutBufSize */ 1024,
2577 /* nInBufSize */ 1024,
2578 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2579 /* lpSecurityAttrib */ NULL
);
2580 ok(server
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2582 event
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
2583 ok(event
!= NULL
, "CreateEventA failed\n");
2585 memset(&overlapped
, 0, sizeof(overlapped
));
2586 overlapped
.hEvent
= event
;
2588 ret
= ConnectNamedPipe(server
, &overlapped
);
2589 err
= GetLastError();
2590 ok(ret
== FALSE
, "ConnectNamedPipe succeeded\n");
2591 ok(err
== ERROR_IO_PENDING
, "ConnectNamedPipe set error %i\n", err
);
2593 wait
= WaitForSingleObject(event
, 0);
2594 ok(wait
== WAIT_TIMEOUT
, "WaitForSingleObject returned %x\n", wait
);
2596 client
= CreateFileA(PIPENAME
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
2597 OPEN_EXISTING
, 0, NULL
);
2598 ok(client
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2600 wait
= WaitForSingleObject(event
, 0);
2601 ok(wait
== WAIT_OBJECT_0
, "WaitForSingleObject returned %x\n", wait
);
2603 /* Start a read that can't complete immediately. */
2604 completion_called
= 0;
2606 ret
= ReadFileEx(server
, read_buf
, sizeof(read_buf
), &overlapped
, completion_routine
);
2607 ok(ret
== TRUE
, "ReadFileEx failed, err=%i\n", GetLastError());
2608 ok(completion_called
== 0, "completion routine called before ReadFileEx returned\n");
2610 ret
= WriteFile(client
, test_string
, strlen(test_string
), &num_bytes
, NULL
);
2611 ok(ret
== TRUE
, "WriteFile failed\n");
2612 ok(num_bytes
== strlen(test_string
), "only %i bytes written\n", num_bytes
);
2614 ok(completion_called
== 0, "completion routine called during WriteFile\n");
2616 wait
= WaitForSingleObjectEx(event
, 0, TRUE
);
2617 ok(wait
== WAIT_IO_COMPLETION
|| wait
== WAIT_OBJECT_0
, "WaitForSingleObjectEx returned %x\n", wait
);
2619 ok(completion_called
== 1, "completion not called after writing pipe\n");
2620 ok(completion_errorcode
== 0, "completion called with error %x\n", completion_errorcode
);
2621 ok(completion_num_bytes
== strlen(test_string
), "ReadFileEx returned only %d bytes\n", completion_num_bytes
);
2622 ok(completion_lpoverlapped
== &overlapped
, "completion called with wrong overlapped pointer\n");
2623 ok(!memcmp(test_string
, read_buf
, strlen(test_string
)), "ReadFileEx read wrong bytes\n");
2625 /* Make writes until the pipe is full and the write fails */
2626 memset(write_buf
, 0xaa, sizeof(write_buf
));
2627 for (i
=0; i
<256; i
++)
2629 completion_called
= 0;
2631 ret
= WriteFileEx(server
, write_buf
, sizeof(write_buf
), &overlapped
, completion_routine
);
2632 err
= GetLastError();
2634 ok(completion_called
== 0, "completion routine called during WriteFileEx\n");
2636 wait
= WaitForSingleObjectEx(event
, 0, TRUE
);
2638 if (wait
== WAIT_TIMEOUT
)
2639 /* write couldn't complete immediately, presumably the pipe is full */
2642 ok(wait
== WAIT_IO_COMPLETION
|| wait
== WAIT_OBJECT_0
, "WaitForSingleObject returned %x\n", wait
);
2644 ok(ret
== TRUE
, "WriteFileEx failed, err=%i\n", err
);
2645 ok(completion_errorcode
== 0, "completion called with error %x\n", completion_errorcode
);
2646 ok(completion_lpoverlapped
== &overlapped
, "completion called with wrong overlapped pointer\n");
2649 ok(ret
== TRUE
, "WriteFileEx failed, err=%i\n", err
);
2650 ok(completion_called
== 0, "completion routine called but wait timed out\n");
2651 ok(completion_errorcode
== 0, "completion called with error %x\n", completion_errorcode
);
2652 ok(completion_lpoverlapped
== &overlapped
, "completion called with wrong overlapped pointer\n");
2654 /* free up some space in the pipe */
2655 for (i
=0; i
<256; i
++)
2657 ret
= ReadFile(client
, read_buf
, sizeof(read_buf
), &num_bytes
, NULL
);
2658 ok(ret
== TRUE
, "ReadFile failed\n");
2660 ok(completion_called
== 0, "completion routine called during ReadFile\n");
2662 wait
= WaitForSingleObjectEx(event
, 0, TRUE
);
2663 ok(wait
== WAIT_IO_COMPLETION
|| wait
== WAIT_OBJECT_0
|| wait
== WAIT_TIMEOUT
,
2664 "WaitForSingleObject returned %x\n", wait
);
2665 if (wait
!= WAIT_TIMEOUT
) break;
2668 ok(completion_called
== 1, "completion routine not called\n");
2669 ok(completion_errorcode
== 0, "completion called with error %x\n", completion_errorcode
);
2670 ok(completion_lpoverlapped
== &overlapped
, "completion called with wrong overlapped pointer\n");
2672 num_bytes
= 0xdeadbeef;
2673 SetLastError(0xdeadbeef);
2674 ret
= ReadFile(INVALID_HANDLE_VALUE
, read_buf
, 0, &num_bytes
, NULL
);
2675 ok(!ret
, "ReadFile should fail\n");
2676 ok(GetLastError() == ERROR_INVALID_HANDLE
, "wrong error %u\n", GetLastError());
2677 ok(num_bytes
== 0, "expected 0, got %u\n", num_bytes
);
2679 S(U(overlapped
)).Offset
= 0;
2680 S(U(overlapped
)).OffsetHigh
= 0;
2681 overlapped
.Internal
= -1;
2682 overlapped
.InternalHigh
= -1;
2683 overlapped
.hEvent
= event
;
2684 num_bytes
= 0xdeadbeef;
2685 SetLastError(0xdeadbeef);
2686 ret
= ReadFile(server
, read_buf
, 0, &num_bytes
, &overlapped
);
2687 ok(!ret
, "ReadFile should fail\n");
2688 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
2689 ok(num_bytes
== 0, "bytes %u\n", num_bytes
);
2690 ok((NTSTATUS
)overlapped
.Internal
== STATUS_PENDING
, "expected STATUS_PENDING, got %#lx\n", overlapped
.Internal
);
2691 ok(overlapped
.InternalHigh
== -1, "expected -1, got %lu\n", overlapped
.InternalHigh
);
2693 wait
= WaitForSingleObject(event
, 100);
2694 ok(wait
== WAIT_TIMEOUT
, "WaitForSingleObject returned %x\n", wait
);
2696 num_bytes
= 0xdeadbeef;
2697 ret
= WriteFile(client
, test_string
, 1, &num_bytes
, NULL
);
2698 ok(ret
, "WriteFile failed\n");
2699 ok(num_bytes
== 1, "bytes %u\n", num_bytes
);
2701 wait
= WaitForSingleObject(event
, 100);
2702 ok(wait
== WAIT_OBJECT_0
, "WaitForSingleObject returned %x\n", wait
);
2704 ok(num_bytes
== 1, "bytes %u\n", num_bytes
);
2705 ok((NTSTATUS
)overlapped
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#lx\n", overlapped
.Internal
);
2706 ok(overlapped
.InternalHigh
== 0, "expected 0, got %lu\n", overlapped
.InternalHigh
);
2708 /* read the pending byte and clear the pipe */
2709 num_bytes
= 0xdeadbeef;
2710 ret
= ReadFile(server
, read_buf
, 1, &num_bytes
, &overlapped
);
2711 ok(ret
, "ReadFile failed\n");
2712 ok(num_bytes
== 1, "bytes %u\n", num_bytes
);
2714 CloseHandle(client
);
2715 CloseHandle(server
);
2719 #define test_peek_pipe(a,b,c,d) _test_peek_pipe(__LINE__,a,b,c,d)
2720 static void _test_peek_pipe(unsigned line
, HANDLE pipe
, DWORD expected_read
, DWORD expected_avail
, DWORD expected_message_length
)
2722 DWORD bytes_read
= 0xdeadbeed, avail
= 0xdeadbeef, left
= 0xdeadbeed;
2724 FILE_PIPE_PEEK_BUFFER
*peek_buf
= (void*)buf
;
2729 r
= PeekNamedPipe(pipe
, buf
, sizeof(buf
), &bytes_read
, &avail
, &left
);
2730 ok_(__FILE__
,line
)(r
, "PeekNamedPipe failed: %u\n", GetLastError());
2731 ok_(__FILE__
,line
)(bytes_read
== expected_read
, "bytes_read = %u, expected %u\n", bytes_read
, expected_read
);
2732 ok_(__FILE__
,line
)(avail
== expected_avail
, "avail = %u, expected %u\n", avail
, expected_avail
);
2733 ok_(__FILE__
,line
)(left
== expected_message_length
- expected_read
, "left = %d, expected %d\n",
2734 left
, expected_message_length
- expected_read
);
2736 status
= NtFsControlFile(pipe
, 0, NULL
, NULL
, &io
, FSCTL_PIPE_PEEK
, NULL
, 0, buf
, sizeof(buf
));
2737 ok_(__FILE__
,line
)(!status
|| status
== STATUS_PENDING
, "NtFsControlFile(FSCTL_PIPE_PEEK) failed: %x\n", status
);
2738 ok_(__FILE__
,line
)(io
.Information
== FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER
, Data
[expected_read
]),
2739 "io.Information = %lu\n", io
.Information
);
2740 ok_(__FILE__
,line
)(peek_buf
->ReadDataAvailable
== expected_avail
, "ReadDataAvailable = %u, expected %u\n",
2741 peek_buf
->ReadDataAvailable
, expected_avail
);
2742 ok_(__FILE__
,line
)(peek_buf
->MessageLength
== expected_message_length
, "MessageLength = %u, expected %u\n",
2743 peek_buf
->MessageLength
, expected_message_length
);
2747 r
= PeekNamedPipe(pipe
, buf
, 1, &bytes_read
, &avail
, &left
);
2748 ok_(__FILE__
,line
)(r
, "PeekNamedPipe failed: %u\n", GetLastError());
2749 ok_(__FILE__
,line
)(bytes_read
== 1, "bytes_read = %u, expected %u\n", bytes_read
, expected_read
);
2750 ok_(__FILE__
,line
)(avail
== expected_avail
, "avail = %u, expected %u\n", avail
, expected_avail
);
2751 ok_(__FILE__
,line
)(left
== expected_message_length
-1, "left = %d, expected %d\n", left
, expected_message_length
-1);
2755 #define overlapped_read_sync(a,b,c,d,e) _overlapped_read_sync(__LINE__,a,b,c,d,e)
2756 static void _overlapped_read_sync(unsigned line
, HANDLE reader
, void *buf
, DWORD buf_size
, DWORD expected_result
, BOOL partial_read
)
2758 DWORD read_bytes
= 0xdeadbeef;
2759 OVERLAPPED overlapped
;
2762 memset(&overlapped
, 0, sizeof(overlapped
));
2763 overlapped
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
2764 res
= ReadFile(reader
, buf
, buf_size
, &read_bytes
, &overlapped
);
2766 ok_(__FILE__
,line
)(!res
&& GetLastError() == ERROR_MORE_DATA
, "ReadFile returned: %x (%u)\n", res
, GetLastError());
2768 ok_(__FILE__
,line
)(res
, "ReadFile failed: %u\n", GetLastError());
2770 ok_(__FILE__
,line
)(!read_bytes
, "read_bytes %u expected 0\n", read_bytes
);
2772 ok_(__FILE__
,line
)(read_bytes
== expected_result
, "read_bytes %u expected %u\n", read_bytes
, expected_result
);
2774 read_bytes
= 0xdeadbeef;
2775 res
= GetOverlappedResult(reader
, &overlapped
, &read_bytes
, FALSE
);
2777 ok_(__FILE__
,line
)(!res
&& GetLastError() == ERROR_MORE_DATA
,
2778 "GetOverlappedResult returned: %x (%u)\n", res
, GetLastError());
2780 ok_(__FILE__
,line
)(res
, "GetOverlappedResult failed: %u\n", GetLastError());
2781 ok_(__FILE__
,line
)(read_bytes
== expected_result
, "read_bytes %u expected %u\n", read_bytes
, expected_result
);
2782 CloseHandle(overlapped
.hEvent
);
2785 #define overlapped_read_async(a,b,c,d) _overlapped_read_async(__LINE__,a,b,c,d)
2786 static void _overlapped_read_async(unsigned line
, HANDLE reader
, void *buf
, DWORD buf_size
, OVERLAPPED
*overlapped
)
2788 DWORD read_bytes
= 0xdeadbeef;
2791 memset(overlapped
, 0, sizeof(*overlapped
));
2792 overlapped
->hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
2793 res
= ReadFile(reader
, buf
, buf_size
, &read_bytes
, overlapped
);
2794 ok_(__FILE__
,line
)(!res
&& GetLastError() == ERROR_IO_PENDING
, "ReadFile returned %x(%u)\n", res
, GetLastError());
2795 ok_(__FILE__
,line
)(!read_bytes
, "read_bytes %u expected 0\n", read_bytes
);
2797 _test_not_signaled(line
, overlapped
->hEvent
);
2800 #define overlapped_write_sync(a,b,c) _overlapped_write_sync(__LINE__,a,b,c)
2801 static void _overlapped_write_sync(unsigned line
, HANDLE writer
, void *buf
, DWORD size
)
2803 DWORD written_bytes
= 0xdeadbeef;
2804 OVERLAPPED overlapped
;
2807 memset(&overlapped
, 0, sizeof(overlapped
));
2808 overlapped
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
2809 res
= WriteFile(writer
, buf
, size
, &written_bytes
, &overlapped
);
2810 ok_(__FILE__
,line
)(res
, "WriteFile returned %x(%u)\n", res
, GetLastError());
2811 ok_(__FILE__
,line
)(written_bytes
== size
, "WriteFile returned written_bytes = %u\n", written_bytes
);
2813 written_bytes
= 0xdeadbeef;
2814 res
= GetOverlappedResult(writer
, &overlapped
, &written_bytes
, FALSE
);
2815 ok_(__FILE__
,line
)(res
, "GetOverlappedResult failed: %u\n", GetLastError());
2816 ok_(__FILE__
,line
)(written_bytes
== size
, "GetOverlappedResult returned written_bytes %u expected %u\n", written_bytes
, size
);
2818 CloseHandle(overlapped
.hEvent
);
2821 #define overlapped_write_async(a,b,c,d) _overlapped_write_async(__LINE__,a,b,c,d)
2822 static void _overlapped_write_async(unsigned line
, HANDLE writer
, void *buf
, DWORD size
, OVERLAPPED
*overlapped
)
2824 DWORD written_bytes
= 0xdeadbeef;
2827 memset(overlapped
, 0, sizeof(*overlapped
));
2828 overlapped
->hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
2829 res
= WriteFile(writer
, buf
, size
, &written_bytes
, overlapped
);
2830 ok_(__FILE__
,line
)(!res
&& GetLastError() == ERROR_IO_PENDING
, "WriteFile returned %x(%u)\n", res
, GetLastError());
2831 ok_(__FILE__
,line
)(!written_bytes
, "written_bytes = %u\n", written_bytes
);
2833 _test_not_signaled(line
, overlapped
->hEvent
);
2836 #define test_flush_sync(a) _test_flush_sync(__LINE__,a)
2837 static void _test_flush_sync(unsigned line
, HANDLE pipe
)
2841 res
= FlushFileBuffers(pipe
);
2842 ok_(__FILE__
,line
)(res
, "FlushFileBuffers failed: %u\n", GetLastError());
2845 static DWORD expected_flush_error
;
2847 static DWORD CALLBACK
flush_proc(HANDLE pipe
)
2851 res
= FlushFileBuffers(pipe
);
2852 if (expected_flush_error
== ERROR_SUCCESS
)
2853 ok(res
, "FlushFileBuffers failed: %u\n", GetLastError());
2855 ok(!res
&& GetLastError() == expected_flush_error
, "FlushFileBuffers failed: %u\n", GetLastError());
2859 #define test_flush_async(a,b) _test_flush_async(__LINE__,a,b)
2860 static HANDLE
_test_flush_async(unsigned line
, HANDLE pipe
, DWORD error
)
2865 expected_flush_error
= error
;
2866 thread
= CreateThread(NULL
, 0, flush_proc
, pipe
, 0, &tid
);
2867 ok_(__FILE__
,line
)(thread
!= NULL
, "CreateThread failed: %u\n", GetLastError());
2870 _test_not_signaled(line
, thread
);
2874 #define test_flush_done(a) _test_flush_done(__LINE__,a)
2875 static void _test_flush_done(unsigned line
, HANDLE thread
)
2877 DWORD res
= WaitForSingleObject(thread
, 1000);
2878 ok_(__FILE__
,line
)(res
== WAIT_OBJECT_0
, "WaitForSingleObject returned %u (%u)\n", res
, GetLastError());
2879 CloseHandle(thread
);
2882 #define test_overlapped_result(a,b,c,d) _test_overlapped_result(__LINE__,a,b,c,d)
2883 static void _test_overlapped_result(unsigned line
, HANDLE handle
, OVERLAPPED
*overlapped
, DWORD expected_result
, BOOL partial_read
)
2885 DWORD result
= 0xdeadbeef;
2888 _test_signaled(line
, overlapped
->hEvent
);
2890 res
= GetOverlappedResult(handle
, overlapped
, &result
, FALSE
);
2892 ok_(__FILE__
,line
)(!res
&& GetLastError() == ERROR_MORE_DATA
, "GetOverlappedResult returned: %x (%u)\n", res
, GetLastError());
2894 ok_(__FILE__
,line
)(res
, "GetOverlappedResult failed: %u\n", GetLastError());
2895 ok_(__FILE__
,line
)(result
== expected_result
, "read_bytes = %u, expected %u\n", result
, expected_result
);
2896 CloseHandle(overlapped
->hEvent
);
2899 #define test_overlapped_failure(a,b,c) _test_overlapped_failure(__LINE__,a,b,c)
2900 static void _test_overlapped_failure(unsigned line
, HANDLE handle
, OVERLAPPED
*overlapped
, DWORD error
)
2905 _test_signaled(line
, overlapped
->hEvent
);
2907 res
= GetOverlappedResult(handle
, overlapped
, &result
, FALSE
);
2908 ok_(__FILE__
,line
)(!res
&& GetLastError() == error
, "GetOverlappedResult returned: %x (%u), expected error %u\n",
2909 res
, GetLastError(), error
);
2910 ok_(__FILE__
,line
)(!result
, "result = %u\n", result
);
2911 CloseHandle(overlapped
->hEvent
);
2914 #define cancel_overlapped(a,b) _cancel_overlapped(__LINE__,a,b)
2915 static void _cancel_overlapped(unsigned line
, HANDLE handle
, OVERLAPPED
*overlapped
)
2919 res
= pCancelIoEx(handle
, overlapped
);
2920 ok_(__FILE__
,line
)(res
, "CancelIoEx failed: %u\n", GetLastError());
2922 _test_overlapped_failure(line
, handle
, overlapped
, ERROR_OPERATION_ABORTED
);
2925 static void test_blocking_rw(HANDLE writer
, HANDLE reader
, DWORD buf_size
, BOOL msg_mode
, BOOL msg_read
)
2927 OVERLAPPED read_overlapped
, read_overlapped2
, write_overlapped
, write_overlapped2
;
2928 char buf
[10000], read_buf
[10000];
2929 HANDLE flush_thread
;
2931 memset(buf
, 0xaa, sizeof(buf
));
2933 /* test pending read with overlapped event */
2934 overlapped_read_async(reader
, read_buf
, 1000, &read_overlapped
);
2935 test_flush_sync(writer
);
2936 test_peek_pipe(reader
, 0, 0, 0);
2938 /* write more data than needed for read */
2939 overlapped_write_sync(writer
, buf
, 4000);
2940 test_overlapped_result(reader
, &read_overlapped
, 1000, msg_read
);
2941 test_peek_pipe(reader
, 3000, 3000, msg_mode
? 3000 : 0);
2943 /* test pending write with overlapped event */
2944 overlapped_write_async(writer
, buf
, buf_size
, &write_overlapped
);
2945 test_peek_pipe(reader
, 3000 + (msg_mode
? 0 : buf_size
), 3000 + buf_size
, msg_mode
? 3000 : 0);
2947 /* write one more byte */
2948 overlapped_write_async(writer
, buf
, 1, &write_overlapped2
);
2949 flush_thread
= test_flush_async(writer
, ERROR_SUCCESS
);
2950 test_not_signaled(write_overlapped
.hEvent
);
2951 test_peek_pipe(reader
, 3000 + (msg_mode
? 0 : buf_size
+ 1), 3000 + buf_size
+ 1,
2952 msg_mode
? 3000 : 0);
2954 /* empty write will not block */
2955 overlapped_write_sync(writer
, buf
, 0);
2956 test_not_signaled(write_overlapped
.hEvent
);
2957 test_not_signaled(write_overlapped2
.hEvent
);
2958 test_peek_pipe(reader
, 3000 + (msg_mode
? 0 : buf_size
+ 1), 3000 + buf_size
+ 1,
2959 msg_mode
? 3000 : 0);
2961 /* read remaining data from the first write */
2962 overlapped_read_sync(reader
, read_buf
, 3000, 3000, FALSE
);
2963 test_overlapped_result(writer
, &write_overlapped
, buf_size
, FALSE
);
2964 test_not_signaled(write_overlapped2
.hEvent
);
2965 test_not_signaled(flush_thread
);
2966 test_peek_pipe(reader
, buf_size
+ (msg_mode
? 0 : 1), buf_size
+ 1, msg_mode
? buf_size
: 0);
2968 /* read one byte so that the next write fits the buffer */
2969 overlapped_read_sync(reader
, read_buf
, 1, 1, msg_read
);
2970 test_overlapped_result(writer
, &write_overlapped2
, 1, FALSE
);
2971 test_peek_pipe(reader
, buf_size
+ (msg_mode
? -1 : 0), buf_size
, msg_mode
? buf_size
- 1 : 0);
2973 /* read the whole buffer */
2974 overlapped_read_sync(reader
, read_buf
, buf_size
, buf_size
-msg_read
, FALSE
);
2975 test_peek_pipe(reader
, msg_read
? 1 : 0, msg_read
? 1 : 0, msg_read
? 1 : 0);
2979 overlapped_read_sync(reader
, read_buf
, 1000, 1, FALSE
);
2980 test_peek_pipe(reader
, 0, 0, 0);
2985 /* we still have an empty message in queue */
2986 overlapped_read_sync(reader
, read_buf
, 1000, 0, FALSE
);
2987 test_peek_pipe(reader
, 0, 0, 0);
2989 test_flush_done(flush_thread
);
2991 /* pipe is empty, the next read will block */
2992 overlapped_read_async(reader
, read_buf
, 0, &read_overlapped
);
2993 overlapped_read_async(reader
, read_buf
, 1000, &read_overlapped2
);
2995 /* write one byte */
2996 overlapped_write_sync(writer
, buf
, 1);
2997 test_overlapped_result(reader
, &read_overlapped
, 0, msg_read
);
2998 test_overlapped_result(reader
, &read_overlapped2
, 1, FALSE
);
2999 test_peek_pipe(reader
, 0, 0, 0);
3001 /* write a message larger than buffer */
3002 overlapped_write_async(writer
, buf
, buf_size
+2000, &write_overlapped
);
3003 test_peek_pipe(reader
, buf_size
+ 2000, buf_size
+ 2000, msg_mode
? buf_size
+ 2000 : 0);
3005 /* read so that pending write is still larger than the buffer */
3006 overlapped_read_sync(reader
, read_buf
, 1999, 1999, msg_read
);
3007 test_not_signaled(write_overlapped
.hEvent
);
3008 test_peek_pipe(reader
, buf_size
+ 1, buf_size
+ 1, msg_mode
? buf_size
+ 1 : 0);
3010 /* read one more byte */
3011 overlapped_read_sync(reader
, read_buf
, 1, 1, msg_read
);
3012 test_overlapped_result(writer
, &write_overlapped
, buf_size
+2000, FALSE
);
3013 test_peek_pipe(reader
, buf_size
, buf_size
, msg_mode
? buf_size
: 0);
3015 /* read remaining data */
3016 overlapped_read_sync(reader
, read_buf
, buf_size
+1, buf_size
, FALSE
);
3017 test_peek_pipe(reader
, 0, 0, 0);
3019 /* simple pass of empty message */
3020 overlapped_write_sync(writer
, buf
, 0);
3021 test_peek_pipe(reader
, 0, 0, 0);
3023 overlapped_read_sync(reader
, read_buf
, 1, 0, FALSE
);
3025 /* pipe is empty, the next read will block */
3026 test_flush_sync(writer
);
3027 overlapped_read_async(reader
, read_buf
, 0, &read_overlapped
);
3028 overlapped_read_async(reader
, read_buf
, 1, &read_overlapped2
);
3030 /* 0 length write wakes one read in msg mode */
3031 overlapped_write_sync(writer
, buf
, 0);
3033 test_overlapped_result(reader
, &read_overlapped
, 0, FALSE
);
3035 test_not_signaled(read_overlapped
.hEvent
);
3036 test_not_signaled(read_overlapped2
.hEvent
);
3037 overlapped_write_sync(writer
, buf
, 1);
3038 test_overlapped_result(reader
, &read_overlapped2
, 1, FALSE
);
3040 overlapped_write_sync(writer
, buf
, 20);
3041 test_peek_pipe(reader
, 20, 20, msg_mode
? 20 : 0);
3042 overlapped_write_sync(writer
, buf
, 15);
3043 test_peek_pipe(reader
, msg_mode
? 20 : 35, 35, msg_mode
? 20 : 0);
3044 overlapped_read_sync(reader
, read_buf
, 10, 10, msg_read
);
3045 test_peek_pipe(reader
, msg_mode
? 10 : 25, 25, msg_mode
? 10 : 0);
3046 overlapped_read_sync(reader
, read_buf
, 10, 10, FALSE
);
3047 test_peek_pipe(reader
, 15, 15, msg_mode
? 15 : 0);
3048 overlapped_read_sync(reader
, read_buf
, 15, 15, FALSE
);
3051 win_skip("CancelIoEx not available\n");
3055 /* add one more pending read, then cancel the first one */
3056 overlapped_read_async(reader
, read_buf
, 1, &read_overlapped
);
3057 overlapped_read_async(reader
, read_buf
, 1, &read_overlapped2
);
3058 cancel_overlapped(reader
, &read_overlapped2
);
3059 test_not_signaled(read_overlapped
.hEvent
);
3060 overlapped_write_sync(writer
, buf
, 1);
3061 test_overlapped_result(reader
, &read_overlapped
, 1, FALSE
);
3063 /* make two async writes, cancel the first one and make sure that we read from the second one */
3064 overlapped_write_async(writer
, buf
, buf_size
+2000, &write_overlapped
);
3065 overlapped_write_async(writer
, buf
, 1, &write_overlapped2
);
3066 test_peek_pipe(reader
, buf_size
+ 2000 + (msg_mode
? 0 : 1),
3067 buf_size
+ 2001, msg_mode
? buf_size
+ 2000 : 0);
3068 cancel_overlapped(writer
, &write_overlapped
);
3069 test_peek_pipe(reader
, 1, 1, msg_mode
? 1 : 0);
3070 overlapped_read_sync(reader
, read_buf
, 1000, 1, FALSE
);
3071 test_overlapped_result(writer
, &write_overlapped2
, 1, FALSE
);
3072 test_peek_pipe(reader
, 0, 0, 0);
3074 /* same as above, but partially read written data before canceling */
3075 overlapped_write_async(writer
, buf
, buf_size
+2000, &write_overlapped
);
3076 overlapped_write_async(writer
, buf
, 1, &write_overlapped2
);
3077 test_peek_pipe(reader
, buf_size
+ 2000 + (msg_mode
? 0 : 1),
3078 buf_size
+ 2001, msg_mode
? buf_size
+ 2000 : 0);
3079 overlapped_read_sync(reader
, read_buf
, 10, 10, msg_read
);
3080 test_not_signaled(write_overlapped
.hEvent
);
3081 cancel_overlapped(writer
, &write_overlapped
);
3082 test_peek_pipe(reader
, 1, 1, msg_mode
? 1 : 0);
3083 overlapped_read_sync(reader
, read_buf
, 1000, 1, FALSE
);
3084 test_overlapped_result(writer
, &write_overlapped2
, 1, FALSE
);
3085 test_peek_pipe(reader
, 0, 0, 0);
3087 /* empty queue by canceling write and make sure that flush is signaled */
3088 overlapped_write_async(writer
, buf
, buf_size
+2000, &write_overlapped
);
3089 flush_thread
= test_flush_async(writer
, ERROR_SUCCESS
);
3090 test_not_signaled(flush_thread
);
3091 cancel_overlapped(writer
, &write_overlapped
);
3092 test_peek_pipe(reader
, 0, 0, 0);
3093 test_flush_done(flush_thread
);
3096 #define overlapped_transact(a,b,c,d,e,f) _overlapped_transact(__LINE__,a,b,c,d,e,f)
3097 static void _overlapped_transact(unsigned line
, HANDLE caller
, void *write_buf
, DWORD write_size
,
3098 void *read_buf
, DWORD read_size
, OVERLAPPED
*overlapped
)
3102 memset(overlapped
, 0, sizeof(*overlapped
));
3103 overlapped
->hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
3104 res
= TransactNamedPipe(caller
, write_buf
, write_size
, read_buf
, read_size
, NULL
, overlapped
);
3105 ok_(__FILE__
,line
)(!res
&& GetLastError() == ERROR_IO_PENDING
,
3106 "TransactNamedPipe returned: %x(%u)\n", res
, GetLastError());
3109 #define overlapped_transact_failure(a,b,c,d,e,f) _overlapped_transact_failure(__LINE__,a,b,c,d,e,f)
3110 static void _overlapped_transact_failure(unsigned line
, HANDLE caller
, void *write_buf
, DWORD write_size
,
3111 void *read_buf
, DWORD read_size
, DWORD expected_error
)
3113 OVERLAPPED overlapped
;
3116 memset(&overlapped
, 0, sizeof(overlapped
));
3117 overlapped
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
3118 res
= TransactNamedPipe(caller
, write_buf
, write_size
, read_buf
, read_size
, NULL
, &overlapped
);
3119 ok_(__FILE__
,line
)(!res
, "TransactNamedPipe succeeded\n");
3121 if (GetLastError() == ERROR_IO_PENDING
) /* win8+ */
3123 _test_overlapped_failure(line
, caller
, &overlapped
, expected_error
);
3127 ok_(__FILE__
,line
)(GetLastError() == expected_error
,
3128 "TransactNamedPipe returned error %u, expected %u\n",
3129 GetLastError(), expected_error
);
3130 CloseHandle(overlapped
.hEvent
);
3134 static void child_process_write_pipe(HANDLE pipe
)
3136 OVERLAPPED overlapped
;
3139 memset(buf
, 'x', sizeof(buf
));
3140 overlapped_write_async(pipe
, buf
, sizeof(buf
), &overlapped
);
3142 /* sleep until parent process terminates this process */
3146 static HANDLE
create_writepipe_process(HANDLE pipe
)
3148 STARTUPINFOA si
= { sizeof(si
) };
3149 PROCESS_INFORMATION info
;
3150 char **argv
, buf
[MAX_PATH
];
3153 winetest_get_mainargs(&argv
);
3154 sprintf(buf
, "\"%s\" pipe writepipe %lx", argv
[0], (UINT_PTR
)pipe
);
3155 res
= CreateProcessA(NULL
, buf
, NULL
, NULL
, TRUE
, 0L, NULL
, NULL
, &si
, &info
);
3156 ok(res
, "CreateProcess failed: %u\n", GetLastError());
3157 CloseHandle(info
.hThread
);
3159 return info
.hProcess
;
3162 static void create_overlapped_pipe(DWORD mode
, HANDLE
*client
, HANDLE
*server
)
3164 SECURITY_ATTRIBUTES sec_attr
= { sizeof(sec_attr
), NULL
, TRUE
};
3165 DWORD read_mode
= mode
& (PIPE_READMODE_BYTE
| PIPE_READMODE_MESSAGE
);
3166 OVERLAPPED overlapped
;
3169 *server
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
,
3170 PIPE_WAIT
| mode
, 1, 5000, 6000, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
3171 ok(*server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed: %u\n", GetLastError());
3172 test_signaled(*server
);
3174 memset(&overlapped
, 0, sizeof(overlapped
));
3175 overlapped
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
3176 res
= ConnectNamedPipe(*server
, &overlapped
);
3177 ok(!res
&& GetLastError() == ERROR_IO_PENDING
, "WriteFile returned %x(%u)\n", res
, GetLastError());
3178 test_not_signaled(*server
);
3179 test_not_signaled(overlapped
.hEvent
);
3181 *client
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, &sec_attr
, OPEN_EXISTING
, FILE_FLAG_OVERLAPPED
, NULL
);
3182 ok(*client
!= INVALID_HANDLE_VALUE
, "CreateFile failed: %u\n", GetLastError());
3184 res
= SetNamedPipeHandleState(*client
, &read_mode
, NULL
, NULL
);
3185 ok(res
, "SetNamedPipeHandleState failed: %u\n", GetLastError());
3187 test_signaled(*client
);
3188 test_not_signaled(*server
);
3189 test_overlapped_result(*server
, &overlapped
, 0, FALSE
);
3192 static void test_overlapped_transport(BOOL msg_mode
, BOOL msg_read_mode
)
3194 OVERLAPPED overlapped
, overlapped2
;
3195 HANDLE server
, client
, flush
;
3201 DWORD create_flags
=
3202 (msg_mode
? PIPE_TYPE_MESSAGE
: PIPE_TYPE_BYTE
) |
3203 (msg_read_mode
? PIPE_READMODE_MESSAGE
: PIPE_READMODE_BYTE
);
3205 create_overlapped_pipe(create_flags
, &client
, &server
);
3207 trace("testing %s, %s server->client writes...\n",
3208 msg_mode
? "message mode" : "byte mode", msg_read_mode
? "message read" : "byte read");
3209 test_blocking_rw(server
, client
, 5000, msg_mode
, msg_read_mode
);
3210 trace("testing %s, %s client->server writes...\n",
3211 msg_mode
? "message mode" : "byte mode", msg_read_mode
? "message read" : "byte read");
3212 test_blocking_rw(client
, server
, 6000, msg_mode
, msg_read_mode
);
3214 CloseHandle(client
);
3215 CloseHandle(server
);
3217 /* close client with pending writes */
3218 memset(buf
, 0xaa, sizeof(buf
));
3219 create_overlapped_pipe(create_flags
, &client
, &server
);
3220 overlapped_write_async(server
, buf
, 7000, &overlapped
);
3221 flush
= test_flush_async(server
, ERROR_BROKEN_PIPE
);
3222 CloseHandle(client
);
3223 test_overlapped_failure(server
, &overlapped
, ERROR_BROKEN_PIPE
);
3224 test_flush_done(flush
);
3225 CloseHandle(server
);
3227 /* close server with pending writes */
3228 create_overlapped_pipe(create_flags
, &client
, &server
);
3229 overlapped_write_async(client
, buf
, 7000, &overlapped
);
3230 flush
= test_flush_async(client
, ERROR_BROKEN_PIPE
);
3231 CloseHandle(server
);
3232 test_overlapped_failure(client
, &overlapped
, ERROR_BROKEN_PIPE
);
3233 test_flush_done(flush
);
3234 CloseHandle(client
);
3236 /* disconnect with pending writes */
3237 create_overlapped_pipe(create_flags
, &client
, &server
);
3238 overlapped_write_async(client
, buf
, 7000, &overlapped
);
3239 overlapped_write_async(server
, buf
, 7000, &overlapped2
);
3240 flush
= test_flush_async(client
, ERROR_PIPE_NOT_CONNECTED
);
3241 res
= DisconnectNamedPipe(server
);
3242 ok(res
, "DisconnectNamedPipe failed: %u\n", GetLastError());
3243 test_overlapped_failure(client
, &overlapped
, ERROR_PIPE_NOT_CONNECTED
);
3244 test_overlapped_failure(client
, &overlapped2
, ERROR_PIPE_NOT_CONNECTED
);
3245 test_flush_done(flush
);
3246 CloseHandle(server
);
3247 CloseHandle(client
);
3249 /* terminate process with pending write */
3250 create_overlapped_pipe(create_flags
, &client
, &server
);
3251 process
= create_writepipe_process(client
);
3252 /* successfully read part of write that is pending in child process */
3253 res
= ReadFile(server
, buf
, 10, &read_bytes
, NULL
);
3255 ok(res
, "ReadFile failed: %u\n", GetLastError());
3257 ok(!res
&& GetLastError() == ERROR_MORE_DATA
, "ReadFile returned: %x %u\n", res
, GetLastError());
3258 ok(read_bytes
== 10, "read_bytes = %u\n", read_bytes
);
3259 TerminateProcess(process
, 0);
3260 wait_child_process(process
);
3261 /* after terminating process, there is no pending write and pipe buffer is empty */
3262 overlapped_read_async(server
, buf
, 10, &overlapped
);
3263 overlapped_write_sync(client
, buf
, 1);
3264 test_overlapped_result(server
, &overlapped
, 1, FALSE
);
3265 CloseHandle(process
);
3266 CloseHandle(server
);
3267 CloseHandle(client
);
3270 static void test_transact(HANDLE caller
, HANDLE callee
, DWORD write_buf_size
, DWORD read_buf_size
)
3272 OVERLAPPED overlapped
, overlapped2
, read_overlapped
, write_overlapped
;
3273 char buf
[10000], read_buf
[10000];
3275 memset(buf
, 0xaa, sizeof(buf
));
3277 /* simple transact call */
3278 overlapped_transact(caller
, (BYTE
*)"abc", 3, read_buf
, 100, &overlapped
);
3279 overlapped_write_sync(callee
, (BYTE
*)"test", 4);
3280 test_overlapped_result(caller
, &overlapped
, 4, FALSE
);
3281 ok(!memcmp(read_buf
, "test", 4), "unexpected read_buf\n");
3282 overlapped_read_sync(callee
, read_buf
, 1000, 3, FALSE
);
3283 ok(!memcmp(read_buf
, "abc", 3), "unexpected read_buf\n");
3285 /* transact fails if there is already data in read buffer */
3286 overlapped_write_sync(callee
, buf
, 1);
3287 overlapped_transact_failure(caller
, buf
, 2, read_buf
, 1, ERROR_PIPE_BUSY
);
3288 overlapped_read_sync(caller
, read_buf
, 1000, 1, FALSE
);
3290 /* transact doesn't block on write */
3291 overlapped_write_async(caller
, buf
, write_buf_size
+2000, &write_overlapped
);
3292 overlapped_transact(caller
, buf
, 2, read_buf
, 1, &overlapped
);
3293 test_not_signaled(overlapped
.hEvent
);
3294 overlapped_write_sync(callee
, buf
, 1);
3295 test_overlapped_result(caller
, &overlapped
, 1, FALSE
);
3296 overlapped_read_sync(callee
, read_buf
, sizeof(read_buf
), write_buf_size
+2000, FALSE
);
3297 test_overlapped_result(caller
, &write_overlapped
, write_buf_size
+2000, FALSE
);
3298 overlapped_read_sync(callee
, read_buf
, sizeof(read_buf
), 2, FALSE
);
3300 /* transact with already pending read */
3301 overlapped_read_async(callee
, read_buf
, 10, &read_overlapped
);
3302 overlapped_transact(caller
, buf
, 5, read_buf
, 6, &overlapped
);
3303 test_overlapped_result(callee
, &read_overlapped
, 5, FALSE
);
3304 test_not_signaled(overlapped
.hEvent
);
3305 overlapped_write_sync(callee
, buf
, 10);
3306 test_overlapped_result(caller
, &overlapped
, 6, TRUE
);
3307 overlapped_read_sync(caller
, read_buf
, sizeof(read_buf
), 4, FALSE
);
3309 /* 0-size messages */
3310 overlapped_transact(caller
, buf
, 5, read_buf
, 0, &overlapped
);
3311 overlapped_read_sync(callee
, read_buf
, sizeof(read_buf
), 5, FALSE
);
3312 overlapped_write_sync(callee
, buf
, 0);
3313 test_overlapped_result(caller
, &overlapped
, 0, FALSE
);
3315 overlapped_transact(caller
, buf
, 0, read_buf
, 0, &overlapped
);
3316 overlapped_read_sync(callee
, read_buf
, sizeof(read_buf
), 0, FALSE
);
3317 test_not_signaled(overlapped
.hEvent
);
3318 overlapped_write_sync(callee
, buf
, 0);
3319 test_overlapped_result(caller
, &overlapped
, 0, FALSE
);
3321 /* reply transact with another transact */
3322 overlapped_transact(caller
, buf
, 3, read_buf
, 100, &overlapped
);
3323 overlapped_read_sync(callee
, read_buf
, 1000, 3, FALSE
);
3324 overlapped_transact(callee
, buf
, 4, read_buf
, 100, &overlapped2
);
3325 test_overlapped_result(caller
, &overlapped
, 4, FALSE
);
3326 overlapped_write_sync(caller
, buf
, 1);
3327 test_overlapped_result(caller
, &overlapped2
, 1, FALSE
);
3329 if (!pCancelIoEx
) return;
3331 /* cancel keeps written data */
3332 overlapped_write_async(caller
, buf
, write_buf_size
+2000, &write_overlapped
);
3333 overlapped_transact(caller
, buf
, 2, read_buf
, 1, &overlapped
);
3334 test_not_signaled(overlapped
.hEvent
);
3335 cancel_overlapped(caller
, &overlapped
);
3336 overlapped_read_sync(callee
, read_buf
, sizeof(read_buf
), write_buf_size
+2000, FALSE
);
3337 test_overlapped_result(caller
, &write_overlapped
, write_buf_size
+2000, FALSE
);
3338 overlapped_read_sync(callee
, read_buf
, sizeof(read_buf
), 2, FALSE
);
3341 static void test_TransactNamedPipe(void)
3343 HANDLE client
, server
;
3346 create_overlapped_pipe(PIPE_TYPE_BYTE
, &client
, &server
);
3347 overlapped_transact_failure(client
, buf
, 2, buf
, 1, ERROR_BAD_PIPE
);
3348 CloseHandle(client
);
3349 CloseHandle(server
);
3351 create_overlapped_pipe(PIPE_TYPE_MESSAGE
| PIPE_READMODE_BYTE
, &client
, &server
);
3352 overlapped_transact_failure(client
, buf
, 2, buf
, 1, ERROR_BAD_PIPE
);
3353 CloseHandle(client
);
3354 CloseHandle(server
);
3356 trace("testing server->client transaction...\n");
3357 create_overlapped_pipe(PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
, &client
, &server
);
3358 test_transact(server
, client
, 5000, 6000);
3359 CloseHandle(client
);
3360 CloseHandle(server
);
3362 trace("testing client->server transaction...\n");
3363 create_overlapped_pipe(PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
, &client
, &server
);
3364 test_transact(client
, server
, 6000, 5000);
3365 CloseHandle(client
);
3366 CloseHandle(server
);
3369 static HANDLE
create_overlapped_server( OVERLAPPED
*overlapped
)
3374 pipe
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
, PIPE_READMODE_BYTE
| PIPE_WAIT
,
3375 1, 5000, 6000, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
3376 ok(pipe
!= INVALID_HANDLE_VALUE
, "got %u\n", GetLastError());
3377 ret
= ConnectNamedPipe(pipe
, overlapped
);
3378 ok(!ret
&& GetLastError() == ERROR_IO_PENDING
, "got %u\n", GetLastError());
3382 static void child_process_check_pid(DWORD server_pid
)
3384 DWORD current
= GetProcessId(GetCurrentProcess());
3389 pipe
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
3390 ok(pipe
!= INVALID_HANDLE_VALUE
, "got %u\n", GetLastError());
3393 ret
= pGetNamedPipeClientProcessId(pipe
, &pid
);
3394 ok(ret
, "got %u\n", GetLastError());
3395 ok(pid
== current
, "got %04x\n", pid
);
3398 ret
= pGetNamedPipeServerProcessId(pipe
, &pid
);
3399 ok(ret
, "got %u\n", GetLastError());
3400 ok(pid
== server_pid
, "got %04x expected %04x\n", pid
, server_pid
);
3404 static HANDLE
create_check_id_process(const char *verb
, DWORD id
)
3406 STARTUPINFOA si
= {sizeof(si
)};
3407 PROCESS_INFORMATION info
;
3408 char **argv
, buf
[MAX_PATH
];
3411 winetest_get_mainargs(&argv
);
3412 sprintf(buf
, "\"%s\" pipe %s %x", argv
[0], verb
, id
);
3413 ret
= CreateProcessA(NULL
, buf
, NULL
, NULL
, TRUE
, 0, NULL
, NULL
, &si
, &info
);
3414 ok(ret
, "got %u\n", GetLastError());
3415 CloseHandle(info
.hThread
);
3416 return info
.hProcess
;
3419 static void test_namedpipe_process_id(void)
3421 HANDLE client
, server
, process
;
3422 DWORD current
= GetProcessId(GetCurrentProcess());
3423 OVERLAPPED overlapped
;
3427 if (!pGetNamedPipeClientProcessId
)
3429 win_skip("GetNamedPipeClientProcessId not available\n");
3433 create_overlapped_pipe(PIPE_TYPE_BYTE
, &client
, &server
);
3435 SetLastError(0xdeadbeef);
3436 ret
= pGetNamedPipeClientProcessId(server
, NULL
);
3437 ok(!ret
, "success\n");
3438 todo_wine
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "got %u\n", GetLastError());
3441 ret
= pGetNamedPipeClientProcessId(server
, &pid
);
3442 ok(ret
, "got %u\n", GetLastError());
3443 ok(pid
== current
, "got %04x expected %04x\n", pid
, current
);
3446 ret
= pGetNamedPipeClientProcessId(client
, &pid
);
3447 ok(ret
, "got %u\n", GetLastError());
3448 ok(pid
== current
, "got %04x expected %04x\n", pid
, current
);
3450 SetLastError(0xdeadbeef);
3451 ret
= pGetNamedPipeServerProcessId(server
, NULL
);
3452 ok(!ret
, "success\n");
3453 todo_wine
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "got %u\n", GetLastError());
3456 ret
= pGetNamedPipeServerProcessId(client
, &pid
);
3457 ok(ret
, "got %u\n", GetLastError());
3458 ok(pid
== current
, "got %04x expected %04x\n", pid
, current
);
3461 ret
= pGetNamedPipeServerProcessId(server
, &pid
);
3462 ok(ret
, "got %u\n", GetLastError());
3463 ok(pid
== current
, "got %04x expected %04x\n", pid
, current
);
3465 /* closed client handle */
3466 CloseHandle(client
);
3468 ret
= pGetNamedPipeClientProcessId(server
, &pid
);
3469 ok(ret
, "got %u\n", GetLastError());
3470 ok(pid
== current
, "got %04x expected %04x\n", pid
, current
);
3473 ret
= pGetNamedPipeServerProcessId(server
, &pid
);
3474 ok(ret
, "got %u\n", GetLastError());
3475 ok(pid
== current
, "got %04x expected %04x\n", pid
, current
);
3476 CloseHandle(server
);
3478 /* disconnected server */
3479 create_overlapped_pipe(PIPE_TYPE_BYTE
, &client
, &server
);
3480 DisconnectNamedPipe(server
);
3482 SetLastError(0xdeadbeef);
3483 ret
= pGetNamedPipeClientProcessId(server
, &pid
);
3484 todo_wine
ok(!ret
, "success\n");
3485 todo_wine
ok(GetLastError() == ERROR_NOT_FOUND
, "got %u\n", GetLastError());
3488 ret
= pGetNamedPipeServerProcessId(server
, &pid
);
3489 ok(ret
, "got %u\n", GetLastError());
3490 ok(pid
== current
, "got %04x expected %04x\n", pid
, current
);
3492 SetLastError(0xdeadbeef);
3493 ret
= pGetNamedPipeClientProcessId(client
, &pid
);
3494 todo_wine
ok(!ret
, "success\n");
3495 todo_wine
ok(GetLastError() == ERROR_PIPE_NOT_CONNECTED
, "got %u\n", GetLastError());
3497 SetLastError(0xdeadbeef);
3498 ret
= pGetNamedPipeServerProcessId(client
, &pid
);
3499 todo_wine
ok(!ret
, "success\n");
3500 todo_wine
ok(GetLastError() == ERROR_PIPE_NOT_CONNECTED
, "got %u\n", GetLastError());
3501 CloseHandle(client
);
3502 CloseHandle(server
);
3504 /* closed server handle */
3505 create_overlapped_pipe(PIPE_TYPE_BYTE
, &client
, &server
);
3506 CloseHandle(server
);
3509 ret
= pGetNamedPipeClientProcessId(client
, &pid
);
3510 ok(ret
, "got %u\n", GetLastError());
3511 ok(pid
== current
, "got %04x expected %04x\n", pid
, current
);
3514 ret
= pGetNamedPipeServerProcessId(client
, &pid
);
3515 ok(ret
, "got %u\n", GetLastError());
3516 ok(pid
== current
, "got %04x expected %04x\n", pid
, current
);
3517 CloseHandle(client
);
3519 /* different process */
3520 memset(&overlapped
, 0, sizeof(overlapped
));
3521 overlapped
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
3522 server
= create_overlapped_server( &overlapped
);
3523 ok(server
!= INVALID_HANDLE_VALUE
, "got %u\n", GetLastError());
3525 process
= create_check_id_process("checkpid", GetProcessId(GetCurrentProcess()));
3526 wait_child_process(process
);
3528 CloseHandle(overlapped
.hEvent
);
3529 CloseHandle(process
);
3530 CloseHandle(server
);
3533 static void child_process_check_session_id(DWORD server_id
)
3540 ProcessIdToSessionId(GetProcessId(GetCurrentProcess()), ¤t
);
3542 pipe
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
3543 ok(pipe
!= INVALID_HANDLE_VALUE
, "got %u\n", GetLastError());
3546 ret
= pGetNamedPipeClientSessionId(pipe
, &id
);
3547 ok(ret
, "got %u\n", GetLastError());
3548 ok(id
== current
, "got %04x\n", id
);
3551 ret
= pGetNamedPipeServerSessionId(pipe
, &id
);
3552 ok(ret
, "got %u\n", GetLastError());
3553 ok(id
== server_id
, "got %04x expected %04x\n", id
, server_id
);
3557 static void test_namedpipe_session_id(void)
3559 HANDLE client
, server
, process
;
3560 OVERLAPPED overlapped
;
3565 if (!pGetNamedPipeClientSessionId
)
3567 win_skip("GetNamedPipeClientSessionId not available\n");
3571 ProcessIdToSessionId(GetProcessId(GetCurrentProcess()), ¤t
);
3573 create_overlapped_pipe(PIPE_TYPE_BYTE
, &client
, &server
);
3575 if (0) /* crashes on recent Windows */
3577 SetLastError(0xdeadbeef);
3578 ret
= pGetNamedPipeClientSessionId(server
, NULL
);
3579 ok(!ret
, "success\n");
3583 ret
= pGetNamedPipeClientSessionId(server
, &id
);
3584 ok(ret
, "got %u\n", GetLastError());
3585 ok(id
== current
, "got %u expected %u\n", id
, current
);
3588 ret
= pGetNamedPipeClientSessionId(client
, &id
);
3589 ok(ret
, "got %u\n", GetLastError());
3590 ok(id
== current
, "got %u expected %u\n", id
, current
);
3592 SetLastError(0xdeadbeef);
3593 ret
= pGetNamedPipeServerSessionId(server
, NULL
);
3594 ok(!ret
, "success\n");
3595 todo_wine
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "got %u\n", GetLastError());
3598 ret
= pGetNamedPipeServerSessionId(client
, &id
);
3599 ok(ret
, "got %u\n", GetLastError());
3600 ok(id
== current
, "got %u expected %u\n", id
, current
);
3603 ret
= pGetNamedPipeServerSessionId(server
, &id
);
3604 ok(ret
, "got %u\n", GetLastError());
3605 ok(id
== current
, "got %u expected %u\n", id
, current
);
3607 /* closed client handle */
3608 CloseHandle(client
);
3611 ret
= pGetNamedPipeClientSessionId(server
, &id
);
3612 ok(ret
, "got %u\n", GetLastError());
3613 ok(id
== current
, "got %04x expected %04x\n", id
, current
);
3616 ret
= pGetNamedPipeServerSessionId(server
, &id
);
3617 ok(ret
, "got %u\n", GetLastError());
3618 ok(id
== current
, "got %04x expected %04x\n", id
, current
);
3619 CloseHandle(server
);
3621 /* disconnected server */
3622 create_overlapped_pipe(PIPE_TYPE_BYTE
, &client
, &server
);
3623 DisconnectNamedPipe(server
);
3625 SetLastError(0xdeadbeef);
3626 ret
= pGetNamedPipeClientSessionId(server
, &id
);
3627 todo_wine
ok(!ret
, "success\n");
3628 todo_wine
ok(GetLastError() == ERROR_NOT_FOUND
, "got %u\n", GetLastError());
3631 ret
= pGetNamedPipeServerSessionId(server
, &id
);
3632 ok(ret
, "got %u\n", GetLastError());
3633 ok(id
== current
, "got %04x expected %04x\n", id
, current
);
3635 SetLastError(0xdeadbeef);
3636 ret
= pGetNamedPipeClientSessionId(client
, &id
);
3637 todo_wine
ok(!ret
, "success\n");
3638 todo_wine
ok(GetLastError() == ERROR_PIPE_NOT_CONNECTED
, "got %u\n", GetLastError());
3640 SetLastError(0xdeadbeef);
3641 ret
= pGetNamedPipeServerSessionId(client
, &id
);
3642 todo_wine
ok(!ret
, "success\n");
3643 todo_wine
ok(GetLastError() == ERROR_PIPE_NOT_CONNECTED
, "got %u\n", GetLastError());
3644 CloseHandle(client
);
3645 CloseHandle(server
);
3647 /* closed server handle */
3648 create_overlapped_pipe(PIPE_TYPE_BYTE
, &client
, &server
);
3649 CloseHandle(server
);
3652 ret
= pGetNamedPipeClientSessionId(client
, &id
);
3653 ok(ret
, "got %u\n", GetLastError());
3654 ok(id
== current
, "got %04x expected %04x\n", id
, current
);
3657 ret
= pGetNamedPipeServerSessionId(client
, &id
);
3658 ok(ret
, "got %u\n", GetLastError());
3659 ok(id
== current
, "got %04x expected %04x\n", id
, current
);
3660 CloseHandle(client
);
3662 /* different process */
3663 memset(&overlapped
, 0, sizeof(overlapped
));
3664 overlapped
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
3665 server
= create_overlapped_server( &overlapped
);
3666 ok(server
!= INVALID_HANDLE_VALUE
, "got %u\n", GetLastError());
3668 process
= create_check_id_process("checksessionid", current
);
3669 wait_child_process(process
);
3671 CloseHandle(overlapped
.hEvent
);
3672 CloseHandle(process
);
3673 CloseHandle(server
);
3676 static void test_multiple_instances(void)
3678 HANDLE server
[4], client
;
3685 win_skip("Skipping multiple instance tests on too old Windows\n");
3689 for (i
= 0; i
< ARRAY_SIZE(server
); i
++)
3691 server
[i
] = CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
3692 PIPE_READMODE_BYTE
| PIPE_WAIT
, ARRAY_SIZE(server
), 1024, 1024,
3693 NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
3694 ok(server
[i
] != INVALID_HANDLE_VALUE
, "got invalid handle\n");
3697 client
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3698 ok(client
!= INVALID_HANDLE_VALUE
, "got invalid handle\n");
3700 /* Show that this has connected to server[0] not any other one */
3702 memset(&ov
, 0, sizeof(ov
));
3703 ret
= ConnectNamedPipe(server
[2], &ov
);
3704 ok(ret
== FALSE
, "got %d\n", ret
);
3705 ok(GetLastError() == ERROR_IO_PENDING
, "got %d\n", GetLastError());
3707 memset(&ov
, 0, sizeof(ov
));
3708 ret
= ConnectNamedPipe(server
[0], &ov
);
3709 ok(ret
== FALSE
, "got %d\n", ret
);
3710 ok(GetLastError() == ERROR_PIPE_CONNECTED
, "got %d\n", GetLastError());
3712 CloseHandle(client
);
3714 /* The next connected server is server[1], doesn't matter that server[2] has pending listeners */
3716 client
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3717 ok(client
!= INVALID_HANDLE_VALUE
, "got invalid handle\n");
3719 memset(&ov
, 0, sizeof(ov
));
3720 ret
= ConnectNamedPipe(server
[2], &ov
);
3721 ok(ret
== FALSE
, "got %d\n", ret
);
3722 ok(GetLastError() == ERROR_IO_PENDING
, "got %d\n", GetLastError());
3724 memset(&ov
, 0, sizeof(ov
));
3725 ret
= ConnectNamedPipe(server
[1], &ov
);
3726 ok(ret
== FALSE
, "got %d\n", ret
);
3727 ok(GetLastError() == ERROR_PIPE_CONNECTED
, "got %d\n", GetLastError());
3729 CloseHandle(client
);
3731 /* server[2] is connected next */
3733 client
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3734 ok(client
!= INVALID_HANDLE_VALUE
, "got invalid handle\n");
3736 memset(&ov
, 0, sizeof(ov
));
3737 ret
= ConnectNamedPipe(server
[2], &ov
);
3738 ok(ret
== FALSE
, "got %d\n", ret
);
3739 ok(GetLastError() == ERROR_PIPE_CONNECTED
, "got %d\n", GetLastError());
3741 CloseHandle(client
);
3743 /* Disconnect in order server[0] and server[2] */
3745 DisconnectNamedPipe(server
[0]);
3746 DisconnectNamedPipe(server
[2]);
3748 /* Put into listening state server[2] and server[0] */
3750 memset(&ov
, 0, sizeof(ov
));
3751 ret
= ConnectNamedPipe(server
[2], &ov
);
3752 ok(ret
== FALSE
, "got %d\n", ret
);
3753 ok(GetLastError() == ERROR_IO_PENDING
, "got %d\n", GetLastError());
3755 memset(&ov
, 0, sizeof(ov
));
3756 ret
= ConnectNamedPipe(server
[0], &ov
);
3757 ok(ret
== FALSE
, "got %d\n", ret
);
3758 ok(GetLastError() == ERROR_IO_PENDING
, "got %d\n", GetLastError());
3760 /* server[3] is connected next */
3762 client
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3763 ok(client
!= INVALID_HANDLE_VALUE
, "got invalid handle\n");
3765 memset(&ov
, 0, sizeof(ov
));
3766 ret
= ConnectNamedPipe(server
[3], &ov
);
3767 ok(ret
== FALSE
, "got %d\n", ret
);
3768 ok(GetLastError() == ERROR_PIPE_CONNECTED
, "got %d\n", GetLastError());
3770 CloseHandle(client
);
3772 /* server[2], which stasted listening first, will be connected next */
3774 client
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3775 ok(client
!= INVALID_HANDLE_VALUE
, "got invalid handle\n");
3777 memset(&ov
, 0, sizeof(ov
));
3778 ret
= ConnectNamedPipe(server
[2], &ov
);
3779 ok(ret
== FALSE
, "got %d\n", ret
);
3780 ok(GetLastError() == ERROR_PIPE_CONNECTED
, "got %d\n", GetLastError());
3782 memset(&ov
, 0, sizeof(ov
));
3783 ret
= ConnectNamedPipe(server
[0], &ov
);
3784 ok(ret
== FALSE
, "got %d\n", ret
);
3785 ok(GetLastError() == ERROR_IO_PENDING
, "got %d\n", GetLastError());
3787 CloseHandle(client
);
3789 /* Finally server[0] is connected */
3791 client
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3792 ok(client
!= INVALID_HANDLE_VALUE
, "got invalid handle\n");
3794 memset(&ov
, 0, sizeof(ov
));
3795 ret
= ConnectNamedPipe(server
[0], &ov
);
3796 ok(ret
== FALSE
, "got %d\n", ret
);
3797 ok(GetLastError() == ERROR_PIPE_CONNECTED
, "got %d\n", GetLastError());
3799 CloseHandle(client
);
3801 /* No more listening pipes available */
3802 DisconnectNamedPipe(server
[0]);
3803 client
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3804 ok(client
== INVALID_HANDLE_VALUE
&& GetLastError() == ERROR_PIPE_BUSY
, "got %p(%u)\n", client
, GetLastError());
3806 for (i
= 0; i
< ARRAY_SIZE(server
); i
++)
3808 DisconnectNamedPipe(server
[i
]);
3809 CloseHandle(server
[i
]);
3813 static DWORD WINAPI
wait_pipe_proc(void *arg
)
3816 ret
= WaitNamedPipeA(PIPENAME
, 1000);
3817 ok(ret
, "WaitNamedPipe failed (%u)\n", GetLastError());
3821 static HANDLE
async_wait_pipe(void)
3826 thread
= CreateThread(NULL
, 0, wait_pipe_proc
, NULL
, 0, NULL
);
3827 ok(thread
!= NULL
, "CreateThread failed: %u\n", GetLastError());
3829 ret
= WaitNamedPipeA(PIPENAME
, 1);
3830 ok(!ret
&& GetLastError() == ERROR_SEM_TIMEOUT
, "WaitNamedPipe failed %x(%u)\n", ret
, GetLastError());
3835 static void test_wait_pipe(void)
3837 HANDLE server
[2], client
, wait
;
3842 ret
= WaitNamedPipeA(PIPENAME
, 0);
3843 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
, "WaitNamedPipe failed %x(%u)\n", ret
, GetLastError());
3845 server
[0] = CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
3846 PIPE_READMODE_BYTE
| PIPE_WAIT
, ARRAY_SIZE(server
), 1024, 1024,
3847 NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
3848 ok(server
[0] != INVALID_HANDLE_VALUE
, "got invalid handle\n");
3850 ret
= WaitNamedPipeA(PIPENAME
, 1);
3851 ok(ret
, "WaitNamedPipe failed (%u)\n", GetLastError());
3853 client
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3854 ok(client
!= INVALID_HANDLE_VALUE
, "got invalid handle\n");
3856 /* Creating a new pipe server wakes waiters */
3857 wait
= async_wait_pipe();
3858 server
[1] = CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
3859 PIPE_READMODE_BYTE
| PIPE_WAIT
, ARRAY_SIZE(server
), 1024, 1024,
3860 NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
3861 ok(server
[1] != INVALID_HANDLE_VALUE
, "got invalid handle\n");
3863 res
= WaitForSingleObject(wait
, 100);
3864 ok(res
== WAIT_OBJECT_0
, "WaitForSingleObject returned %u\n", res
);
3867 CloseHandle(server
[1]);
3869 CloseHandle(client
);
3870 ret
= DisconnectNamedPipe(server
[0]);
3871 ok(ret
, "DisconnectNamedPipe failed (%u)\n", GetLastError());
3873 /* Putting pipe server into waiting listening state wakes waiters */
3874 wait
= async_wait_pipe();
3875 memset(&ov
, 0, sizeof(ov
));
3876 ov
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
3877 ret
= ConnectNamedPipe(server
[0], &ov
);
3878 ok(ret
== FALSE
, "got %d\n", ret
);
3879 ok(GetLastError() == ERROR_IO_PENDING
, "got %d\n", GetLastError());
3881 res
= WaitForSingleObject(wait
, 100);
3882 ok(res
== WAIT_OBJECT_0
, "WaitForSingleObject returned %u\n", res
);
3883 CloseHandle(server
[0]);
3885 res
= WaitForSingleObject(ov
.hEvent
, 0);
3886 ok(res
== WAIT_OBJECT_0
, "WaitForSingleObject returned %u\n", res
);
3887 CloseHandle(ov
.hEvent
);
3890 static void test_nowait(DWORD pipe_type
)
3892 HANDLE piperead
, pipewrite
, file
;
3895 char readbuf
[32768];
3896 static const char teststring
[] = "bits";
3898 /* CreateNamedPipe with PIPE_NOWAIT, and read from empty pipe */
3899 piperead
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
,
3900 /* dwPipeMode */ pipe_type
| PIPE_NOWAIT
,
3901 /* nMaxInstances */ 1,
3902 /* nOutBufSize */ 512,
3903 /* nInBufSize */ 512,
3904 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
3905 /* lpSecurityAttrib */ NULL
);
3906 ok(piperead
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
3907 pipewrite
= CreateFileA(PIPENAME
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3908 ok(pipewrite
!= INVALID_HANDLE_VALUE
, "CreateFileA failed\n");
3909 memset(&ol
, 0, sizeof(ol
));
3910 ol
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
3911 SetLastError(0xdeadbeef);
3912 ok(ReadFile(piperead
, readbuf
, sizeof(readbuf
), &read
, &ol
) == FALSE
, "ReadFile should fail\n");
3913 ok(GetLastError() == ERROR_NO_DATA
, "got %d should be ERROR_NO_DATA\n", GetLastError());
3914 if (GetLastError() == ERROR_IO_PENDING
)
3917 /* test a small write/read */
3918 ok(WriteFile(pipewrite
, teststring
, sizeof(teststring
), &write
, NULL
), "WriteFile should succeed\n");
3919 ok(ReadFile(piperead
, readbuf
, sizeof(readbuf
), &read
, &ol
), "ReadFile should succeed\n");
3920 ok(read
== write
, "read/write bytes should match\n");
3921 ok(CloseHandle(ol
.hEvent
), "CloseHandle for the event failed\n");
3922 ok(CloseHandle(pipewrite
), "CloseHandle for the write pipe failed\n");
3923 ok(CloseHandle(piperead
), "CloseHandle for the read pipe failed\n");
3926 /* create write side with PIPE_NOWAIT, read side PIPE_WAIT, and test writes */
3927 pipewrite
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
,
3928 /* dwPipeMode */ pipe_type
| PIPE_NOWAIT
,
3929 /* nMaxInstances */ 1,
3930 /* nOutBufSize */ 512,
3931 /* nInBufSize */ 512,
3932 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
3933 /* lpSecurityAttrib */ NULL
);
3934 ok(pipewrite
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
3935 piperead
= CreateFileA(PIPENAME
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_OVERLAPPED
, 0);
3936 ok(piperead
!= INVALID_HANDLE_VALUE
, "CreateFileA failed\n");
3937 memset(&ol
, 0, sizeof(ol
));
3938 ol
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
3939 memset(&ol2
, 0, sizeof(ol2
));
3940 ol2
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
3942 /* write one byte larger than the buffer size, should fail */
3943 SetLastError(0xdeadbeef);
3944 ok(WriteFile(pipewrite
, readbuf
, 513, &write
, &ol
), "WriteFile should succeed\n");
3945 /* WriteFile only documents that 'write < sizeof(readbuf)' for this case, but Windows
3946 * doesn't seem to do partial writes ('write == 0' always)
3948 ok(write
< sizeof(readbuf
), "WriteFile should fail to write the whole buffer\n");
3949 ok(write
== 0, "WriteFile doesn't do partial writes here\n");
3950 if (GetLastError() == ERROR_IO_PENDING
)
3953 /* overlapped read of 32768, non-blocking write of 512 */
3954 SetLastError(0xdeadbeef);
3955 ok(ReadFile(piperead
, readbuf
, sizeof(readbuf
), &read
, &ol2
) == FALSE
, "ReadFile should fail\n");
3956 ok(GetLastError() == ERROR_IO_PENDING
, "got %d should be ERROR_IO_PENDING\n", GetLastError());
3957 ok(WriteFile(pipewrite
, teststring
, sizeof(teststring
), &write
, &ol
), "WriteFile should succeed\n");
3958 ok(write
== sizeof(teststring
), "got %d\n", write
);
3959 ok(GetOverlappedResult(piperead
, &ol2
, &read
, FALSE
), "GetOverlappedResult should succeed\n");
3960 ok(read
== sizeof(teststring
), "got %d\n", read
);
3961 if (GetOverlappedResult(piperead
, &ol2
, &read
, FALSE
) == FALSE
)
3964 /* overlapped read of 32768, non-blocking write of 513 */
3965 SetLastError(0xdeadbeef);
3966 ok(ReadFile(piperead
, readbuf
, sizeof(readbuf
), &read
, &ol2
) == FALSE
, "ReadFile should fail\n");
3967 ok(GetLastError() == ERROR_IO_PENDING
, "got %d should be ERROR_IO_PENDING\n", GetLastError());
3968 ok(WriteFile(pipewrite
, readbuf
, 513, &write
, &ol
), "WriteFile should succeed\n");
3969 ok(write
== 513, "got %d, write should be %d\n", write
, 513);
3970 ok(GetOverlappedResult(piperead
, &ol2
, &read
, FALSE
), "GetOverlappedResult should succeed\n");
3971 ok(read
== 513, "got %d, read should be %d\n", read
, 513);
3972 if (GetOverlappedResult(piperead
, &ol2
, &read
, FALSE
) == FALSE
)
3975 /* overlapped read of 1 byte, non-blocking write of 513 bytes */
3976 SetLastError(0xdeadbeef);
3977 ok(ReadFile(piperead
, readbuf
, 1, &read
, &ol2
) == FALSE
, "ReadFile should fail\n");
3978 ok(GetLastError() == ERROR_IO_PENDING
, "got %d should be ERROR_IO_PENDING\n", GetLastError());
3979 ok(WriteFile(pipewrite
, readbuf
, 513, &write
, &ol
), "WriteFile should succeed\n");
3980 ok(write
== 513, "got %d, write should be %d\n", write
, 513);
3981 ok(GetOverlappedResult(piperead
, &ol2
, &read
, FALSE
), "GetOverlappedResult should succeed\n");
3982 ok(read
== 1, "got %d, read should be %d\n", read
, 1);
3983 if (GetOverlappedResult(piperead
, &ol2
, &read
, FALSE
) == FALSE
)
3985 /* read the remaining 512 bytes */
3986 SetLastError(0xdeadbeef);
3987 ok(ReadFile(piperead
, readbuf
, sizeof(readbuf
), &read
, &ol2
), "ReadFile should succeed\n");
3988 ok(read
== 512, "got %d, write should be %d\n", write
, 512);
3989 if (GetOverlappedResult(piperead
, &ol2
, &read
, FALSE
) == FALSE
)
3992 /* overlapped read of 1 byte, non-blocking write of 514 bytes */
3993 SetLastError(0xdeadbeef);
3994 ok(ReadFile(piperead
, readbuf
, 1, &read
, &ol2
) == FALSE
, "ReadFile should fail\n");
3995 ok(GetLastError() == ERROR_IO_PENDING
, "got %d should be ERROR_IO_PENDING\n", GetLastError());
3996 ok(WriteFile(pipewrite
, readbuf
, 514, &write
, &ol
), "WriteFile should succeed\n");
3997 if (pipe_type
== PIPE_TYPE_MESSAGE
)
4000 ok(write
== 0, "got %d\n", write
);
4002 ok(!GetOverlappedResult(piperead
, &ol2
, &read
, FALSE
), "GetOverlappedResult should fail\n");
4004 ok(GetLastError() == ERROR_IO_INCOMPLETE
, "got %d should be ERROR_IO_PENDING\n", GetLastError());
4006 ok(read
== 0, "got %d, read should be %d\n", read
, 1);
4010 ok(write
== 1, "got %d\n", write
);
4011 ok(GetOverlappedResult(piperead
, &ol2
, &read
, FALSE
), "GetOverlappedResult should fail\n");
4012 ok(read
== 1, "got %d, read should be %d\n", read
, 1);
4014 if (GetOverlappedResult(piperead
, &ol2
, &read
, FALSE
) == FALSE
)
4017 /* write the exact buffer size, should succeed */
4018 SetLastError(0xdeadbeef);
4019 ok(WriteFile(pipewrite
, readbuf
, 512, &write
, &ol
), "WriteFile should succeed\n");
4020 ok(write
== 512, "WriteFile should write the whole buffer\n");
4021 if (GetLastError() == ERROR_IO_PENDING
)
4024 ok(CloseHandle(ol
.hEvent
), "CloseHandle for the event failed\n");
4025 ok(CloseHandle(ol2
.hEvent
), "CloseHandle for the event failed\n");
4026 ok(CloseHandle(pipewrite
), "CloseHandle for the write pipe failed\n");
4027 ok(CloseHandle(piperead
), "CloseHandle for the read pipe failed\n");
4030 /* CreateNamedPipe with PIPE_NOWAIT, test ConnectNamedPipe */
4031 pipewrite
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
,
4032 /* dwPipeMode */ pipe_type
| PIPE_NOWAIT
,
4033 /* nMaxInstances */ 1,
4034 /* nOutBufSize */ 512,
4035 /* nInBufSize */ 512,
4036 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
4037 /* lpSecurityAttrib */ NULL
);
4038 ok(pipewrite
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
4039 memset(&ol
, 0, sizeof(ol
));
4040 ol
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
4041 SetLastError(0xdeadbeef);
4042 ok(ConnectNamedPipe(pipewrite
, &ol
) == FALSE
, "ConnectNamedPipe should fail\n");
4043 ok(GetLastError() == ERROR_PIPE_LISTENING
, "got %d should be ERROR_PIPE_LISTENING\n", GetLastError());
4044 if (GetLastError() == ERROR_IO_PENDING
)
4045 CancelIo(pipewrite
);
4047 /* connect and disconnect, then test ConnectNamedPipe again */
4048 file
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
4049 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFileA failed\n");
4050 ok(CloseHandle(file
), "CloseHandle failed\n");
4051 SetLastError(0xdeadbeef);
4052 ok(ConnectNamedPipe(pipewrite
,&ol
) == FALSE
, "ConnectNamedPipe should fail\n");
4053 ok(GetLastError() == ERROR_NO_DATA
, "got %d should be ERROR_NO_DATA\n", GetLastError());
4054 if (GetLastError() == ERROR_IO_PENDING
)
4055 CancelIo(pipewrite
);
4057 /* call DisconnectNamedPipe and test ConnectNamedPipe again */
4058 ok(DisconnectNamedPipe(pipewrite
) == TRUE
, "DisconnectNamedPipe should succeed\n");
4059 SetLastError(0xdeadbeef);
4060 ok(ConnectNamedPipe(pipewrite
,&ol
) == FALSE
, "ConnectNamedPipe should fail\n");
4061 ok(GetLastError() == ERROR_PIPE_LISTENING
, "got %d should be ERROR_PIPE_LISTENING\n", GetLastError());
4062 if (GetLastError() == ERROR_IO_PENDING
)
4063 CancelIo(pipewrite
);
4064 ok(CloseHandle(ol
.hEvent
), "CloseHandle for the event failed\n");
4065 ok(CloseHandle(pipewrite
), "CloseHandle for the write pipe failed\n");
4068 static void test_GetOverlappedResultEx(void)
4070 HANDLE client
, server
;
4076 if (!pGetOverlappedResultEx
)
4078 win_skip("GetOverlappedResultEx() is not available\n");
4082 create_overlapped_pipe(PIPE_TYPE_BYTE
, &client
, &server
);
4084 overlapped_write_async(client
, buffer
, sizeof(buffer
), &ovl
);
4086 user_apc_ran
= FALSE
;
4087 QueueUserAPC(user_apc
, GetCurrentThread(), 0);
4089 SetLastError(0xdeadbeef);
4090 ret
= pGetOverlappedResultEx(client
, &ovl
, &ret_size
, 0, FALSE
);
4091 ok(!ret
, "expected failure\n");
4092 ok(GetLastError() == ERROR_IO_INCOMPLETE
, "wrong error %u\n", GetLastError());
4093 ok(!user_apc_ran
, "APC should not have run\n");
4095 SetLastError(0xdeadbeef);
4096 ret
= pGetOverlappedResultEx(client
, &ovl
, &ret_size
, 0, TRUE
);
4097 ok(!ret
, "expected failure\n");
4098 ok(GetLastError() == ERROR_IO_INCOMPLETE
, "wrong error %u\n", GetLastError());
4099 ok(!user_apc_ran
, "APC should not have run\n");
4101 SetLastError(0xdeadbeef);
4102 ret
= pGetOverlappedResultEx(client
, &ovl
, &ret_size
, 10, FALSE
);
4103 ok(!ret
, "expected failure\n");
4104 ok(GetLastError() == WAIT_TIMEOUT
, "wrong error %u\n", GetLastError());
4105 ok(!user_apc_ran
, "APC should not have run\n");
4107 SetLastError(0xdeadbeef);
4108 ret
= pGetOverlappedResultEx(client
, &ovl
, &ret_size
, 10, TRUE
);
4109 ok(!ret
, "expected failure\n");
4110 ok(GetLastError() == WAIT_IO_COMPLETION
, "wrong error %u\n", GetLastError());
4111 ok(user_apc_ran
, "APC should have run\n");
4113 CloseHandle(ovl
.hEvent
);
4115 CloseHandle(client
);
4116 CloseHandle(server
);
4119 static void child_process_exit_process_async(DWORD parent_pid
, HANDLE parent_pipe
)
4121 OVERLAPPED overlapped
= {0};
4122 static char buffer
[1];
4123 HANDLE parent
, pipe
;
4126 parent
= OpenProcess(PROCESS_DUP_HANDLE
, FALSE
, parent_pid
);
4127 ok(!!parent
, "got parent %p\n", parent
);
4129 ret
= DuplicateHandle(parent
, parent_pipe
, GetCurrentProcess(), &pipe
, 0,
4130 FALSE
, DUPLICATE_SAME_ACCESS
| DUPLICATE_CLOSE_SOURCE
);
4131 ok(ret
, "got error %u\n", GetLastError());
4133 overlapped
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
4135 ret
= ReadFile(pipe
, buffer
, sizeof(buffer
), NULL
, &overlapped
);
4136 ok(!ret
, "expected failure\n");
4137 ok(GetLastError() == ERROR_IO_PENDING
, "got error %u\n", GetLastError());
4139 /* exit without closing the pipe handle */
4142 static void test_exit_process_async(void)
4144 HANDLE client
, server
, port
;
4145 OVERLAPPED
*overlapped
;
4146 PROCESS_INFORMATION pi
;
4147 STARTUPINFOA si
= {0};
4154 winetest_get_mainargs(&argv
);
4156 create_overlapped_pipe(PIPE_TYPE_BYTE
, &client
, &server
);
4157 port
= CreateIoCompletionPort(client
, NULL
, 123, 0);
4159 sprintf(cmdline
, "%s pipe exit_process_async %x %p", argv
[0], GetCurrentProcessId(), client
);
4160 ret
= CreateProcessA(NULL
, cmdline
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &si
, &pi
);
4161 ok(ret
, "got error %u\n", GetLastError());
4162 ret
= WaitForSingleObject(pi
.hProcess
, 1000);
4163 ok(!ret
, "wait timed out\n");
4164 CloseHandle(pi
.hThread
);
4165 CloseHandle(pi
.hProcess
);
4169 ret
= GetQueuedCompletionStatus(port
, &size
, &key
, &overlapped
, 1000);
4170 ok(!ret
, "expected failure\n");
4171 ok(GetLastError() == ERROR_OPERATION_ABORTED
, "got error %u\n", GetLastError());
4172 ok(!size
, "got size %u\n", size
);
4173 ok(key
== 123, "got key %Iu\n", key
);
4176 CloseHandle(server
);
4185 hmod
= GetModuleHandleA("advapi32.dll");
4186 pDuplicateTokenEx
= (void *) GetProcAddress(hmod
, "DuplicateTokenEx");
4187 hmod
= GetModuleHandleA("kernel32.dll");
4188 pCancelIoEx
= (void *) GetProcAddress(hmod
, "CancelIoEx");
4189 pGetNamedPipeClientProcessId
= (void *) GetProcAddress(hmod
, "GetNamedPipeClientProcessId");
4190 pGetNamedPipeServerProcessId
= (void *) GetProcAddress(hmod
, "GetNamedPipeServerProcessId");
4191 pGetNamedPipeClientSessionId
= (void *) GetProcAddress(hmod
, "GetNamedPipeClientSessionId");
4192 pGetNamedPipeServerSessionId
= (void *) GetProcAddress(hmod
, "GetNamedPipeServerSessionId");
4193 pGetOverlappedResultEx
= (void *)GetProcAddress(hmod
, "GetOverlappedResultEx");
4195 argc
= winetest_get_mainargs(&argv
);
4199 if (!strcmp(argv
[2], "writepipe"))
4202 sscanf(argv
[3], "%lx", &handle
);
4203 child_process_write_pipe((HANDLE
)handle
);
4206 if (!strcmp(argv
[2], "checkpid"))
4208 DWORD pid
= GetProcessId(GetCurrentProcess());
4209 sscanf(argv
[3], "%x", &pid
);
4210 child_process_check_pid(pid
);
4213 if (!strcmp(argv
[2], "checksessionid"))
4216 ProcessIdToSessionId(GetProcessId(GetCurrentProcess()), &id
);
4217 sscanf(argv
[3], "%x", &id
);
4218 child_process_check_session_id(id
);
4221 if (!strcmp(argv
[2], "exit_process_async"))
4225 sscanf(argv
[3], "%x", &pid
);
4226 sscanf(argv
[4], "%p", &handle
);
4227 child_process_exit_process_async(pid
, handle
);
4232 if (test_DisconnectNamedPipe())
4234 test_CreateNamedPipe_instances_must_match();
4236 test_CreateNamedPipe(PIPE_TYPE_BYTE
);
4237 test_CreateNamedPipe(PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
);
4241 test_impersonation();
4243 test_overlapped_error();
4244 test_NamedPipeHandleState();
4245 test_GetNamedPipeInfo();
4246 test_readfileex_pending();
4247 test_overlapped_transport(TRUE
, FALSE
);
4248 test_overlapped_transport(TRUE
, TRUE
);
4249 test_overlapped_transport(FALSE
, FALSE
);
4250 test_TransactNamedPipe();
4251 test_namedpipe_process_id();
4252 test_namedpipe_session_id();
4253 test_multiple_instances();
4255 test_nowait(PIPE_TYPE_BYTE
);
4256 test_nowait(PIPE_TYPE_MESSAGE
);
4257 test_GetOverlappedResultEx();
4258 test_exit_process_async();