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
*pCancelSynchronousIo
)(HANDLE handle
);
41 static BOOL (WINAPI
*pGetNamedPipeClientProcessId
)(HANDLE
,ULONG
*);
42 static BOOL (WINAPI
*pGetNamedPipeServerProcessId
)(HANDLE
,ULONG
*);
43 static BOOL (WINAPI
*pGetNamedPipeClientSessionId
)(HANDLE
,ULONG
*);
44 static BOOL (WINAPI
*pGetNamedPipeServerSessionId
)(HANDLE
,ULONG
*);
45 static BOOL (WINAPI
*pGetOverlappedResultEx
)(HANDLE
,OVERLAPPED
*,DWORD
*,DWORD
,BOOL
);
47 static BOOL user_apc_ran
;
48 static void CALLBACK
user_apc(ULONG_PTR param
)
61 ULONG_PTR returnValue
;
67 static DWORD CALLBACK
rpcThreadMain(LPVOID arg
)
69 struct rpcThreadArgs
*rpcargs
= (struct rpcThreadArgs
*)arg
;
70 if (winetest_debug
> 1) trace("rpcThreadMain starting\n");
71 SetLastError( rpcargs
->lastError
);
76 rpcargs
->returnValue
= (ULONG_PTR
)ReadFile( (HANDLE
)rpcargs
->args
[0], /* hFile */
77 (LPVOID
)rpcargs
->args
[1], /* buffer */
78 (DWORD
)rpcargs
->args
[2], /* bytesToRead */
79 (LPDWORD
)rpcargs
->args
[3], /* bytesRead */
80 (LPOVERLAPPED
)rpcargs
->args
[4] ); /* overlapped */
84 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
85 rpcargs
->returnValue
= 0;
89 rpcargs
->lastError
= GetLastError();
90 if (winetest_debug
> 1) trace("rpcThreadMain returning\n");
94 /* Runs ReadFile(...) from a different thread */
95 static BOOL
RpcReadFile(HANDLE hFile
, LPVOID buffer
, DWORD bytesToRead
, LPDWORD bytesRead
, LPOVERLAPPED overlapped
)
97 struct rpcThreadArgs rpcargs
;
101 rpcargs
.returnValue
= 0;
102 rpcargs
.lastError
= GetLastError();
103 rpcargs
.op
= RPC_READFILE
;
104 rpcargs
.args
[0] = (ULONG_PTR
)hFile
;
105 rpcargs
.args
[1] = (ULONG_PTR
)buffer
;
106 rpcargs
.args
[2] = (ULONG_PTR
)bytesToRead
;
107 rpcargs
.args
[3] = (ULONG_PTR
)bytesRead
;
108 rpcargs
.args
[4] = (ULONG_PTR
)overlapped
;
110 thread
= CreateThread(NULL
, 0, rpcThreadMain
, (void *)&rpcargs
, 0, &threadId
);
111 ok(thread
!= NULL
, "CreateThread failed. %ld\n", GetLastError());
112 ret
= WaitForSingleObject(thread
, INFINITE
);
113 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject failed with %ld.\n", GetLastError());
116 SetLastError(rpcargs
.lastError
);
117 return (BOOL
)rpcargs
.returnValue
;
120 #define test_not_signaled(h) _test_not_signaled(__LINE__,h)
121 static void _test_not_signaled(unsigned line
, HANDLE handle
)
123 DWORD res
= WaitForSingleObject(handle
, 0);
124 ok_(__FILE__
,line
)(res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %lu (%lu)\n", res
, GetLastError());
127 #define test_signaled(h) _test_signaled(__LINE__,h)
128 static void _test_signaled(unsigned line
, HANDLE handle
)
130 DWORD res
= WaitForSingleObject(handle
, 0);
131 ok_(__FILE__
,line
)(res
== WAIT_OBJECT_0
, "WaitForSingleObject returned %lu\n", res
);
134 #define test_pipe_info(a,b,c,d,e) _test_pipe_info(__LINE__,a,b,c,d,e)
135 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
)
137 DWORD flags
= 0xdeadbeef, out_buf_size
= 0xdeadbeef, in_buf_size
= 0xdeadbeef, max_instances
= 0xdeadbeef;
140 res
= GetNamedPipeInfo(pipe
, &flags
, &out_buf_size
, &in_buf_size
, &max_instances
);
141 ok_(__FILE__
,line
)(res
, "GetNamedPipeInfo failed: %x\n", res
);
142 ok_(__FILE__
,line
)(flags
== ex_flags
, "flags = %lx, expected %lx\n", flags
, ex_flags
);
143 ok_(__FILE__
,line
)(out_buf_size
== ex_out_buf_size
, "out_buf_size = %lx, expected %lu\n", out_buf_size
, ex_out_buf_size
);
144 ok_(__FILE__
,line
)(in_buf_size
== ex_in_buf_size
, "in_buf_size = %lx, expected %lu\n", in_buf_size
, ex_in_buf_size
);
145 ok_(__FILE__
,line
)(max_instances
== ex_max_instances
, "max_instances = %lx, expected %lu\n", max_instances
, ex_max_instances
);
148 #define test_file_access(a,b) _test_file_access(__LINE__,a,b)
149 static void _test_file_access(unsigned line
, HANDLE handle
, DWORD expected_access
)
151 FILE_ACCESS_INFORMATION info
;
155 memset(&info
, 0x11, sizeof(info
));
156 status
= NtQueryInformationFile(handle
, &io
, &info
, sizeof(info
), FileAccessInformation
);
157 ok_(__FILE__
,line
)(status
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08lx\n", status
);
158 ok_(__FILE__
,line
)(info
.AccessFlags
== expected_access
, "got access %08lx expected %08lx\n",
159 info
.AccessFlags
, expected_access
);
162 static void test_CreateNamedPipe(int pipemode
)
166 static const char obuf
[] = "Bit Bucket";
167 static const char obuf2
[] = "More bits";
168 char ibuf
[32], *pbuf
;
176 if (pipemode
== PIPE_TYPE_BYTE
)
177 trace("test_CreateNamedPipe starting in byte mode\n");
179 trace("test_CreateNamedPipe starting in message mode\n");
181 /* Wait for nonexistent pipe */
182 ret
= WaitNamedPipeA(PIPENAME
, 2000);
183 ok(ret
== 0, "WaitNamedPipe returned %d for nonexistent pipe\n", ret
);
184 ok(GetLastError() == ERROR_FILE_NOT_FOUND
, "wrong error %lu\n", GetLastError());
186 /* Bad parameter checks */
187 hnp
= CreateNamedPipeA("not a named pipe", PIPE_ACCESS_DUPLEX
, pipemode
| PIPE_WAIT
,
188 /* nMaxInstances */ 1,
189 /* nOutBufSize */ 1024,
190 /* nInBufSize */ 1024,
191 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
192 /* lpSecurityAttrib */ NULL
);
193 ok(hnp
== INVALID_HANDLE_VALUE
&& GetLastError() == ERROR_INVALID_NAME
,
194 "CreateNamedPipe should fail if name doesn't start with \\\\.\\pipe\n");
196 if (pipemode
== PIPE_TYPE_BYTE
)
198 /* Bad parameter checks */
199 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_READMODE_MESSAGE
,
200 /* nMaxInstances */ 1,
201 /* nOutBufSize */ 1024,
202 /* nInBufSize */ 1024,
203 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
204 /* lpSecurityAttrib */ NULL
);
205 ok(hnp
== INVALID_HANDLE_VALUE
&& GetLastError() == ERROR_INVALID_PARAMETER
,
206 "CreateNamedPipe should fail with PIPE_TYPE_BYTE | PIPE_READMODE_MESSAGE\n");
209 hnp
= CreateNamedPipeA(NULL
,
210 PIPE_ACCESS_DUPLEX
, pipemode
| PIPE_WAIT
,
211 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
212 ok(hnp
== INVALID_HANDLE_VALUE
&& GetLastError() == ERROR_PATH_NOT_FOUND
,
213 "CreateNamedPipe should fail if name is NULL\n");
215 hFile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
216 ok(hFile
== INVALID_HANDLE_VALUE
217 && GetLastError() == ERROR_FILE_NOT_FOUND
,
218 "connecting to nonexistent named pipe should fail with ERROR_FILE_NOT_FOUND\n");
220 /* Functional checks */
222 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, pipemode
| PIPE_WAIT
,
223 /* nMaxInstances */ 1,
224 /* nOutBufSize */ 1024,
225 /* nInBufSize */ 1024,
226 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
227 /* lpSecurityAttrib */ NULL
);
228 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
231 test_file_access(hnp
, SYNCHRONIZE
| READ_CONTROL
| FILE_WRITE_ATTRIBUTES
232 | FILE_READ_ATTRIBUTES
| FILE_WRITE_PROPERTIES
| FILE_READ_PROPERTIES
233 | FILE_APPEND_DATA
| FILE_WRITE_DATA
| FILE_READ_DATA
);
235 ret
= PeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, NULL
);
236 ok(!ret
&& GetLastError() == ERROR_BAD_PIPE
, "PeekNamedPipe returned %x (%lu)\n",
237 ret
, GetLastError());
239 ret
= WaitNamedPipeA(PIPENAME
, 2000);
240 ok(ret
, "WaitNamedPipe failed (%ld)\n", GetLastError());
242 hFile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
243 ok(hFile
!= INVALID_HANDLE_VALUE
, "CreateFile failed (%ld)\n", GetLastError());
245 ok(!WaitNamedPipeA(PIPENAME
, 100), "WaitNamedPipe succeeded\n");
247 ok(GetLastError() == ERROR_SEM_TIMEOUT
, "wrong error %lu\n", GetLastError());
249 /* Test ConnectNamedPipe() in both directions */
250 ok(!ConnectNamedPipe(hnp
, NULL
), "ConnectNamedPipe(server) succeeded\n");
251 ok(GetLastError() == ERROR_PIPE_CONNECTED
, "expected ERROR_PIPE_CONNECTED, got %lu\n", GetLastError());
252 ok(!ConnectNamedPipe(hFile
, NULL
), "ConnectNamedPipe(client) succeeded\n");
253 ok(GetLastError() == ERROR_INVALID_FUNCTION
, "expected ERROR_INVALID_FUNCTION, got %lu\n", GetLastError());
255 /* don't try to do i/o if one side couldn't be opened, as it hangs */
256 if (hFile
!= INVALID_HANDLE_VALUE
) {
259 /* Make sure we can read and write a few bytes in both directions */
260 memset(ibuf
, 0, sizeof(ibuf
));
261 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile\n");
262 ok(written
== sizeof(obuf
), "write file len\n");
263 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
264 ok(readden
== sizeof(obuf
), "read got %ld bytes\n", readden
);
265 ok(memcmp(obuf
, ibuf
, written
) == 0, "content check\n");
267 memset(ibuf
, 0, sizeof(ibuf
));
268 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile\n");
269 ok(written
== sizeof(obuf2
), "write file len\n");
270 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
271 ok(readden
== sizeof(obuf2
), "read got %ld bytes\n", readden
);
272 ok(memcmp(obuf2
, ibuf
, written
) == 0, "content check\n");
274 /* Now the same again, but with an additional call to PeekNamedPipe */
275 memset(ibuf
, 0, sizeof(ibuf
));
276 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile\n");
277 ok(written
== sizeof(obuf
), "write file len 1\n");
278 ok(PeekNamedPipe(hFile
, NULL
, 0, NULL
, &avail
, &left
), "Peek\n");
279 ok(avail
== sizeof(obuf
), "peek 1 got %ld bytes\n", avail
);
280 if (pipemode
== PIPE_TYPE_BYTE
)
281 ok(left
== 0, "peek 1 got %ld bytes left\n", left
);
283 ok(left
== sizeof(obuf
), "peek 1 got %ld bytes left\n", left
);
284 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
285 ok(readden
== sizeof(obuf
), "read 1 got %ld bytes\n", readden
);
286 ok(memcmp(obuf
, ibuf
, written
) == 0, "content 1 check\n");
288 memset(ibuf
, 0, sizeof(ibuf
));
289 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile\n");
290 ok(written
== sizeof(obuf2
), "write file len 2\n");
291 ok(PeekNamedPipe(hnp
, NULL
, 0, NULL
, &avail
, &left
), "Peek\n");
292 ok(avail
== sizeof(obuf2
), "peek 2 got %ld bytes\n", avail
);
293 if (pipemode
== PIPE_TYPE_BYTE
)
294 ok(left
== 0, "peek 2 got %ld bytes left\n", left
);
296 ok(left
== sizeof(obuf2
), "peek 2 got %ld bytes left\n", left
);
297 ok(PeekNamedPipe(hnp
, (LPVOID
)1, 0, NULL
, &avail
, &left
), "Peek\n");
298 ok(avail
== sizeof(obuf2
), "peek 2 got %ld bytes\n", avail
);
299 if (pipemode
== PIPE_TYPE_BYTE
)
300 ok(left
== 0, "peek 2 got %ld bytes left\n", left
);
302 ok(left
== sizeof(obuf2
), "peek 2 got %ld bytes left\n", left
);
303 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
304 ok(readden
== sizeof(obuf2
), "read 2 got %ld bytes\n", readden
);
305 ok(memcmp(obuf2
, ibuf
, written
) == 0, "content 2 check\n");
307 /* Test how ReadFile behaves when the buffer is not big enough for the whole message */
308 memset(ibuf
, 0, sizeof(ibuf
));
309 ok(WriteFile(hnp
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile\n");
310 ok(written
== sizeof(obuf2
), "write file len\n");
311 ok(PeekNamedPipe(hFile
, ibuf
, 4, &readden
, &avail
, &left
), "Peek\n");
312 ok(readden
== 4, "peek got %ld bytes\n", readden
);
313 ok(avail
== sizeof(obuf2
), "peek got %ld bytes available\n", avail
);
314 if (pipemode
== PIPE_TYPE_BYTE
)
315 ok(left
== -4, "peek got %ld bytes left\n", left
);
317 ok(left
== sizeof(obuf2
)-4, "peek got %ld bytes left\n", left
);
318 ok(ReadFile(hFile
, ibuf
, 4, &readden
, NULL
), "ReadFile\n");
319 ok(readden
== 4, "read got %ld bytes\n", readden
);
320 ok(ReadFile(hFile
, ibuf
+ 4, sizeof(ibuf
) - 4, &readden
, NULL
), "ReadFile\n");
321 ok(readden
== sizeof(obuf2
) - 4, "read got %ld bytes\n", readden
);
322 ok(memcmp(obuf2
, ibuf
, written
) == 0, "content check\n");
324 memset(ibuf
, 0, sizeof(ibuf
));
325 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile\n");
326 ok(written
== sizeof(obuf
), "write file len\n");
327 ok(PeekNamedPipe(hnp
, ibuf
, 4, &readden
, &avail
, &left
), "Peek\n");
328 ok(readden
== 4, "peek got %ld bytes\n", readden
);
329 ok(avail
== sizeof(obuf
), "peek got %ld bytes available\n", avail
);
330 if (pipemode
== PIPE_TYPE_BYTE
)
332 ok(left
== -4, "peek got %ld bytes left\n", left
);
333 ok(ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile\n");
337 ok(left
== sizeof(obuf
)-4, "peek got %ld bytes left\n", left
);
338 SetLastError(0xdeadbeef);
339 ok(!ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile\n");
340 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error\n");
342 ok(readden
== 4, "read got %ld bytes\n", readden
);
343 ok(ReadFile(hnp
, ibuf
+ 4, sizeof(ibuf
) - 4, &readden
, NULL
), "ReadFile\n");
344 ok(readden
== sizeof(obuf
) - 4, "read got %ld bytes\n", readden
);
345 ok(memcmp(obuf
, ibuf
, written
) == 0, "content check\n");
347 /* Similar to above, but use a read buffer size small enough to read in three parts */
348 memset(ibuf
, 0, sizeof(ibuf
));
349 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile\n");
350 ok(written
== sizeof(obuf2
), "write file len\n");
351 if (pipemode
== PIPE_TYPE_BYTE
)
353 ok(ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile\n");
354 ok(readden
== 4, "read got %ld bytes\n", readden
);
355 ok(ReadFile(hnp
, ibuf
+ 4, 4, &readden
, NULL
), "ReadFile\n");
359 SetLastError(0xdeadbeef);
360 ok(!ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile\n");
361 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error\n");
362 ok(readden
== 4, "read got %ld bytes\n", readden
);
363 SetLastError(0xdeadbeef);
364 ok(!ReadFile(hnp
, ibuf
+ 4, 4, &readden
, NULL
), "ReadFile\n");
365 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error\n");
367 ok(readden
== 4, "read got %ld bytes\n", readden
);
368 ok(ReadFile(hnp
, ibuf
+ 8, sizeof(ibuf
) - 8, &readden
, NULL
), "ReadFile\n");
369 ok(readden
== sizeof(obuf2
) - 8, "read got %ld bytes\n", readden
);
370 ok(memcmp(obuf2
, ibuf
, written
) == 0, "content check\n");
372 /* Test reading of multiple writes */
373 memset(ibuf
, 0, sizeof(ibuf
));
374 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile3a\n");
375 ok(written
== sizeof(obuf
), "write file len 3a\n");
376 ok(WriteFile(hnp
, obuf2
, sizeof(obuf2
), &written
, NULL
), " WriteFile3b\n");
377 ok(written
== sizeof(obuf2
), "write file len 3b\n");
378 ok(PeekNamedPipe(hFile
, ibuf
, 4, &readden
, &avail
, &left
), "Peek3\n");
379 ok(readden
== 4, "peek3 got %ld bytes\n", readden
);
380 if (pipemode
== PIPE_TYPE_BYTE
)
381 ok(left
== -4, "peek3 got %ld bytes left\n", left
);
383 ok(left
== sizeof(obuf
)-4, "peek3 got %ld bytes left\n", left
);
384 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek3 got %ld bytes available\n", avail
);
385 ok(PeekNamedPipe(hFile
, ibuf
, sizeof(ibuf
), &readden
, &avail
, &left
), "Peek3\n");
386 if (pipemode
== PIPE_TYPE_BYTE
) {
387 ok(readden
== sizeof(obuf
) + sizeof(obuf2
), "peek3 got %ld bytes\n", readden
);
388 ok(left
== (DWORD
) -(sizeof(obuf
) + sizeof(obuf2
)), "peek3 got %ld bytes left\n", left
);
392 ok(readden
== sizeof(obuf
), "peek3 got %ld bytes\n", readden
);
393 ok(left
== 0, "peek3 got %ld bytes left\n", left
);
395 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek3 got %ld bytes available\n", avail
);
397 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "pipe content 3a check\n");
398 if (pipemode
== PIPE_TYPE_BYTE
&& readden
>= sizeof(obuf
)+sizeof(obuf2
)) {
399 pbuf
+= sizeof(obuf
);
400 ok(memcmp(obuf2
, pbuf
, sizeof(obuf2
)) == 0, "pipe content 3b check\n");
402 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
403 ok(readden
== sizeof(obuf
) + sizeof(obuf2
), "read 3 got %ld bytes\n", readden
);
405 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 3a check\n");
406 pbuf
+= sizeof(obuf
);
407 ok(memcmp(obuf2
, pbuf
, sizeof(obuf2
)) == 0, "content 3b check\n");
409 /* Multiple writes in the reverse direction */
410 memset(ibuf
, 0, sizeof(ibuf
));
411 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile4a\n");
412 ok(written
== sizeof(obuf
), "write file len 4a\n");
413 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), " WriteFile4b\n");
414 ok(written
== sizeof(obuf2
), "write file len 4b\n");
415 ok(PeekNamedPipe(hnp
, ibuf
, 4, &readden
, &avail
, &left
), "Peek3\n");
416 ok(readden
== 4, "peek3 got %ld bytes\n", readden
);
417 if (pipemode
== PIPE_TYPE_BYTE
)
418 ok(left
== -4, "peek3 got %ld bytes left\n", left
);
420 ok(left
== sizeof(obuf
)-4, "peek3 got %ld bytes left\n", left
);
421 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek3 got %ld bytes available\n", avail
);
422 ok(PeekNamedPipe(hnp
, ibuf
, sizeof(ibuf
), &readden
, &avail
, &left
), "Peek4\n");
423 if (pipemode
== PIPE_TYPE_BYTE
) {
424 ok(readden
== sizeof(obuf
) + sizeof(obuf2
), "peek4 got %ld bytes\n", readden
);
425 ok(left
== (DWORD
) -(sizeof(obuf
) + sizeof(obuf2
)), "peek4 got %ld bytes left\n", left
);
429 ok(readden
== sizeof(obuf
), "peek4 got %ld bytes\n", readden
);
430 ok(left
== 0, "peek4 got %ld bytes left\n", left
);
432 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek4 got %ld bytes available\n", avail
);
434 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "pipe content 4a check\n");
435 if (pipemode
== PIPE_TYPE_BYTE
&& readden
>= sizeof(obuf
)+sizeof(obuf2
)) {
436 pbuf
+= sizeof(obuf
);
437 ok(memcmp(obuf2
, pbuf
, sizeof(obuf2
)) == 0, "pipe content 4b check\n");
439 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
440 if (pipemode
== PIPE_TYPE_BYTE
) {
441 ok(readden
== sizeof(obuf
) + sizeof(obuf2
), "read 4 got %ld bytes\n", readden
);
444 ok(readden
== sizeof(obuf
), "read 4 got %ld bytes\n", readden
);
447 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 4a check\n");
448 if (pipemode
== PIPE_TYPE_BYTE
) {
449 pbuf
+= sizeof(obuf
);
450 ok(memcmp(obuf2
, pbuf
, sizeof(obuf2
)) == 0, "content 4b check\n");
453 /* Test reading of multiple writes after a mode change
454 (CreateFile always creates a byte mode pipe) */
455 lpmode
= PIPE_READMODE_MESSAGE
;
456 if (pipemode
== PIPE_TYPE_BYTE
) {
457 /* trying to change the client end of a byte pipe to message mode should fail */
458 ok(!SetNamedPipeHandleState(hFile
, &lpmode
, NULL
, NULL
), "Change mode\n");
461 ok(SetNamedPipeHandleState(hFile
, &lpmode
, NULL
, NULL
), "Change mode\n");
463 memset(ibuf
, 0, sizeof(ibuf
));
464 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile5a\n");
465 ok(written
== sizeof(obuf
), "write file len 3a\n");
466 ok(WriteFile(hnp
, obuf2
, sizeof(obuf2
), &written
, NULL
), " WriteFile5b\n");
467 ok(written
== sizeof(obuf2
), "write file len 3b\n");
468 ok(PeekNamedPipe(hFile
, ibuf
, sizeof(ibuf
), &readden
, &avail
, &left
), "Peek5\n");
469 ok(readden
== sizeof(obuf
), "peek5 got %ld bytes\n", readden
);
470 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek5 got %ld bytes available\n", avail
);
471 ok(left
== 0, "peek5 got %ld bytes left\n", left
);
473 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 5a check\n");
474 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
475 ok(readden
== sizeof(obuf
), "read 5 got %ld bytes\n", readden
);
477 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 5a check\n");
478 if (readden
<= sizeof(obuf
))
479 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
481 /* Multiple writes in the reverse direction */
482 /* the write of obuf2 from write4 should still be in the buffer */
483 ok(PeekNamedPipe(hnp
, ibuf
, sizeof(ibuf
), &readden
, &avail
, NULL
), "Peek6a\n");
484 ok(readden
== sizeof(obuf2
), "peek6a got %ld bytes\n", readden
);
485 ok(avail
== sizeof(obuf2
), "peek6a got %ld bytes available\n", avail
);
487 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
488 ok(readden
== sizeof(obuf2
), "read 6a got %ld bytes\n", readden
);
490 ok(memcmp(obuf2
, pbuf
, sizeof(obuf2
)) == 0, "content 6a check\n");
492 memset(ibuf
, 0, sizeof(ibuf
));
493 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile6a\n");
494 ok(written
== sizeof(obuf
), "write file len 6a\n");
495 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), " WriteFile6b\n");
496 ok(written
== sizeof(obuf2
), "write file len 6b\n");
497 ok(PeekNamedPipe(hnp
, ibuf
, sizeof(ibuf
), &readden
, &avail
, NULL
), "Peek6\n");
498 ok(readden
== sizeof(obuf
), "peek6 got %ld bytes\n", readden
);
500 ok(avail
== sizeof(obuf
) + sizeof(obuf2
), "peek6b got %ld bytes available\n", avail
);
502 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 6a check\n");
503 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
504 ok(readden
== sizeof(obuf
), "read 6b got %ld bytes\n", readden
);
506 ok(memcmp(obuf
, pbuf
, sizeof(obuf
)) == 0, "content 6a check\n");
507 if (readden
<= sizeof(obuf
))
508 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
), "ReadFile\n");
510 /* Test how ReadFile behaves when the buffer is not big enough for the whole message */
511 memset(ibuf
, 0, sizeof(ibuf
));
512 ok(WriteFile(hnp
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile 7\n");
513 ok(written
== sizeof(obuf2
), "write file len 7\n");
514 SetLastError(0xdeadbeef);
515 ok(!ReadFile(hFile
, ibuf
, 4, &readden
, NULL
), "ReadFile 7\n");
516 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 7\n");
517 ok(readden
== 4, "read got %ld bytes 7\n", readden
);
518 ok(ReadFile(hFile
, ibuf
+ 4, sizeof(ibuf
) - 4, &readden
, NULL
), "ReadFile 7\n");
519 ok(readden
== sizeof(obuf2
) - 4, "read got %ld bytes 7\n", readden
);
520 ok(memcmp(obuf2
, ibuf
, written
) == 0, "content check 7\n");
522 memset(ibuf
, 0, sizeof(ibuf
));
523 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile 8\n");
524 ok(written
== sizeof(obuf
), "write file len 8\n");
525 SetLastError(0xdeadbeef);
526 ok(!ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile 8\n");
527 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 8\n");
528 ok(readden
== 4, "read got %ld bytes 8\n", readden
);
529 ok(ReadFile(hnp
, ibuf
+ 4, sizeof(ibuf
) - 4, &readden
, NULL
), "ReadFile 8\n");
530 ok(readden
== sizeof(obuf
) - 4, "read got %ld bytes 8\n", readden
);
531 ok(memcmp(obuf
, ibuf
, written
) == 0, "content check 8\n");
533 /* The following test shows that when doing a partial read of a message, the rest
534 * is still in the pipe, and can be received from a second thread. This shows
535 * especially that the content is _not_ stored in thread-local-storage until it is
536 * completely transmitted. The same method works even across multiple processes. */
537 memset(ibuf
, 0, sizeof(ibuf
));
538 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile 9\n");
539 ok(written
== sizeof(obuf
), "write file len 9\n");
540 ok(WriteFile(hnp
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile 9\n");
541 ok(written
== sizeof(obuf2
), "write file len 9\n");
542 SetLastError(0xdeadbeef);
543 ok(!ReadFile(hFile
, ibuf
, 4, &readden
, NULL
), "ReadFile 9\n");
544 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 9\n");
545 ok(readden
== 4, "read got %ld bytes 9\n", readden
);
546 SetLastError(0xdeadbeef);
547 ret
= RpcReadFile(hFile
, ibuf
+ 4, 4, &readden
, NULL
);
548 ok(!ret
, "RpcReadFile 9\n");
549 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 9\n");
550 ok(readden
== 4, "read got %ld bytes 9\n", readden
);
551 ret
= RpcReadFile(hFile
, ibuf
+ 8, sizeof(ibuf
), &readden
, NULL
);
552 ok(ret
, "RpcReadFile 9\n");
553 ok(readden
== sizeof(obuf
) - 8, "read got %ld bytes 9\n", readden
);
554 ok(memcmp(obuf
, ibuf
, sizeof(obuf
)) == 0, "content check 9\n");
555 if (readden
<= sizeof(obuf
) - 8) /* blocks forever if second part was already received */
557 memset(ibuf
, 0, sizeof(ibuf
));
558 SetLastError(0xdeadbeef);
559 ret
= RpcReadFile(hFile
, ibuf
, 4, &readden
, NULL
);
560 ok(!ret
, "RpcReadFile 9\n");
561 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 9\n");
562 ok(readden
== 4, "read got %ld bytes 9\n", readden
);
563 SetLastError(0xdeadbeef);
564 ok(!ReadFile(hFile
, ibuf
+ 4, 4, &readden
, NULL
), "ReadFile 9\n");
565 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 9\n");
566 ok(readden
== 4, "read got %ld bytes 9\n", readden
);
567 ret
= RpcReadFile(hFile
, ibuf
+ 8, sizeof(ibuf
), &readden
, NULL
);
568 ok(ret
, "RpcReadFile 9\n");
569 ok(readden
== sizeof(obuf2
) - 8, "read got %ld bytes 9\n", readden
);
570 ok(memcmp(obuf2
, ibuf
, sizeof(obuf2
)) == 0, "content check 9\n");
573 /* Now the reverse direction */
574 memset(ibuf
, 0, sizeof(ibuf
));
575 ok(WriteFile(hFile
, obuf2
, sizeof(obuf2
), &written
, NULL
), "WriteFile 10\n");
576 ok(written
== sizeof(obuf2
), "write file len 10\n");
577 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile 10\n");
578 ok(written
== sizeof(obuf
), "write file len 10\n");
579 SetLastError(0xdeadbeef);
580 ok(!ReadFile(hnp
, ibuf
, 4, &readden
, NULL
), "ReadFile 10\n");
581 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 10\n");
582 ok(readden
== 4, "read got %ld bytes 10\n", readden
);
583 SetLastError(0xdeadbeef);
584 ret
= RpcReadFile(hnp
, ibuf
+ 4, 4, &readden
, NULL
);
585 ok(!ret
, "RpcReadFile 10\n");
586 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 10\n");
587 ok(readden
== 4, "read got %ld bytes 10\n", readden
);
588 ret
= RpcReadFile(hnp
, ibuf
+ 8, sizeof(ibuf
), &readden
, NULL
);
589 ok(ret
, "RpcReadFile 10\n");
590 ok(readden
== sizeof(obuf2
) - 8, "read got %ld bytes 10\n", readden
);
591 ok(memcmp(obuf2
, ibuf
, sizeof(obuf2
)) == 0, "content check 10\n");
592 if (readden
<= sizeof(obuf2
) - 8) /* blocks forever if second part was already received */
594 memset(ibuf
, 0, sizeof(ibuf
));
595 SetLastError(0xdeadbeef);
596 ret
= RpcReadFile(hnp
, ibuf
, 4, &readden
, NULL
);
597 ok(!ret
, "RpcReadFile 10\n");
598 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 10\n");
599 ok(readden
== 4, "read got %ld bytes 10\n", readden
);
600 SetLastError(0xdeadbeef);
601 ok(!ReadFile(hnp
, ibuf
+ 4, 4, &readden
, NULL
), "ReadFile 10\n");
602 ok(GetLastError() == ERROR_MORE_DATA
, "wrong error 10\n");
603 ok(readden
== 4, "read got %ld bytes 10\n", readden
);
604 ret
= RpcReadFile(hnp
, ibuf
+ 8, sizeof(ibuf
), &readden
, NULL
);
605 ok(ret
, "RpcReadFile 10\n");
606 ok(readden
== sizeof(obuf
) - 8, "read got %ld bytes 10\n", readden
);
607 ok(memcmp(obuf
, ibuf
, sizeof(obuf
)) == 0, "content check 10\n");
612 /* Picky conformance tests */
614 /* Verify that you can't connect to pipe again
615 * until server calls DisconnectNamedPipe+ConnectNamedPipe
616 * or creates a new pipe
617 * case 1: other client not yet closed
619 hFile2
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
620 ok(hFile2
== INVALID_HANDLE_VALUE
,
621 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n");
622 ok(GetLastError() == ERROR_PIPE_BUSY
,
623 "connecting to named pipe before other client closes should fail with ERROR_PIPE_BUSY\n");
625 ok(CloseHandle(hFile
), "CloseHandle\n");
627 /* case 2: other client already closed */
628 hFile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
629 ok(hFile
== INVALID_HANDLE_VALUE
,
630 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n");
631 ok(GetLastError() == ERROR_PIPE_BUSY
,
632 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail with ERROR_PIPE_BUSY\n");
634 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe\n");
636 /* case 3: server has called DisconnectNamedPipe but not ConnectNamed Pipe */
637 hFile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
638 ok(hFile
== INVALID_HANDLE_VALUE
,
639 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n");
640 ok(GetLastError() == ERROR_PIPE_BUSY
,
641 "connecting to named pipe after other client closes but before ConnectNamedPipe should fail with ERROR_PIPE_BUSY\n");
643 /* to be complete, we'd call ConnectNamedPipe here and loop,
644 * but by default that's blocking, so we'd either have
645 * to turn on the uncommon nonblocking mode, or
646 * use another thread.
650 ok(CloseHandle(hnp
), "CloseHandle\n");
652 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_INBOUND
, pipemode
| PIPE_WAIT
,
653 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
654 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
657 test_file_access(hnp
, SYNCHRONIZE
| READ_CONTROL
| FILE_READ_ATTRIBUTES
| FILE_READ_PROPERTIES
662 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_OUTBOUND
, pipemode
| PIPE_WAIT
,
663 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
664 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
667 test_file_access(hnp
, SYNCHRONIZE
| READ_CONTROL
| FILE_WRITE_ATTRIBUTES
668 | FILE_WRITE_PROPERTIES
| FILE_APPEND_DATA
| FILE_WRITE_DATA
);
670 hFile
= CreateFileA(PIPENAME
, 0, 0, NULL
, OPEN_EXISTING
, 0, 0);
671 ok(hFile
!= INVALID_HANDLE_VALUE
, "CreateFile failed: %lu\n", GetLastError());
672 test_file_access(hFile
, SYNCHRONIZE
| FILE_READ_ATTRIBUTES
);
677 hnp
= CreateNamedPipeA("\\\\.\\pipe\\a<>*?|\"/b", PIPE_ACCESS_DUPLEX
,
678 PIPE_TYPE_BYTE
, 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
679 ok(hnp
!= INVALID_HANDLE_VALUE
, "failed to create pipe, error %lu\n", GetLastError());
680 hFile
= CreateFileA("\\\\.\\pipe\\a<>*?|\"/b", 0, 0, NULL
, OPEN_EXISTING
, 0, 0);
681 ok(hFile
!= INVALID_HANDLE_VALUE
, "failed to open pipe, error %lu\n", GetLastError());
685 hnp
= CreateNamedPipeA("\\\\.\\pipe\\trailingslash\\", PIPE_ACCESS_DUPLEX
,
686 PIPE_TYPE_BYTE
, 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
687 ok(hnp
!= INVALID_HANDLE_VALUE
, "failed to create pipe, error %lu\n", GetLastError());
688 hFile
= CreateFileA("\\\\.\\pipe\\trailingslash", 0, 0, NULL
, OPEN_EXISTING
, 0, 0);
689 ok(hFile
== INVALID_HANDLE_VALUE
, "expected opening pipe to fail\n");
690 ok(GetLastError() == ERROR_FILE_NOT_FOUND
, "expected ERROR_FILE_NOT_FOUND, got %lu\n", GetLastError());
691 hFile
= CreateFileA("\\\\.\\pipe\\trailingslash\\", 0, 0, NULL
, OPEN_EXISTING
, 0, 0);
692 ok(hFile
!= INVALID_HANDLE_VALUE
, "failed to open pipe, error %lu\n", GetLastError());
696 if (winetest_debug
> 1) trace("test_CreateNamedPipe returning\n");
699 static void test_CreateNamedPipe_instances_must_match(void)
703 /* Check no mismatch */
704 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
705 /* nMaxInstances */ 2,
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 */ 2,
714 /* nOutBufSize */ 1024,
715 /* nInBufSize */ 1024,
716 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
717 /* lpSecurityAttrib */ NULL
);
718 ok(hnp2
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
720 ok(CloseHandle(hnp
), "CloseHandle\n");
721 ok(CloseHandle(hnp2
), "CloseHandle\n");
723 /* Check nMaxInstances */
724 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
725 /* nMaxInstances */ 1,
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_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
733 /* nMaxInstances */ 1,
734 /* nOutBufSize */ 1024,
735 /* nInBufSize */ 1024,
736 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
737 /* lpSecurityAttrib */ NULL
);
738 ok(hnp2
== INVALID_HANDLE_VALUE
739 && GetLastError() == ERROR_PIPE_BUSY
, "nMaxInstances not obeyed\n");
741 ok(CloseHandle(hnp
), "CloseHandle\n");
743 /* Check PIPE_ACCESS_* */
744 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
745 /* nMaxInstances */ 2,
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_INBOUND
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
753 /* nMaxInstances */ 2,
754 /* nOutBufSize */ 1024,
755 /* nInBufSize */ 1024,
756 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
757 /* lpSecurityAttrib */ NULL
);
758 ok(hnp2
== INVALID_HANDLE_VALUE
759 && GetLastError() == ERROR_ACCESS_DENIED
, "PIPE_ACCESS_* mismatch allowed\n");
761 ok(CloseHandle(hnp
), "CloseHandle\n");
763 /* check everything else */
764 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
765 /* nMaxInstances */ 4,
766 /* nOutBufSize */ 1024,
767 /* nInBufSize */ 1024,
768 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
769 /* lpSecurityAttrib */ NULL
);
770 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
772 hnp2
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_MESSAGE
,
773 /* nMaxInstances */ 3,
774 /* nOutBufSize */ 102,
776 /* nDefaultWait */ 1234,
777 /* lpSecurityAttrib */ NULL
);
778 ok(hnp2
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
780 ok(CloseHandle(hnp
), "CloseHandle\n");
781 ok(CloseHandle(hnp2
), "CloseHandle\n");
784 static void test_ReadFile(void)
786 HANDLE server
, client
;
787 OVERLAPPED overlapped
;
791 static char buf
[512];
793 server
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
794 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
795 1, 1024, 1024, NMPWAIT_WAIT_FOREVER
, NULL
);
796 ok(server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %lu\n", GetLastError());
798 client
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
,
799 OPEN_EXISTING
, 0, 0);
800 ok(client
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %lu\n", GetLastError());
802 ok(WriteFile(client
, buf
, sizeof(buf
), &size
, NULL
), "WriteFile\n");
804 res
= ReadFile(server
, buf
, 1, &size
, NULL
);
805 ok(!res
&& GetLastError() == ERROR_MORE_DATA
, "ReadFile returned %x(%lu)\n", res
, GetLastError());
806 ok(size
== 1, "size = %lu\n", size
);
808 /* pass both overlapped and ret read */
809 memset(&overlapped
, 0, sizeof(overlapped
));
810 res
= ReadFile(server
, buf
, 1, &size
, &overlapped
);
811 ok(!res
&& GetLastError() == ERROR_MORE_DATA
, "ReadFile returned %x(%lu)\n", res
, GetLastError());
812 ok(size
== 0, "size = %lu\n", size
);
813 ok((NTSTATUS
)overlapped
.Internal
== STATUS_BUFFER_OVERFLOW
, "Internal = %Ix\n", overlapped
.Internal
);
814 ok(overlapped
.InternalHigh
== 1, "InternalHigh = %Ix\n", overlapped
.InternalHigh
);
816 DisconnectNamedPipe(server
);
818 memset(&overlapped
, 0, sizeof(overlapped
));
819 overlapped
.InternalHigh
= 0xdeadbeef;
820 res
= ReadFile(server
, buf
, 1, &size
, &overlapped
);
821 ok(!res
&& GetLastError() == ERROR_PIPE_NOT_CONNECTED
, "ReadFile returned %x(%lu)\n", res
, GetLastError());
822 ok(size
== 0, "size = %lu\n", size
);
823 ok(overlapped
.Internal
== STATUS_PENDING
, "Internal = %Ix\n", overlapped
.Internal
);
824 ok(overlapped
.InternalHigh
== 0xdeadbeef, "InternalHigh = %Ix\n", overlapped
.InternalHigh
);
826 memset(&overlapped
, 0, sizeof(overlapped
));
827 overlapped
.InternalHigh
= 0xdeadbeef;
828 res
= WriteFile(server
, buf
, 1, &size
, &overlapped
);
829 ok(!res
&& GetLastError() == ERROR_PIPE_NOT_CONNECTED
, "ReadFile returned %x(%lu)\n", res
, GetLastError());
830 ok(size
== 0, "size = %lu\n", size
);
831 ok(overlapped
.Internal
== STATUS_PENDING
, "Internal = %Ix\n", overlapped
.Internal
);
832 ok(overlapped
.InternalHigh
== 0xdeadbeef, "InternalHigh = %Ix\n", overlapped
.InternalHigh
);
838 /** implementation of alarm() */
839 static DWORD CALLBACK
alarmThreadMain(LPVOID arg
)
841 DWORD_PTR timeout
= (DWORD_PTR
) arg
;
842 if (winetest_debug
> 1) trace("alarmThreadMain\n");
843 if (WaitForSingleObject( alarm_event
, timeout
) == WAIT_TIMEOUT
)
845 ok(FALSE
, "alarm\n");
851 static HANDLE hnp
= INVALID_HANDLE_VALUE
;
853 /** Trivial byte echo server - disconnects after each session */
854 static DWORD CALLBACK
serverThreadMain1(LPVOID arg
)
858 if (winetest_debug
> 1) trace("serverThreadMain1 start\n");
859 /* Set up a simple echo server */
860 hnp
= CreateNamedPipeA(PIPENAME
"serverThreadMain1", PIPE_ACCESS_DUPLEX
,
861 PIPE_TYPE_BYTE
| PIPE_WAIT
,
862 /* nMaxInstances */ 1,
863 /* nOutBufSize */ 1024,
864 /* nInBufSize */ 1024,
865 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
866 /* lpSecurityAttrib */ NULL
);
868 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
869 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
875 /* Wait for client to connect */
876 if (winetest_debug
> 1) trace("Server calling ConnectNamedPipe...\n");
877 ok(ConnectNamedPipe(hnp
, NULL
)
878 || GetLastError() == ERROR_PIPE_CONNECTED
, "ConnectNamedPipe\n");
879 if (winetest_debug
> 1) trace("ConnectNamedPipe returned.\n");
881 /* Echo bytes once */
882 memset(buf
, 0, sizeof(buf
));
884 if (winetest_debug
> 1) trace("Server reading...\n");
885 success
= ReadFile(hnp
, buf
, sizeof(buf
), &readden
, NULL
);
886 if (winetest_debug
> 1) trace("Server done reading.\n");
887 ok(success
, "ReadFile\n");
888 ok(readden
, "short read\n");
890 if (winetest_debug
> 1) trace("Server writing...\n");
891 ok(WriteFile(hnp
, buf
, readden
, &written
, NULL
), "WriteFile\n");
892 if (winetest_debug
> 1) trace("Server done writing.\n");
893 ok(written
== readden
, "write file len\n");
895 /* finish this connection, wait for next one */
896 ok(FlushFileBuffers(hnp
), "FlushFileBuffers\n");
897 if (winetest_debug
> 1) trace("Server done flushing.\n");
898 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe\n");
899 if (winetest_debug
> 1) trace("Server done disconnecting.\n");
904 /** Trivial byte echo server - closes after each connection */
905 static DWORD CALLBACK
serverThreadMain2(LPVOID arg
)
910 trace("serverThreadMain2\n");
911 /* Set up a simple echo server */
912 hnp
= CreateNamedPipeA(PIPENAME
"serverThreadMain2", PIPE_ACCESS_DUPLEX
,
913 PIPE_TYPE_BYTE
| PIPE_WAIT
,
914 /* nMaxInstances */ 2,
915 /* nOutBufSize */ 1024,
916 /* nInBufSize */ 1024,
917 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
918 /* lpSecurityAttrib */ NULL
);
919 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
921 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
929 user_apc_ran
= FALSE
;
932 if (winetest_debug
> 1) trace("Queueing an user APC\n"); /* verify the pipe is non alerable */
933 ret
= QueueUserAPC(&user_apc
, GetCurrentThread(), 0);
934 ok(ret
, "QueueUserAPC failed: %ld\n", GetLastError());
937 /* Wait for client to connect */
938 if (winetest_debug
> 1) trace("Server calling ConnectNamedPipe...\n");
939 ok(ConnectNamedPipe(hnp
, NULL
)
940 || GetLastError() == ERROR_PIPE_CONNECTED
, "ConnectNamedPipe\n");
941 if (winetest_debug
> 1) trace("ConnectNamedPipe returned.\n");
943 /* Echo bytes once */
944 memset(buf
, 0, sizeof(buf
));
946 if (winetest_debug
> 1) trace("Server reading...\n");
947 success
= ReadFile(hnp
, buf
, sizeof(buf
), &readden
, NULL
);
948 if (winetest_debug
> 1) trace("Server done reading.\n");
949 ok(success
, "ReadFile\n");
951 if (winetest_debug
> 1) trace("Server writing...\n");
952 ok(WriteFile(hnp
, buf
, readden
, &written
, NULL
), "WriteFile\n");
953 if (winetest_debug
> 1) trace("Server done writing.\n");
954 ok(written
== readden
, "write file len\n");
956 /* finish this connection, wait for next one */
957 ok(FlushFileBuffers(hnp
), "FlushFileBuffers\n");
958 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe\n");
960 ok(user_apc_ran
== FALSE
, "UserAPC ran, pipe using alertable io mode\n");
963 SleepEx(0, TRUE
); /* get rid of apc */
965 /* Set up next echo server */
967 CreateNamedPipeA(PIPENAME
"serverThreadMain2", PIPE_ACCESS_DUPLEX
,
968 PIPE_TYPE_BYTE
| PIPE_WAIT
,
969 /* nMaxInstances */ 2,
970 /* nOutBufSize */ 1024,
971 /* nInBufSize */ 1024,
972 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
973 /* lpSecurityAttrib */ NULL
);
975 ok(hnpNext
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
977 ok(CloseHandle(hnp
), "CloseHandle\n");
983 /** Trivial byte echo server - uses overlapped named pipe calls */
984 static DWORD CALLBACK
serverThreadMain3(LPVOID arg
)
989 if (winetest_debug
> 1) trace("serverThreadMain3\n");
990 /* Set up a simple echo server */
991 hnp
= CreateNamedPipeA(PIPENAME
"serverThreadMain3", PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
992 PIPE_TYPE_BYTE
| PIPE_WAIT
,
993 /* nMaxInstances */ 1,
994 /* nOutBufSize */ 1024,
995 /* nInBufSize */ 1024,
996 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
997 /* lpSecurityAttrib */ NULL
);
998 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
1000 hEvent
= CreateEventW(NULL
, /* security attribute */
1001 TRUE
, /* manual reset event */
1002 FALSE
, /* initial state */
1004 ok(hEvent
!= NULL
, "CreateEvent\n");
1006 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
1012 OVERLAPPED oOverlap
;
1013 int letWFSOEwait
= (i
& 2);
1014 int letGORwait
= (i
& 1);
1017 memset(&oOverlap
, 0, sizeof(oOverlap
));
1018 oOverlap
.hEvent
= hEvent
;
1020 /* Wait for client to connect */
1022 if (winetest_debug
> 1) trace("Server calling non-overlapped ConnectNamedPipe on overlapped pipe...\n");
1023 success
= ConnectNamedPipe(hnp
, NULL
);
1024 err
= GetLastError();
1025 ok(success
|| (err
== ERROR_PIPE_CONNECTED
), "ConnectNamedPipe failed: %ld\n", err
);
1026 if (winetest_debug
> 1) trace("ConnectNamedPipe operation complete.\n");
1028 if (winetest_debug
> 1) trace("Server calling overlapped ConnectNamedPipe...\n");
1029 success
= ConnectNamedPipe(hnp
, &oOverlap
);
1030 err
= GetLastError();
1031 ok(!success
&& (err
== ERROR_IO_PENDING
|| err
== ERROR_PIPE_CONNECTED
), "overlapped ConnectNamedPipe\n");
1032 if (winetest_debug
> 1) trace("overlapped ConnectNamedPipe returned.\n");
1033 if (!success
&& (err
== ERROR_IO_PENDING
)) {
1038 ret
= WaitForSingleObjectEx(hEvent
, INFINITE
, TRUE
);
1039 } while (ret
== WAIT_IO_COMPLETION
);
1040 ok(ret
== 0, "wait ConnectNamedPipe returned %lx\n", ret
);
1042 success
= GetOverlappedResult(hnp
, &oOverlap
, &dummy
, letGORwait
);
1043 if (!letGORwait
&& !letWFSOEwait
&& !success
) {
1044 ok(GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult\n");
1045 success
= GetOverlappedResult(hnp
, &oOverlap
, &dummy
, TRUE
);
1048 ok(success
|| (err
== ERROR_PIPE_CONNECTED
), "GetOverlappedResult ConnectNamedPipe\n");
1049 if (winetest_debug
> 1) trace("overlapped ConnectNamedPipe operation complete.\n");
1052 /* Echo bytes once */
1053 memset(buf
, 0, sizeof(buf
));
1055 if (winetest_debug
> 1) trace("Server reading...\n");
1056 success
= ReadFile(hnp
, buf
, sizeof(buf
), &readden
, &oOverlap
);
1057 if (winetest_debug
> 1) trace("Server ReadFile returned...\n");
1058 err
= GetLastError();
1059 ok(success
|| err
== ERROR_IO_PENDING
, "overlapped ReadFile\n");
1060 if (winetest_debug
> 1) trace("overlapped ReadFile returned.\n");
1061 if (!success
&& (err
== ERROR_IO_PENDING
)) {
1066 ret
= WaitForSingleObjectEx(hEvent
, INFINITE
, TRUE
);
1067 } while (ret
== WAIT_IO_COMPLETION
);
1068 ok(ret
== 0, "wait ReadFile returned %lx\n", ret
);
1070 success
= GetOverlappedResult(hnp
, &oOverlap
, &readden
, letGORwait
);
1071 if (!letGORwait
&& !letWFSOEwait
&& !success
) {
1072 ok(GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult\n");
1073 success
= GetOverlappedResult(hnp
, &oOverlap
, &readden
, TRUE
);
1076 if (winetest_debug
> 1) trace("Server done reading.\n");
1077 ok(success
, "overlapped ReadFile\n");
1079 if (winetest_debug
> 1) trace("Server writing...\n");
1080 success
= WriteFile(hnp
, buf
, readden
, &written
, &oOverlap
);
1081 if (winetest_debug
> 1) trace("Server WriteFile returned...\n");
1082 err
= GetLastError();
1083 ok(success
|| err
== ERROR_IO_PENDING
, "overlapped WriteFile\n");
1084 if (winetest_debug
> 1) trace("overlapped WriteFile returned.\n");
1085 if (!success
&& (err
== ERROR_IO_PENDING
)) {
1090 ret
= WaitForSingleObjectEx(hEvent
, INFINITE
, TRUE
);
1091 } while (ret
== WAIT_IO_COMPLETION
);
1092 ok(ret
== 0, "wait WriteFile returned %lx\n", ret
);
1094 success
= GetOverlappedResult(hnp
, &oOverlap
, &written
, letGORwait
);
1095 if (!letGORwait
&& !letWFSOEwait
&& !success
) {
1096 ok(GetLastError() == ERROR_IO_INCOMPLETE
, "GetOverlappedResult\n");
1097 success
= GetOverlappedResult(hnp
, &oOverlap
, &written
, TRUE
);
1100 if (winetest_debug
> 1) trace("Server done writing.\n");
1101 ok(success
, "overlapped WriteFile\n");
1102 ok(written
== readden
, "write file len\n");
1104 /* finish this connection, wait for next one */
1105 ok(FlushFileBuffers(hnp
), "FlushFileBuffers\n");
1106 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe\n");
1111 /** Trivial byte echo server - uses i/o completion ports */
1112 static DWORD CALLBACK
serverThreadMain4(LPVOID arg
)
1118 if (winetest_debug
> 1) trace("serverThreadMain4\n");
1119 /* Set up a simple echo server */
1120 hnp
= CreateNamedPipeA(PIPENAME
"serverThreadMain4", PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
1121 PIPE_TYPE_BYTE
| PIPE_WAIT
,
1122 /* nMaxInstances */ 1,
1123 /* nOutBufSize */ 1024,
1124 /* nInBufSize */ 1024,
1125 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1126 /* lpSecurityAttrib */ NULL
);
1127 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
1129 hcompletion
= CreateIoCompletionPort(hnp
, NULL
, 12345, 1);
1130 ok(hcompletion
!= NULL
, "CreateIoCompletionPort failed, error=%li\n", GetLastError());
1132 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
1138 OVERLAPPED oConnect
;
1141 OVERLAPPED
*oResult
;
1145 memset(&oConnect
, 0, sizeof(oConnect
));
1146 memset(&oRead
, 0, sizeof(oRead
));
1147 memset(&oWrite
, 0, sizeof(oWrite
));
1149 /* Wait for client to connect */
1150 if (winetest_debug
> 1) trace("Server calling overlapped ConnectNamedPipe...\n");
1151 success
= ConnectNamedPipe(hnp
, &oConnect
);
1152 err
= GetLastError();
1153 ok(!success
&& (err
== ERROR_IO_PENDING
|| err
== ERROR_PIPE_CONNECTED
),
1154 "overlapped ConnectNamedPipe got %u err %lu\n", success
, err
);
1155 if (!success
&& err
== ERROR_IO_PENDING
) {
1156 if (winetest_debug
> 1) trace("ConnectNamedPipe GetQueuedCompletionStatus\n");
1157 success
= GetQueuedCompletionStatus(hcompletion
, &dummy
, &compkey
, &oResult
, 0);
1160 ok( GetLastError() == WAIT_TIMEOUT
,
1161 "ConnectNamedPipe GetQueuedCompletionStatus wrong error %lu\n", GetLastError());
1162 success
= GetQueuedCompletionStatus(hcompletion
, &dummy
, &compkey
, &oResult
, 10000);
1164 ok(success
, "ConnectNamedPipe GetQueuedCompletionStatus failed, errno=%li\n", GetLastError());
1167 ok(compkey
== 12345, "got completion key %i instead of 12345\n", (int)compkey
);
1168 ok(oResult
== &oConnect
, "got overlapped pointer %p instead of %p\n", oResult
, &oConnect
);
1171 if (winetest_debug
> 1) trace("overlapped ConnectNamedPipe operation complete.\n");
1173 /* Echo bytes once */
1174 memset(buf
, 0, sizeof(buf
));
1176 if (winetest_debug
> 1) trace("Server reading...\n");
1177 success
= ReadFile(hnp
, buf
, sizeof(buf
), &readden
, &oRead
);
1178 if (winetest_debug
> 1) trace("Server ReadFile returned...\n");
1179 err
= GetLastError();
1180 ok(success
|| err
== ERROR_IO_PENDING
, "overlapped ReadFile, err=%li\n", err
);
1181 success
= GetQueuedCompletionStatus(hcompletion
, &readden
, &compkey
,
1183 ok(success
, "ReadFile GetQueuedCompletionStatus failed, errno=%li\n", GetLastError());
1186 ok(compkey
== 12345, "got completion key %i instead of 12345\n", (int)compkey
);
1187 ok(oResult
== &oRead
, "got overlapped pointer %p instead of %p\n", oResult
, &oRead
);
1189 if (winetest_debug
> 1) trace("Server done reading.\n");
1191 if (winetest_debug
> 1) trace("Server writing...\n");
1192 success
= WriteFile(hnp
, buf
, readden
, &written
, &oWrite
);
1193 if (winetest_debug
> 1) trace("Server WriteFile returned...\n");
1194 err
= GetLastError();
1195 ok(success
|| err
== ERROR_IO_PENDING
, "overlapped WriteFile failed, err=%lu\n", err
);
1196 success
= GetQueuedCompletionStatus(hcompletion
, &written
, &compkey
,
1198 ok(success
, "WriteFile GetQueuedCompletionStatus failed, errno=%li\n", GetLastError());
1201 ok(compkey
== 12345, "got completion key %i instead of 12345\n", (int)compkey
);
1202 ok(oResult
== &oWrite
, "got overlapped pointer %p instead of %p\n", oResult
, &oWrite
);
1203 ok(written
== readden
, "write file len\n");
1205 if (winetest_debug
> 1) trace("Server done writing.\n");
1207 /* Client will finish this connection, the following ops will trigger broken pipe errors. */
1209 /* Wait for the pipe to break. */
1210 while (PeekNamedPipe(hnp
, NULL
, 0, NULL
, &written
, &written
));
1212 if (winetest_debug
> 1) trace("Server writing on disconnected pipe...\n");
1213 SetLastError(ERROR_SUCCESS
);
1214 success
= WriteFile(hnp
, buf
, readden
, &written
, &oWrite
);
1215 err
= GetLastError();
1216 ok(!success
&& err
== ERROR_NO_DATA
,
1217 "overlapped WriteFile on disconnected pipe returned %u, err=%li\n", success
, err
);
1219 /* No completion status is queued on immediate error. */
1220 SetLastError(ERROR_SUCCESS
);
1221 oResult
= (OVERLAPPED
*)0xdeadbeef;
1222 success
= GetQueuedCompletionStatus(hcompletion
, &written
, &compkey
,
1224 err
= GetLastError();
1225 ok(!success
&& err
== WAIT_TIMEOUT
&& !oResult
,
1226 "WriteFile GetQueuedCompletionStatus returned %u, err=%li, oResult %p\n",
1227 success
, err
, oResult
);
1229 if (winetest_debug
> 1) trace("Server reading from disconnected pipe...\n");
1230 SetLastError(ERROR_SUCCESS
);
1231 success
= ReadFile(hnp
, buf
, sizeof(buf
), &readden
, &oRead
);
1232 if (winetest_debug
> 1) trace("Server ReadFile from disconnected pipe returned...\n");
1233 err
= GetLastError();
1234 ok(!success
&& err
== ERROR_BROKEN_PIPE
,
1235 "overlapped ReadFile on disconnected pipe returned %u, err=%li\n", success
, err
);
1237 SetLastError(ERROR_SUCCESS
);
1238 oResult
= (OVERLAPPED
*)0xdeadbeef;
1239 success
= GetQueuedCompletionStatus(hcompletion
, &readden
, &compkey
,
1241 err
= GetLastError();
1242 ok(!success
&& err
== WAIT_TIMEOUT
&& !oResult
,
1243 "ReadFile GetQueuedCompletionStatus returned %u, err=%li, oResult %p\n",
1244 success
, err
, oResult
);
1246 /* finish this connection, wait for next one */
1247 ok(FlushFileBuffers(hnp
), "FlushFileBuffers\n");
1248 success
= DisconnectNamedPipe(hnp
);
1249 ok(success
, "DisconnectNamedPipe failed, err %lu\n", GetLastError());
1252 ret
= CloseHandle(hnp
);
1253 ok(ret
, "CloseHandle named pipe failed, err=%li\n", GetLastError());
1254 ret
= CloseHandle(hcompletion
);
1255 ok(ret
, "CloseHandle completion failed, err=%li\n", GetLastError());
1260 static int completion_called
;
1261 static DWORD completion_errorcode
;
1262 static DWORD completion_num_bytes
;
1263 static LPOVERLAPPED completion_lpoverlapped
;
1265 static VOID WINAPI
completion_routine(DWORD errorcode
, DWORD num_bytes
, LPOVERLAPPED lpoverlapped
)
1267 completion_called
++;
1268 completion_errorcode
= errorcode
;
1269 completion_num_bytes
= num_bytes
;
1270 completion_lpoverlapped
= lpoverlapped
;
1271 SetEvent(lpoverlapped
->hEvent
);
1274 /** Trivial byte echo server - uses ReadFileEx/WriteFileEx */
1275 static DWORD CALLBACK
serverThreadMain5(LPVOID arg
)
1280 if (winetest_debug
> 1) trace("serverThreadMain5\n");
1281 /* Set up a simple echo server */
1282 hnp
= CreateNamedPipeA(PIPENAME
"serverThreadMain5", PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
1283 PIPE_TYPE_BYTE
| PIPE_WAIT
,
1284 /* nMaxInstances */ 1,
1285 /* nOutBufSize */ 1024,
1286 /* nInBufSize */ 1024,
1287 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1288 /* lpSecurityAttrib */ NULL
);
1289 ok(hnp
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
1291 hEvent
= CreateEventW(NULL
, /* security attribute */
1292 TRUE
, /* manual reset event */
1293 FALSE
, /* initial state */
1295 ok(hEvent
!= NULL
, "CreateEvent\n");
1297 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
1301 OVERLAPPED oOverlap
;
1304 memset(&oOverlap
, 0, sizeof(oOverlap
));
1305 oOverlap
.hEvent
= hEvent
;
1307 /* Wait for client to connect */
1308 if (winetest_debug
> 1) trace("Server calling ConnectNamedPipe...\n");
1309 success
= ConnectNamedPipe(hnp
, NULL
);
1310 err
= GetLastError();
1311 ok(success
|| (err
== ERROR_PIPE_CONNECTED
), "ConnectNamedPipe failed: %ld\n", err
);
1312 if (winetest_debug
> 1) trace("ConnectNamedPipe operation complete.\n");
1314 /* Echo bytes once */
1315 memset(buf
, 0, sizeof(buf
));
1317 if (winetest_debug
> 1) trace("Server reading...\n");
1318 completion_called
= 0;
1320 success
= ReadFileEx(hnp
, buf
, sizeof(buf
), &oOverlap
, completion_routine
);
1321 if (winetest_debug
> 1) trace("Server ReadFileEx returned...\n");
1322 ok(success
, "ReadFileEx failed, err=%li\n", GetLastError());
1323 ok(completion_called
== 0, "completion routine called before ReadFileEx return\n");
1324 if (winetest_debug
> 1) trace("ReadFileEx returned.\n");
1328 ret
= WaitForSingleObjectEx(hEvent
, INFINITE
, TRUE
);
1329 } while (ret
== WAIT_IO_COMPLETION
);
1330 ok(ret
== 0, "wait ReadFileEx returned %lx\n", ret
);
1332 ok(completion_called
== 1, "completion routine called %i times\n", completion_called
);
1333 ok(completion_errorcode
== ERROR_SUCCESS
, "completion routine got error %ld\n", completion_errorcode
);
1334 ok(completion_num_bytes
!= 0, "read 0 bytes\n");
1335 ok(completion_lpoverlapped
== &oOverlap
, "got wrong overlapped pointer %p\n", completion_lpoverlapped
);
1336 readden
= completion_num_bytes
;
1337 if (winetest_debug
> 1) trace("Server done reading.\n");
1339 if (winetest_debug
> 1) trace("Server writing...\n");
1340 completion_called
= 0;
1342 success
= WriteFileEx(hnp
, buf
, readden
, &oOverlap
, completion_routine
);
1343 if (winetest_debug
> 1) trace("Server WriteFileEx returned...\n");
1344 ok(success
, "WriteFileEx failed, err=%li\n", GetLastError());
1345 ok(completion_called
== 0, "completion routine called before ReadFileEx return\n");
1346 if (winetest_debug
> 1) trace("overlapped WriteFile returned.\n");
1350 ret
= WaitForSingleObjectEx(hEvent
, INFINITE
, TRUE
);
1351 } while (ret
== WAIT_IO_COMPLETION
);
1352 ok(ret
== 0, "wait WriteFileEx returned %lx\n", ret
);
1354 if (winetest_debug
> 1) trace("Server done writing.\n");
1355 ok(completion_called
== 1, "completion routine called %i times\n", completion_called
);
1356 ok(completion_errorcode
== ERROR_SUCCESS
, "completion routine got error %ld\n", completion_errorcode
);
1357 ok(completion_num_bytes
== readden
, "read %li bytes wrote %li\n", readden
, completion_num_bytes
);
1358 ok(completion_lpoverlapped
== &oOverlap
, "got wrong overlapped pointer %p\n", completion_lpoverlapped
);
1360 /* finish this connection, wait for next one */
1361 ok(FlushFileBuffers(hnp
), "FlushFileBuffers\n");
1362 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe\n");
1367 static void exerciseServer(const char *pipename
, HANDLE serverThread
)
1371 if (winetest_debug
> 1) trace("exerciseServer starting\n");
1372 for (i
= 0; i
< NB_SERVER_LOOPS
; i
++) {
1373 HANDLE hFile
=INVALID_HANDLE_VALUE
;
1374 static const char obuf
[] = "Bit Bucket";
1380 for (loop
= 0; loop
< 3; loop
++) {
1382 if (winetest_debug
> 1) trace("Client connecting...\n");
1383 /* Connect to the server */
1384 hFile
= CreateFileA(pipename
, GENERIC_READ
| GENERIC_WRITE
, 0,
1385 NULL
, OPEN_EXISTING
, 0, 0);
1386 if (hFile
!= INVALID_HANDLE_VALUE
)
1388 err
= GetLastError();
1390 ok(err
== ERROR_PIPE_BUSY
|| err
== ERROR_FILE_NOT_FOUND
, "connecting to pipe\n");
1392 ok(err
== ERROR_PIPE_BUSY
, "connecting to pipe\n");
1393 if (winetest_debug
> 1) trace("connect failed, retrying\n");
1396 ok(hFile
!= INVALID_HANDLE_VALUE
, "client opening named pipe\n");
1398 /* Make sure it can echo */
1399 memset(ibuf
, 0, sizeof(ibuf
));
1400 if (winetest_debug
> 1) trace("Client writing...\n");
1401 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile to client end of pipe\n");
1402 ok(written
== sizeof(obuf
), "write file len\n");
1403 if (winetest_debug
> 1) trace("Client reading...\n");
1404 ok(ReadFile(hFile
, ibuf
, sizeof(obuf
), &readden
, NULL
), "ReadFile from client end of pipe\n");
1405 ok(readden
== sizeof(obuf
), "read file len\n");
1406 ok(memcmp(obuf
, ibuf
, written
) == 0, "content check\n");
1408 if (winetest_debug
> 1) trace("Client closing...\n");
1409 ok(CloseHandle(hFile
), "CloseHandle\n");
1412 ok(WaitForSingleObject(serverThread
,INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject\n");
1414 if (winetest_debug
> 1) trace("exerciseServer returning\n");
1417 static void test_NamedPipe_2(void)
1419 HANDLE serverThread
;
1420 DWORD serverThreadId
;
1422 DWORD alarmThreadId
;
1424 trace("test_NamedPipe_2 starting\n");
1425 /* Set up a twenty second timeout */
1426 alarm_event
= CreateEventW( NULL
, TRUE
, FALSE
, NULL
);
1427 SetLastError(0xdeadbeef);
1428 alarmThread
= CreateThread(NULL
, 0, alarmThreadMain
, (void *) 20000, 0, &alarmThreadId
);
1429 ok(alarmThread
!= NULL
, "CreateThread failed: %ld\n", GetLastError());
1431 /* The servers we're about to exercise do try to clean up carefully,
1432 * but to reduce the chance of a test failure due to a pipe handle
1433 * leak in the test code, we'll use a different pipe name for each server.
1437 SetLastError(0xdeadbeef);
1438 serverThread
= CreateThread(NULL
, 0, serverThreadMain1
, (void *)8, 0, &serverThreadId
);
1439 ok(serverThread
!= NULL
, "CreateThread failed: %ld\n", GetLastError());
1440 exerciseServer(PIPENAME
"serverThreadMain1", serverThread
);
1443 SetLastError(0xdeadbeef);
1444 serverThread
= CreateThread(NULL
, 0, serverThreadMain2
, 0, 0, &serverThreadId
);
1445 ok(serverThread
!= NULL
, "CreateThread failed: %ld\n", GetLastError());
1446 exerciseServer(PIPENAME
"serverThreadMain2", serverThread
);
1449 SetLastError(0xdeadbeef);
1450 serverThread
= CreateThread(NULL
, 0, serverThreadMain3
, 0, 0, &serverThreadId
);
1451 ok(serverThread
!= NULL
, "CreateThread failed: %ld\n", GetLastError());
1452 exerciseServer(PIPENAME
"serverThreadMain3", serverThread
);
1455 SetLastError(0xdeadbeef);
1456 serverThread
= CreateThread(NULL
, 0, serverThreadMain4
, 0, 0, &serverThreadId
);
1457 ok(serverThread
!= NULL
, "CreateThread failed: %ld\n", GetLastError());
1458 exerciseServer(PIPENAME
"serverThreadMain4", serverThread
);
1461 SetLastError(0xdeadbeef);
1462 serverThread
= CreateThread(NULL
, 0, serverThreadMain5
, 0, 0, &serverThreadId
);
1463 ok(serverThread
!= NULL
, "CreateThread failed: %ld\n", GetLastError());
1464 exerciseServer(PIPENAME
"serverThreadMain5", serverThread
);
1466 ok(SetEvent( alarm_event
), "SetEvent\n");
1467 CloseHandle( alarm_event
);
1468 if (winetest_debug
> 1) trace("test_NamedPipe_2 returning\n");
1471 static int test_DisconnectNamedPipe(void)
1475 static const char obuf
[] = "Bit Bucket";
1481 SetLastError(0xdeadbeef);
1482 hnp
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_WAIT
,
1483 /* nMaxInstances */ 1,
1484 /* nOutBufSize */ 1024,
1485 /* nInBufSize */ 1024,
1486 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
1487 /* lpSecurityAttrib */ NULL
);
1488 if ((hnp
== INVALID_HANDLE_VALUE
/* Win98 */ || !hnp
/* Win95 */)
1489 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
) {
1491 win_skip("Named pipes are not implemented\n");
1495 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
) == 0
1496 && GetLastError() == ERROR_PIPE_LISTENING
, "WriteFile to not-yet-connected pipe\n");
1497 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
) == 0
1498 && GetLastError() == ERROR_PIPE_LISTENING
, "ReadFile from not-yet-connected pipe\n");
1500 hFile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1501 ok(hFile
!= INVALID_HANDLE_VALUE
, "CreateFile failed\n");
1503 /* don't try to do i/o if one side couldn't be opened, as it hangs */
1504 if (hFile
!= INVALID_HANDLE_VALUE
) {
1506 /* see what happens if server calls DisconnectNamedPipe
1507 * when there are bytes in the pipe
1510 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
), "WriteFile\n");
1511 ok(written
== sizeof(obuf
), "write file len\n");
1512 ok(DisconnectNamedPipe(hnp
), "DisconnectNamedPipe while messages waiting\n");
1513 ok(WriteFile(hFile
, obuf
, sizeof(obuf
), &written
, NULL
) == 0
1514 && GetLastError() == ERROR_PIPE_NOT_CONNECTED
, "WriteFile to disconnected pipe\n");
1515 ok(WriteFile(hnp
, obuf
, sizeof(obuf
), &written
, NULL
) == 0
1516 && GetLastError() == ERROR_PIPE_NOT_CONNECTED
, "WriteFile to disconnected pipe\n");
1517 ok(ReadFile(hFile
, ibuf
, sizeof(ibuf
), &readden
, NULL
) == 0
1518 && GetLastError() == ERROR_PIPE_NOT_CONNECTED
,
1519 "ReadFile from disconnected pipe with bytes waiting\n");
1520 ok(ReadFile(hnp
, ibuf
, sizeof(ibuf
), &readden
, NULL
) == 0
1521 && GetLastError() == ERROR_PIPE_NOT_CONNECTED
,
1522 "ReadFile from disconnected pipe with bytes waiting\n");
1524 ok(!DisconnectNamedPipe(hnp
) && GetLastError() == ERROR_PIPE_NOT_CONNECTED
,
1525 "DisconnectNamedPipe worked twice\n");
1526 ret
= WaitForSingleObject(hFile
, 0);
1527 ok(ret
== WAIT_TIMEOUT
, "WaitForSingleObject returned %lX\n", ret
);
1529 ret
= PeekNamedPipe(hFile
, NULL
, 0, NULL
, &readden
, NULL
);
1530 ok(!ret
&& GetLastError() == ERROR_PIPE_NOT_CONNECTED
, "PeekNamedPipe returned %lx (%lu)\n",
1531 ret
, GetLastError());
1532 ret
= PeekNamedPipe(hnp
, NULL
, 0, NULL
, &readden
, NULL
);
1533 ok(!ret
&& GetLastError() == ERROR_BAD_PIPE
, "PeekNamedPipe returned %lx (%lu)\n",
1534 ret
, GetLastError());
1535 ok(CloseHandle(hFile
), "CloseHandle\n");
1538 ok(CloseHandle(hnp
), "CloseHandle\n");
1542 static void test_CreatePipe(void)
1544 SECURITY_ATTRIBUTES pipe_attr
;
1545 HANDLE piperead
, pipewrite
;
1552 user_apc_ran
= FALSE
;
1553 ok(QueueUserAPC(user_apc
, GetCurrentThread(), 0), "couldn't create user apc\n");
1555 pipe_attr
.nLength
= sizeof(SECURITY_ATTRIBUTES
);
1556 pipe_attr
.bInheritHandle
= TRUE
;
1557 pipe_attr
.lpSecurityDescriptor
= NULL
;
1558 ok(CreatePipe(&piperead
, &pipewrite
, &pipe_attr
, 0) != 0, "CreatePipe failed\n");
1559 test_pipe_info(piperead
, FILE_PIPE_SERVER_END
, 4096, 4096, 1);
1560 test_pipe_info(pipewrite
, 0, 4096, 4096, 1);
1561 test_file_access(piperead
, SYNCHRONIZE
| READ_CONTROL
| FILE_WRITE_ATTRIBUTES
1562 | FILE_READ_ATTRIBUTES
| FILE_READ_PROPERTIES
| FILE_READ_DATA
);
1563 test_file_access(pipewrite
, SYNCHRONIZE
| READ_CONTROL
| FILE_WRITE_ATTRIBUTES
1564 | FILE_READ_ATTRIBUTES
| FILE_WRITE_PROPERTIES
| FILE_APPEND_DATA
1567 ok(WriteFile(pipewrite
,PIPENAME
,sizeof(PIPENAME
), &written
, NULL
), "Write to anonymous pipe failed\n");
1568 ok(written
== sizeof(PIPENAME
), "Write to anonymous pipe wrote %ld bytes\n", written
);
1569 ok(ReadFile(piperead
,readbuf
,sizeof(readbuf
),&read
, NULL
), "Read from non empty pipe failed\n");
1570 ok(read
== sizeof(PIPENAME
), "Read from anonymous pipe got %ld bytes\n", read
);
1571 ok(CloseHandle(pipewrite
), "CloseHandle for the write pipe failed\n");
1572 ok(CloseHandle(piperead
), "CloseHandle for the read pipe failed\n");
1574 /* Now write another chunk*/
1575 ok(CreatePipe(&piperead
, &pipewrite
, &pipe_attr
, 0) != 0, "CreatePipe failed\n");
1576 ok(WriteFile(pipewrite
,PIPENAME
,sizeof(PIPENAME
), &written
, NULL
), "Write to anonymous pipe failed\n");
1577 ok(written
== sizeof(PIPENAME
), "Write to anonymous pipe wrote %ld bytes\n", written
);
1578 /* and close the write end, read should still succeed*/
1579 ok(CloseHandle(pipewrite
), "CloseHandle for the Write Pipe failed\n");
1580 ok(ReadFile(piperead
,readbuf
,sizeof(readbuf
),&read
, NULL
), "Read from broken pipe with pending data failed\n");
1581 ok(read
== sizeof(PIPENAME
), "Read from anonymous pipe got %ld bytes\n", read
);
1582 /* But now we need to get informed that the pipe is closed */
1583 ok(ReadFile(piperead
,readbuf
,sizeof(readbuf
),&read
, NULL
) == 0, "Broken pipe not detected\n");
1584 ok(CloseHandle(piperead
), "CloseHandle for the read pipe failed\n");
1586 /* Try bigger chunks */
1588 buffer
= HeapAlloc( GetProcessHeap(), 0, size
);
1589 for (i
= 0; i
< size
; i
++) buffer
[i
] = i
;
1590 ok(CreatePipe(&piperead
, &pipewrite
, &pipe_attr
, (size
+ 24)) != 0, "CreatePipe failed\n");
1591 ok(WriteFile(pipewrite
, buffer
, size
, &written
, NULL
), "Write to anonymous pipe failed\n");
1592 ok(written
== size
, "Write to anonymous pipe wrote %ld bytes\n", written
);
1593 /* and close the write end, read should still succeed*/
1594 ok(CloseHandle(pipewrite
), "CloseHandle for the Write Pipe failed\n");
1595 memset( buffer
, 0, size
);
1596 ok(ReadFile(piperead
, buffer
, size
, &read
, NULL
), "Read from broken pipe with pending data failed\n");
1597 ok(read
== size
, "Read from anonymous pipe got %ld bytes\n", read
);
1598 for (i
= 0; i
< size
; i
++) ok( buffer
[i
] == (BYTE
)i
, "invalid data %x at %lx\n", buffer
[i
], i
);
1599 /* But now we need to get informed that the pipe is closed */
1600 ok(ReadFile(piperead
,readbuf
,sizeof(readbuf
),&read
, NULL
) == 0, "Broken pipe not detected\n");
1601 ok(CloseHandle(piperead
), "CloseHandle for the read pipe failed\n");
1602 HeapFree(GetProcessHeap(), 0, buffer
);
1604 ok(user_apc_ran
== FALSE
, "user apc ran, pipe using alertable io mode\n");
1605 SleepEx(0, TRUE
); /* get rid of apc */
1607 ok(CreatePipe(&piperead
, &pipewrite
, &pipe_attr
, 1) != 0, "CreatePipe failed\n");
1608 test_pipe_info(piperead
, FILE_PIPE_SERVER_END
, 1, 1, 1);
1609 test_pipe_info(pipewrite
, 0, 1, 1, 1);
1610 ok(CloseHandle(pipewrite
), "CloseHandle for the Write Pipe failed\n");
1611 ok(CloseHandle(piperead
), "CloseHandle for the read pipe failed\n");
1614 static void test_CloseHandle(void)
1616 static const char testdata
[] = "Hello World";
1617 DWORD state
, numbytes
;
1618 HANDLE hpipe
, hfile
;
1622 hpipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
1623 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1624 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1625 ok(hpipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %lu\n", GetLastError());
1627 hfile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1628 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %lu\n", GetLastError());
1630 numbytes
= 0xdeadbeef;
1631 ret
= WriteFile(hpipe
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1632 ok(ret
, "WriteFile failed with %lu\n", GetLastError());
1633 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %lu\n", numbytes
);
1635 numbytes
= 0xdeadbeef;
1636 ret
= PeekNamedPipe(hfile
, NULL
, 0, NULL
, &numbytes
, NULL
);
1637 ok(ret
, "PeekNamedPipe failed with %lu\n", GetLastError());
1638 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %lu\n", numbytes
);
1640 ret
= CloseHandle(hpipe
);
1641 ok(ret
, "CloseHandle failed with %lu\n", GetLastError());
1643 numbytes
= 0xdeadbeef;
1644 memset(buffer
, 0, sizeof(buffer
));
1645 ret
= ReadFile(hfile
, buffer
, 0, &numbytes
, NULL
);
1646 ok(ret
, "ReadFile failed with %lu\n", GetLastError());
1647 ok(numbytes
== 0, "expected 0, got %lu\n", numbytes
);
1649 numbytes
= 0xdeadbeef;
1650 ret
= PeekNamedPipe(hfile
, NULL
, 0, NULL
, &numbytes
, NULL
);
1651 ok(ret
, "PeekNamedPipe failed with %lu\n", GetLastError());
1652 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %lu\n", numbytes
);
1654 numbytes
= 0xdeadbeef;
1655 memset(buffer
, 0, sizeof(buffer
));
1656 ret
= ReadFile(hfile
, buffer
, sizeof(buffer
), &numbytes
, NULL
);
1657 ok(ret
, "ReadFile failed with %lu\n", GetLastError());
1658 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %lu\n", numbytes
);
1660 ret
= GetNamedPipeHandleStateA(hfile
, &state
, NULL
, NULL
, NULL
, NULL
, 0);
1661 ok(ret
, "GetNamedPipeHandleState failed with %lu\n", GetLastError());
1662 state
= PIPE_READMODE_MESSAGE
| PIPE_WAIT
;
1663 ret
= SetNamedPipeHandleState(hfile
, &state
, NULL
, NULL
);
1664 ok(ret
, "SetNamedPipeHandleState failed with %lu\n", GetLastError());
1666 SetLastError(0xdeadbeef);
1667 ret
= ReadFile(hfile
, buffer
, 0, &numbytes
, NULL
);
1668 ok(!ret
, "ReadFile unexpectedly succeeded\n");
1669 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %lu\n", GetLastError());
1671 numbytes
= 0xdeadbeef;
1672 ret
= PeekNamedPipe(hfile
, NULL
, 0, NULL
, &numbytes
, NULL
);
1673 ok(!ret
&& GetLastError() == ERROR_BROKEN_PIPE
, "PeekNamedPipe returned %x (%lu)\n",
1674 ret
, GetLastError());
1675 ok(numbytes
== 0xdeadbeef, "numbytes = %lu\n", numbytes
);
1677 SetLastError(0xdeadbeef);
1678 ret
= WriteFile(hfile
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1679 ok(!ret
, "WriteFile unexpectedly succeeded\n");
1680 ok(GetLastError() == ERROR_NO_DATA
, "expected ERROR_NO_DATA, got %lu\n", GetLastError());
1684 hpipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
1685 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1686 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1687 ok(hpipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %lu\n", GetLastError());
1689 hfile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1690 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %lu\n", GetLastError());
1692 numbytes
= 0xdeadbeef;
1693 ret
= WriteFile(hpipe
, testdata
, 0, &numbytes
, NULL
);
1694 ok(ret
, "WriteFile failed with %lu\n", GetLastError());
1695 ok(numbytes
== 0, "expected 0, got %lu\n", numbytes
);
1697 ret
= CloseHandle(hpipe
);
1698 ok(ret
, "CloseHandle failed with %lu\n", GetLastError());
1700 numbytes
= 0xdeadbeef;
1701 memset(buffer
, 0, sizeof(buffer
));
1702 ret
= ReadFile(hfile
, buffer
, sizeof(buffer
), &numbytes
, NULL
);
1703 ok(ret
, "ReadFile failed with %lu\n", GetLastError());
1704 ok(numbytes
== 0, "expected 0, got %lu\n", numbytes
);
1706 SetLastError(0xdeadbeef);
1707 ret
= ReadFile(hfile
, buffer
, 0, &numbytes
, NULL
);
1708 ok(!ret
, "ReadFile unexpectedly succeeded\n");
1709 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %lu\n", GetLastError());
1711 ret
= GetNamedPipeHandleStateA(hfile
, &state
, NULL
, NULL
, NULL
, NULL
, 0);
1712 ok(ret
, "GetNamedPipeHandleState failed with %lu\n", GetLastError());
1713 state
= PIPE_READMODE_MESSAGE
| PIPE_WAIT
;
1714 ret
= SetNamedPipeHandleState(hfile
, &state
, NULL
, NULL
);
1715 ok(ret
, "SetNamedPipeHandleState failed with %lu\n", GetLastError());
1717 SetLastError(0xdeadbeef);
1718 ret
= ReadFile(hfile
, buffer
, 0, &numbytes
, NULL
);
1719 ok(!ret
, "ReadFile unexpectedly succeeded\n");
1720 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %lu\n", GetLastError());
1722 SetLastError(0xdeadbeef);
1723 ret
= WriteFile(hfile
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1724 ok(!ret
, "WriteFile unexpectedly succeeded\n");
1725 ok(GetLastError() == ERROR_NO_DATA
, "expected ERROR_NO_DATA, got %lu\n", GetLastError());
1729 /* repeat test with hpipe <-> hfile swapped */
1731 hpipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
1732 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1733 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1734 ok(hpipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %lu\n", GetLastError());
1736 hfile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1737 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %lu\n", GetLastError());
1739 numbytes
= 0xdeadbeef;
1740 ret
= WriteFile(hfile
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1741 ok(ret
, "WriteFile failed with %lu\n", GetLastError());
1742 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %lu\n", numbytes
);
1744 numbytes
= 0xdeadbeef;
1745 ret
= PeekNamedPipe(hpipe
, NULL
, 0, NULL
, &numbytes
, NULL
);
1746 ok(ret
, "PeekNamedPipe failed with %lu\n", GetLastError());
1747 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %lu\n", numbytes
);
1749 ret
= CloseHandle(hfile
);
1750 ok(ret
, "CloseHandle failed with %lu\n", GetLastError());
1752 numbytes
= 0xdeadbeef;
1753 memset(buffer
, 0, sizeof(buffer
));
1754 ret
= ReadFile(hpipe
, buffer
, 0, &numbytes
, NULL
);
1755 ok(ret
|| GetLastError() == ERROR_MORE_DATA
/* >= Win 8 */,
1756 "ReadFile failed with %lu\n", GetLastError());
1757 ok(numbytes
== 0, "expected 0, got %lu\n", numbytes
);
1759 numbytes
= 0xdeadbeef;
1760 ret
= PeekNamedPipe(hpipe
, NULL
, 0, NULL
, &numbytes
, NULL
);
1761 ok(ret
, "PeekNamedPipe failed with %lu\n", GetLastError());
1762 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %lu\n", numbytes
);
1764 numbytes
= 0xdeadbeef;
1765 memset(buffer
, 0, sizeof(buffer
));
1766 ret
= ReadFile(hpipe
, buffer
, sizeof(buffer
), &numbytes
, NULL
);
1767 ok(ret
, "ReadFile failed with %lu\n", GetLastError());
1768 ok(numbytes
== sizeof(testdata
), "expected sizeof(testdata), got %lu\n", numbytes
);
1770 ret
= GetNamedPipeHandleStateA(hpipe
, &state
, NULL
, NULL
, NULL
, NULL
, 0);
1771 ok(ret
, "GetNamedPipeHandleState failed with %lu\n", GetLastError());
1772 state
= PIPE_READMODE_MESSAGE
| PIPE_WAIT
;
1773 ret
= SetNamedPipeHandleState(hpipe
, &state
, NULL
, NULL
);
1774 ok(ret
, "SetNamedPipeHandleState failed with %lu\n", GetLastError());
1776 SetLastError(0xdeadbeef);
1777 ret
= ReadFile(hpipe
, buffer
, 0, &numbytes
, NULL
);
1778 ok(!ret
, "ReadFile unexpectedly succeeded\n");
1779 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %lu\n", GetLastError());
1781 numbytes
= 0xdeadbeef;
1782 ret
= PeekNamedPipe(hpipe
, NULL
, 0, NULL
, &numbytes
, NULL
);
1783 ok(!ret
&& GetLastError() == ERROR_BROKEN_PIPE
, "PeekNamedPipe returned %x (%lu)\n",
1784 ret
, GetLastError());
1785 ok(numbytes
== 0xdeadbeef, "numbytes = %lu\n", numbytes
);
1787 SetLastError(0xdeadbeef);
1788 ret
= WriteFile(hpipe
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1789 ok(!ret
, "WriteFile unexpectedly succeeded\n");
1790 ok(GetLastError() == ERROR_NO_DATA
, "expected ERROR_NO_DATA, got %lu\n", GetLastError());
1794 hpipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
1795 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
1796 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1797 ok(hpipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %lu\n", GetLastError());
1799 hfile
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1800 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %lu\n", GetLastError());
1802 numbytes
= 0xdeadbeef;
1803 ret
= WriteFile(hfile
, testdata
, 0, &numbytes
, NULL
);
1804 ok(ret
, "WriteFile failed with %lu\n", GetLastError());
1805 ok(numbytes
== 0, "expected 0, got %lu\n", numbytes
);
1807 ret
= CloseHandle(hfile
);
1808 ok(ret
, "CloseHandle failed with %lu\n", GetLastError());
1810 numbytes
= 0xdeadbeef;
1811 memset(buffer
, 0, sizeof(buffer
));
1812 ret
= ReadFile(hpipe
, buffer
, sizeof(buffer
), &numbytes
, NULL
);
1813 ok(ret
, "ReadFile failed with %lu\n", GetLastError());
1814 ok(numbytes
== 0, "expected 0, got %lu\n", numbytes
);
1816 SetLastError(0xdeadbeef);
1817 ret
= ReadFile(hpipe
, buffer
, 0, &numbytes
, NULL
);
1818 ok(!ret
, "ReadFile unexpectedly succeeded\n");
1819 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %lu\n", GetLastError());
1821 ret
= GetNamedPipeHandleStateA(hpipe
, &state
, NULL
, NULL
, NULL
, NULL
, 0);
1822 ok(ret
, "GetNamedPipeHandleState failed with %lu\n", GetLastError());
1823 state
= PIPE_READMODE_MESSAGE
| PIPE_WAIT
;
1824 ret
= SetNamedPipeHandleState(hpipe
, &state
, NULL
, NULL
);
1825 ok(ret
, "SetNamedPipeHandleState failed with %lu\n", GetLastError());
1827 SetLastError(0xdeadbeef);
1828 ret
= ReadFile(hpipe
, buffer
, 0, &numbytes
, NULL
);
1829 ok(!ret
, "ReadFile unexpectedly succeeded\n");
1830 ok(GetLastError() == ERROR_BROKEN_PIPE
, "expected ERROR_BROKEN_PIPE, got %lu\n", GetLastError());
1832 SetLastError(0xdeadbeef);
1833 ret
= WriteFile(hpipe
, testdata
, sizeof(testdata
), &numbytes
, NULL
);
1834 ok(!ret
, "WriteFile unexpectedly succeeded\n");
1835 ok(GetLastError() == ERROR_NO_DATA
, "expected ERROR_NO_DATA, got %lu\n", GetLastError());
1840 struct named_pipe_client_params
1842 DWORD security_flags
;
1847 #define PIPE_NAME "\\\\.\\pipe\\named_pipe_test"
1849 static DWORD CALLBACK
named_pipe_client_func(LPVOID p
)
1851 struct named_pipe_client_params
*params
= p
;
1854 const char message
[] = "Test";
1855 DWORD bytes_read
, bytes_written
;
1857 TOKEN_PRIVILEGES
*Privileges
= NULL
;
1863 /* modify the token so we can tell if the pipe impersonation
1864 * token reverts to the process token */
1865 ret
= AdjustTokenPrivileges(params
->token
, TRUE
, NULL
, 0, NULL
, NULL
);
1866 ok(ret
, "AdjustTokenPrivileges failed with error %ld\n", GetLastError());
1868 ret
= SetThreadToken(NULL
, params
->token
);
1869 ok(ret
, "SetThreadToken failed with error %ld\n", GetLastError());
1874 HANDLE process_token
;
1876 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
|TOKEN_ADJUST_PRIVILEGES
, &process_token
);
1877 ok(ret
, "OpenProcessToken failed with error %ld\n", GetLastError());
1879 ret
= GetTokenInformation(process_token
, TokenPrivileges
, NULL
, 0, &Size
);
1880 ok(!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "GetTokenInformation(TokenPrivileges) failed with %ld\n", GetLastError());
1881 Privileges
= HeapAlloc(GetProcessHeap(), 0, Size
);
1882 ret
= GetTokenInformation(process_token
, TokenPrivileges
, Privileges
, Size
, &Size
);
1883 ok(ret
, "GetTokenInformation(TokenPrivileges) failed with %ld\n", GetLastError());
1885 ret
= AdjustTokenPrivileges(process_token
, TRUE
, NULL
, 0, NULL
, NULL
);
1886 ok(ret
, "AdjustTokenPrivileges failed with error %ld\n", GetLastError());
1888 CloseHandle(process_token
);
1891 pipe
= CreateFileA(PIPE_NAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, params
->security_flags
, NULL
);
1892 ok(pipe
!= INVALID_HANDLE_VALUE
, "CreateFile for pipe failed with error %ld\n", GetLastError());
1894 ret
= WriteFile(pipe
, message
, sizeof(message
), &bytes_written
, NULL
);
1895 ok(ret
, "WriteFile failed with error %ld\n", GetLastError());
1897 ret
= ReadFile(pipe
, &dummy
, sizeof(dummy
), &bytes_read
, NULL
);
1898 ok(ret
, "ReadFile failed with error %ld\n", GetLastError());
1904 ret
= RevertToSelf();
1905 ok(ret
, "RevertToSelf failed with error %ld\n", GetLastError());
1909 ret
= AdjustTokenPrivileges(params
->token
, TRUE
, NULL
, 0, NULL
, NULL
);
1910 ok(ret
, "AdjustTokenPrivileges failed with error %ld\n", GetLastError());
1915 HANDLE process_token
;
1917 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES
, &process_token
);
1918 ok(ret
, "OpenProcessToken failed with error %ld\n", GetLastError());
1920 ret
= AdjustTokenPrivileges(process_token
, FALSE
, Privileges
, 0, NULL
, NULL
);
1921 ok(ret
, "AdjustTokenPrivileges failed with error %ld\n", GetLastError());
1923 HeapFree(GetProcessHeap(), 0, Privileges
);
1925 CloseHandle(process_token
);
1928 ret
= WriteFile(pipe
, message
, sizeof(message
), &bytes_written
, NULL
);
1929 ok(ret
, "WriteFile failed with error %ld\n", GetLastError());
1931 ret
= ReadFile(pipe
, &dummy
, sizeof(dummy
), &bytes_read
, NULL
);
1932 ok(ret
, "ReadFile failed with error %ld\n", GetLastError());
1939 static HANDLE
make_impersonation_token(DWORD Access
, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
1941 HANDLE ProcessToken
;
1942 HANDLE Token
= NULL
;
1945 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE
, &ProcessToken
);
1946 ok(ret
, "OpenProcessToken failed with error %ld\n", GetLastError());
1948 ret
= pDuplicateTokenEx(ProcessToken
, Access
, NULL
, ImpersonationLevel
, TokenImpersonation
, &Token
);
1949 ok(ret
, "DuplicateToken failed with error %ld\n", GetLastError());
1951 CloseHandle(ProcessToken
);
1956 static void test_ImpersonateNamedPipeClient(HANDLE hClientToken
, DWORD security_flags
, BOOL revert
, void (*test_func
)(int, HANDLE
))
1965 struct named_pipe_client_params params
;
1967 DWORD dwBytesWritten
;
1968 HANDLE hToken
= NULL
;
1969 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
;
1972 hPipeServer
= CreateNamedPipeA(PIPE_NAME
, PIPE_ACCESS_DUPLEX
, PIPE_TYPE_BYTE
| PIPE_READMODE_BYTE
| PIPE_WAIT
, 1, 100, 100, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
1973 ok(hPipeServer
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with error %ld\n", GetLastError());
1975 params
.security_flags
= security_flags
;
1976 params
.token
= hClientToken
;
1977 params
.revert
= revert
;
1978 hThread
= CreateThread(NULL
, 0, named_pipe_client_func
, ¶ms
, 0, &dwTid
);
1979 ok(hThread
!= NULL
, "CreateThread failed with error %ld\n", GetLastError());
1981 SetLastError(0xdeadbeef);
1982 ret
= ImpersonateNamedPipeClient(hPipeServer
);
1983 error
= GetLastError();
1984 ok(ret
/* win2k3 */ || (error
== ERROR_CANNOT_IMPERSONATE
),
1985 "ImpersonateNamedPipeClient should have failed with ERROR_CANNOT_IMPERSONATE instead of %ld\n", GetLastError());
1987 ret
= ConnectNamedPipe(hPipeServer
, NULL
);
1988 ok(ret
|| (GetLastError() == ERROR_PIPE_CONNECTED
), "ConnectNamedPipe failed with error %ld\n", GetLastError());
1990 ret
= ReadFile(hPipeServer
, buffer
, sizeof(buffer
), &dwBytesRead
, NULL
);
1991 ok(ret
, "ReadFile failed with error %ld\n", GetLastError());
1993 ret
= ImpersonateNamedPipeClient(hPipeServer
);
1994 ok(ret
, "ImpersonateNamedPipeClient failed with error %ld\n", GetLastError());
1996 ret
= OpenThreadToken(GetCurrentThread(), TOKEN_QUERY
, FALSE
, &hToken
);
1997 ok(ret
, "OpenThreadToken failed with error %ld\n", GetLastError());
1999 (*test_func
)(0, hToken
);
2001 ImpersonationLevel
= 0xdeadbeef; /* to avoid false positives */
2002 ret
= GetTokenInformation(hToken
, TokenImpersonationLevel
, &ImpersonationLevel
, sizeof(ImpersonationLevel
), &size
);
2003 ok(ret
, "GetTokenInformation(TokenImpersonationLevel) failed with error %ld\n", GetLastError());
2004 ok(ImpersonationLevel
== SecurityImpersonation
, "ImpersonationLevel should have been SecurityImpersonation(%d) instead of %d\n", SecurityImpersonation
, ImpersonationLevel
);
2006 CloseHandle(hToken
);
2010 ret
= WriteFile(hPipeServer
, &dummy
, sizeof(dummy
), &dwBytesWritten
, NULL
);
2011 ok(ret
, "WriteFile failed with error %ld\n", GetLastError());
2013 ret
= ReadFile(hPipeServer
, buffer
, sizeof(buffer
), &dwBytesRead
, NULL
);
2014 ok(ret
, "ReadFile failed with error %ld\n", GetLastError());
2016 ret
= ImpersonateNamedPipeClient(hPipeServer
);
2017 ok(ret
, "ImpersonateNamedPipeClient failed with error %ld\n", GetLastError());
2019 ret
= OpenThreadToken(GetCurrentThread(), TOKEN_QUERY
, FALSE
, &hToken
);
2020 ok(ret
, "OpenThreadToken failed with error %ld\n", GetLastError());
2022 (*test_func
)(1, hToken
);
2024 CloseHandle(hToken
);
2028 ret
= WriteFile(hPipeServer
, &dummy
, sizeof(dummy
), &dwBytesWritten
, NULL
);
2029 ok(ret
, "WriteFile failed with error %ld\n", GetLastError());
2031 WaitForSingleObject(hThread
, INFINITE
);
2033 ret
= ImpersonateNamedPipeClient(hPipeServer
);
2034 ok(ret
, "ImpersonateNamedPipeClient failed with error %ld\n", GetLastError());
2038 CloseHandle(hThread
);
2039 CloseHandle(hPipeServer
);
2042 static BOOL
are_all_privileges_disabled(HANDLE hToken
)
2045 TOKEN_PRIVILEGES
*Privileges
= NULL
;
2047 BOOL all_privs_disabled
= TRUE
;
2050 ret
= GetTokenInformation(hToken
, TokenPrivileges
, NULL
, 0, &Size
);
2051 if (!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
2053 Privileges
= HeapAlloc(GetProcessHeap(), 0, Size
);
2054 ret
= GetTokenInformation(hToken
, TokenPrivileges
, Privileges
, Size
, &Size
);
2057 HeapFree(GetProcessHeap(), 0, Privileges
);
2064 for (i
= 0; i
< Privileges
->PrivilegeCount
; i
++)
2066 if (Privileges
->Privileges
[i
].Attributes
& SE_PRIVILEGE_ENABLED
)
2068 all_privs_disabled
= FALSE
;
2073 HeapFree(GetProcessHeap(), 0, Privileges
);
2075 return all_privs_disabled
;
2078 static DWORD
get_privilege_count(HANDLE hToken
)
2080 TOKEN_STATISTICS Statistics
;
2081 DWORD Size
= sizeof(Statistics
);
2084 ret
= GetTokenInformation(hToken
, TokenStatistics
, &Statistics
, Size
, &Size
);
2085 ok(ret
, "GetTokenInformation(TokenStatistics)\n");
2086 if (!ret
) return -1;
2088 return Statistics
.PrivilegeCount
;
2091 static void test_no_sqos_no_token(int call_index
, HANDLE hToken
)
2098 priv_count
= get_privilege_count(hToken
);
2100 ok(priv_count
== 0, "privilege count should have been 0 instead of %ld\n", priv_count
);
2103 priv_count
= get_privilege_count(hToken
);
2104 ok(priv_count
> 0, "privilege count should now be > 0 instead of 0\n");
2105 ok(!are_all_privileges_disabled(hToken
), "impersonated token should not have been modified\n");
2108 ok(0, "shouldn't happen\n");
2112 static void test_no_sqos(int call_index
, HANDLE hToken
)
2117 ok(!are_all_privileges_disabled(hToken
), "token should be a copy of the process one\n");
2121 ok(are_all_privileges_disabled(hToken
), "impersonated token should have been modified\n");
2124 ok(0, "shouldn't happen\n");
2128 static void test_static_context(int call_index
, HANDLE hToken
)
2133 ok(!are_all_privileges_disabled(hToken
), "token should be a copy of the process one\n");
2136 ok(!are_all_privileges_disabled(hToken
), "impersonated token should not have been modified\n");
2139 ok(0, "shouldn't happen\n");
2143 static void test_dynamic_context(int call_index
, HANDLE hToken
)
2148 ok(!are_all_privileges_disabled(hToken
), "token should be a copy of the process one\n");
2152 ok(are_all_privileges_disabled(hToken
), "impersonated token should have been modified\n");
2155 ok(0, "shouldn't happen\n");
2159 static void test_dynamic_context_no_token(int call_index
, HANDLE hToken
)
2164 ok(are_all_privileges_disabled(hToken
), "token should be a copy of the process one\n");
2167 ok(!are_all_privileges_disabled(hToken
), "process token modification should have been detected and impersonation token updated\n");
2170 ok(0, "shouldn't happen\n");
2174 static void test_no_sqos_revert(int call_index
, HANDLE hToken
)
2180 priv_count
= get_privilege_count(hToken
);
2182 ok(priv_count
== 0, "privilege count should have been 0 instead of %ld\n", priv_count
);
2185 priv_count
= get_privilege_count(hToken
);
2186 ok(priv_count
> 0, "privilege count should now be > 0 instead of 0\n");
2187 ok(!are_all_privileges_disabled(hToken
), "impersonated token should not have been modified\n");
2190 ok(0, "shouldn't happen\n");
2194 static void test_static_context_revert(int call_index
, HANDLE hToken
)
2200 ok(are_all_privileges_disabled(hToken
), "privileges should have been disabled\n");
2204 ok(are_all_privileges_disabled(hToken
), "impersonated token should not have been modified\n");
2207 ok(0, "shouldn't happen\n");
2211 static void test_dynamic_context_revert(int call_index
, HANDLE hToken
)
2217 ok(are_all_privileges_disabled(hToken
), "privileges should have been disabled\n");
2220 ok(!are_all_privileges_disabled(hToken
), "impersonated token should now be process token\n");
2223 ok(0, "shouldn't happen\n");
2227 static void test_impersonation(void)
2229 HANDLE hClientToken
;
2230 HANDLE hProcessToken
;
2233 if( !pDuplicateTokenEx
) {
2234 skip("DuplicateTokenEx not found\n");
2238 ret
= OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
, &hProcessToken
);
2241 skip("couldn't open process token, skipping impersonation tests\n");
2245 if (!get_privilege_count(hProcessToken
) || are_all_privileges_disabled(hProcessToken
))
2247 skip("token didn't have any privileges or they were all disabled. token not suitable for impersonation tests\n");
2248 CloseHandle(hProcessToken
);
2251 CloseHandle(hProcessToken
);
2253 test_ImpersonateNamedPipeClient(NULL
, 0, FALSE
, test_no_sqos_no_token
);
2254 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2255 test_ImpersonateNamedPipeClient(hClientToken
, 0, FALSE
, test_no_sqos
);
2256 CloseHandle(hClientToken
);
2257 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2258 test_ImpersonateNamedPipeClient(hClientToken
,
2259 SECURITY_SQOS_PRESENT
| SECURITY_IMPERSONATION
, FALSE
,
2260 test_static_context
);
2261 CloseHandle(hClientToken
);
2262 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2263 test_ImpersonateNamedPipeClient(hClientToken
,
2264 SECURITY_SQOS_PRESENT
| SECURITY_CONTEXT_TRACKING
| SECURITY_IMPERSONATION
,
2265 FALSE
, test_dynamic_context
);
2266 CloseHandle(hClientToken
);
2267 test_ImpersonateNamedPipeClient(NULL
,
2268 SECURITY_SQOS_PRESENT
| SECURITY_CONTEXT_TRACKING
| SECURITY_IMPERSONATION
,
2269 FALSE
, test_dynamic_context_no_token
);
2271 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2272 test_ImpersonateNamedPipeClient(hClientToken
, 0, TRUE
, test_no_sqos_revert
);
2273 CloseHandle(hClientToken
);
2274 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2275 test_ImpersonateNamedPipeClient(hClientToken
,
2276 SECURITY_SQOS_PRESENT
| SECURITY_IMPERSONATION
, TRUE
,
2277 test_static_context_revert
);
2278 CloseHandle(hClientToken
);
2279 hClientToken
= make_impersonation_token(TOKEN_IMPERSONATE
| TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, SecurityImpersonation
);
2280 test_ImpersonateNamedPipeClient(hClientToken
,
2281 SECURITY_SQOS_PRESENT
| SECURITY_CONTEXT_TRACKING
| SECURITY_IMPERSONATION
,
2282 TRUE
, test_dynamic_context_revert
);
2283 CloseHandle(hClientToken
);
2286 struct overlapped_server_args
2288 HANDLE pipe_created
;
2291 static DWORD CALLBACK
overlapped_server(LPVOID arg
)
2296 struct overlapped_server_args
*a
= arg
;
2300 pipe
= CreateNamedPipeA("\\\\.\\pipe\\my pipe", FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
, PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
, 1, 0, 0, 100000, NULL
);
2301 ok(pipe
!= NULL
, "pipe NULL\n");
2303 ol
.hEvent
= CreateEventA(0, 1, 0, 0);
2304 ok(ol
.hEvent
!= NULL
, "event NULL\n");
2305 ret
= ConnectNamedPipe(pipe
, &ol
);
2306 err
= GetLastError();
2307 ok(ret
== 0, "ret %d\n", ret
);
2308 ok(err
== ERROR_IO_PENDING
, "gle %d\n", err
);
2309 SetEvent(a
->pipe_created
);
2311 ret
= WaitForSingleObjectEx(ol
.hEvent
, INFINITE
, 1);
2312 ok(ret
== WAIT_OBJECT_0
, "ret %x\n", ret
);
2314 ret
= GetOverlappedResult(pipe
, &ol
, &num
, 1);
2315 ok(ret
== 1, "ret %d\n", ret
);
2317 /* This should block */
2318 ret
= ReadFile(pipe
, buf
, sizeof(buf
), &num
, NULL
);
2319 ok(ret
== 1, "ret %d\n", ret
);
2321 DisconnectNamedPipe(pipe
);
2323 ret
= ConnectNamedPipe(pipe
, &ol
);
2324 err
= GetLastError();
2325 ok(ret
== 0, "ret %d\n", ret
);
2326 ok(err
== ERROR_IO_PENDING
, "gle %d\n", err
);
2328 ret
= WaitForSingleObjectEx(ol
.hEvent
, INFINITE
, 1);
2329 ok(ret
== WAIT_OBJECT_0
, "ret %x\n", ret
);
2331 ret
= GetOverlappedResult(pipe
, &ol
, &num
, 1);
2332 err
= GetLastError();
2333 ok(ret
== 0, "ret %d\n", ret
);
2334 ok(err
== ERROR_OPERATION_ABORTED
, "gle %d\n", err
);
2336 CloseHandle(ol
.hEvent
);
2341 static void test_overlapped(void)
2344 HANDLE thread
, pipe
;
2346 struct overlapped_server_args args
;
2348 args
.pipe_created
= CreateEventA(0, 1, 0, 0);
2349 thread
= CreateThread(NULL
, 0, overlapped_server
, &args
, 0, &tid
);
2351 WaitForSingleObject(args
.pipe_created
, INFINITE
);
2352 pipe
= CreateFileA("\\\\.\\pipe\\my pipe", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
2353 ok(pipe
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2355 /* Sleep to try to get the ReadFile in the server to occur before the following WriteFile */
2358 ret
= WriteFile(pipe
, "x", 1, &num
, NULL
);
2359 ok(ret
, "WriteFile failed with error %ld\n", GetLastError());
2361 WaitForSingleObject(thread
, INFINITE
);
2363 CloseHandle(args
.pipe_created
);
2364 CloseHandle(thread
);
2367 static void test_overlapped_error(void)
2369 HANDLE pipe
, file
, event
;
2370 DWORD err
, numbytes
;
2371 OVERLAPPED overlapped
;
2374 event
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
2375 ok(event
!= NULL
, "CreateEventA failed with %lu\n", GetLastError());
2377 pipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
2378 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
2379 1, 1024, 1024, NMPWAIT_WAIT_FOREVER
, NULL
);
2380 ok(pipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %lu\n", GetLastError());
2382 memset(&overlapped
, 0, sizeof(overlapped
));
2383 overlapped
.hEvent
= event
;
2384 ret
= ConnectNamedPipe(pipe
, &overlapped
);
2385 err
= GetLastError();
2386 ok(ret
== FALSE
, "ConnectNamedPipe succeeded\n");
2387 ok(err
== ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %lu\n", err
);
2389 file
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
,
2390 OPEN_EXISTING
, FILE_FLAG_OVERLAPPED
, 0);
2391 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %lu\n", GetLastError());
2393 numbytes
= 0xdeadbeef;
2394 ret
= GetOverlappedResult(pipe
, &overlapped
, &numbytes
, TRUE
);
2395 ok(ret
== TRUE
, "GetOverlappedResult failed\n");
2396 ok(numbytes
== 0, "expected 0, got %lu\n", numbytes
);
2397 ok(overlapped
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %08Ix\n", overlapped
.Internal
);
2402 pipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
2403 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
2404 1, 1024, 1024, NMPWAIT_WAIT_FOREVER
, NULL
);
2405 ok(pipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %lu\n", GetLastError());
2407 file
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
,
2408 OPEN_EXISTING
, FILE_FLAG_OVERLAPPED
, 0);
2409 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFile failed with %lu\n", GetLastError());
2411 memset(&overlapped
, 0, sizeof(overlapped
));
2412 overlapped
.hEvent
= event
;
2413 ret
= ConnectNamedPipe(pipe
, &overlapped
);
2414 err
= GetLastError();
2415 ok(ret
== FALSE
, "ConnectNamedPipe succeeded\n");
2416 ok(err
== ERROR_PIPE_CONNECTED
, "expected ERROR_PIPE_CONNECTED, got %lu\n", err
);
2417 ok(overlapped
.Internal
== STATUS_PENDING
, "expected STATUS_PENDING, got %08Ix\n", overlapped
.Internal
);
2425 static void test_NamedPipeHandleState(void)
2427 HANDLE server
, client
;
2429 DWORD state
, instances
, maxCollectionCount
, collectDataTimeout
;
2430 char userName
[MAX_PATH
];
2432 server
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
2433 /* dwOpenMode */ PIPE_TYPE_BYTE
| PIPE_WAIT
,
2434 /* nMaxInstances */ 1,
2435 /* nOutBufSize */ 1024,
2436 /* nInBufSize */ 1024,
2437 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2438 /* lpSecurityAttrib */ NULL
);
2439 ok(server
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2440 ret
= GetNamedPipeHandleStateA(server
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
2441 ok(ret
, "GetNamedPipeHandleState failed: %ld\n", GetLastError());
2442 ret
= GetNamedPipeHandleStateA(server
, &state
, &instances
, NULL
, NULL
, NULL
,
2444 ok(ret
, "GetNamedPipeHandleState failed: %ld\n", GetLastError());
2447 ok(state
== 0, "unexpected state %08lx\n", state
);
2448 ok(instances
== 1, "expected 1 instances, got %ld\n", instances
);
2450 /* Some parameters have no meaning, and therefore can't be retrieved,
2453 SetLastError(0xdeadbeef);
2454 ret
= GetNamedPipeHandleStateA(server
, &state
, &instances
, &maxCollectionCount
,
2455 &collectDataTimeout
, userName
, ARRAY_SIZE(userName
));
2457 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2458 "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
2459 /* A byte-mode pipe server can't be changed to message mode. */
2460 state
= PIPE_READMODE_MESSAGE
;
2461 SetLastError(0xdeadbeef);
2462 ret
= SetNamedPipeHandleState(server
, &state
, NULL
, NULL
);
2463 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2464 "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
2466 client
= CreateFileA(PIPENAME
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
2467 OPEN_EXISTING
, 0, NULL
);
2468 ok(client
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2470 state
= PIPE_READMODE_BYTE
;
2471 ret
= SetNamedPipeHandleState(client
, &state
, NULL
, NULL
);
2472 ok(ret
, "SetNamedPipeHandleState failed: %ld\n", GetLastError());
2473 /* A byte-mode pipe client can't be changed to message mode, either. */
2474 state
= PIPE_READMODE_MESSAGE
;
2475 SetLastError(0xdeadbeef);
2476 ret
= SetNamedPipeHandleState(server
, &state
, NULL
, NULL
);
2477 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
2478 "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
2480 CloseHandle(client
);
2481 CloseHandle(server
);
2483 server
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
2484 /* dwOpenMode */ PIPE_TYPE_MESSAGE
| PIPE_WAIT
,
2485 /* nMaxInstances */ 1,
2486 /* nOutBufSize */ 1024,
2487 /* nInBufSize */ 1024,
2488 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2489 /* lpSecurityAttrib */ NULL
);
2490 ok(server
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2491 ret
= GetNamedPipeHandleStateA(server
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
2492 ok(ret
, "GetNamedPipeHandleState failed: %ld\n", GetLastError());
2493 ret
= GetNamedPipeHandleStateA(server
, &state
, &instances
, NULL
, NULL
, NULL
,
2495 ok(ret
, "GetNamedPipeHandleState failed: %ld\n", GetLastError());
2498 ok(state
== 0, "unexpected state %08lx\n", state
);
2499 ok(instances
== 1, "expected 1 instances, got %ld\n", instances
);
2501 /* In contrast to byte-mode pipes, a message-mode pipe server can be
2502 * changed to byte mode.
2504 state
= PIPE_READMODE_BYTE
;
2505 ret
= SetNamedPipeHandleState(server
, &state
, NULL
, NULL
);
2506 ok(ret
, "SetNamedPipeHandleState failed: %ld\n", GetLastError());
2508 client
= CreateFileA(PIPENAME
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
2509 OPEN_EXISTING
, 0, NULL
);
2510 ok(client
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2512 state
= PIPE_READMODE_MESSAGE
;
2513 ret
= SetNamedPipeHandleState(client
, &state
, NULL
, NULL
);
2514 ok(ret
, "SetNamedPipeHandleState failed: %ld\n", GetLastError());
2515 /* A message-mode pipe client can also be changed to byte mode.
2517 state
= PIPE_READMODE_BYTE
;
2518 ret
= SetNamedPipeHandleState(client
, &state
, NULL
, NULL
);
2519 ok(ret
, "SetNamedPipeHandleState failed: %ld\n", GetLastError());
2521 CloseHandle(client
);
2522 CloseHandle(server
);
2525 static void test_GetNamedPipeInfo(void)
2529 server
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
2530 /* dwOpenMode */ PIPE_TYPE_BYTE
| PIPE_WAIT
,
2531 /* nMaxInstances */ 1,
2532 /* nOutBufSize */ 1024,
2533 /* nInBufSize */ 1024,
2534 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2535 /* lpSecurityAttrib */ NULL
);
2536 ok(server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
2538 test_pipe_info(server
, PIPE_SERVER_END
| PIPE_TYPE_BYTE
, 1024, 1024, 1);
2540 CloseHandle(server
);
2542 server
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
2543 /* dwOpenMode */ PIPE_TYPE_MESSAGE
| PIPE_NOWAIT
,
2544 /* nMaxInstances */ 3,
2545 /* nOutBufSize */ 1024,
2546 /* nInBufSize */ 1024,
2547 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2548 /* lpSecurityAttrib */ NULL
);
2549 ok(server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
2551 test_pipe_info(server
, PIPE_SERVER_END
| PIPE_TYPE_MESSAGE
, 1024, 1024, 3);
2553 CloseHandle(server
);
2555 server
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
,
2556 /* dwOpenMode */ PIPE_TYPE_MESSAGE
| PIPE_WAIT
,
2557 /* nMaxInstances */ 1,
2558 /* nOutBufSize */ 0,
2560 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2561 /* lpSecurityAttrib */ NULL
);
2562 ok(server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
2564 test_pipe_info(server
, PIPE_SERVER_END
| PIPE_TYPE_MESSAGE
, 0, 0, 1);
2566 CloseHandle(server
);
2568 server
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
,
2569 /* dwOpenMode */ PIPE_TYPE_MESSAGE
| PIPE_WAIT
,
2570 /* nMaxInstances */ 1,
2571 /* nOutBufSize */ 0xf000,
2572 /* nInBufSize */ 0xf000,
2573 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2574 /* lpSecurityAttrib */ NULL
);
2575 ok(server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
2577 test_pipe_info(server
, PIPE_SERVER_END
| PIPE_TYPE_MESSAGE
, 0xf000, 0xf000, 1);
2579 CloseHandle(server
);
2582 static void test_readfileex_pending(void)
2584 HANDLE server
, client
, event
;
2586 DWORD err
, wait
, num_bytes
;
2587 OVERLAPPED overlapped
;
2588 char read_buf
[1024];
2589 char write_buf
[1024];
2590 const char test_string
[] = "test";
2593 server
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
,
2594 /* dwOpenMode */ PIPE_TYPE_BYTE
| PIPE_WAIT
,
2595 /* nMaxInstances */ 1,
2596 /* nOutBufSize */ 1024,
2597 /* nInBufSize */ 1024,
2598 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
2599 /* lpSecurityAttrib */ NULL
);
2600 ok(server
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2602 event
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
2603 ok(event
!= NULL
, "CreateEventA failed\n");
2605 memset(&overlapped
, 0, sizeof(overlapped
));
2606 overlapped
.hEvent
= event
;
2608 ret
= ConnectNamedPipe(server
, &overlapped
);
2609 err
= GetLastError();
2610 ok(ret
== FALSE
, "ConnectNamedPipe succeeded\n");
2611 ok(err
== ERROR_IO_PENDING
, "ConnectNamedPipe set error %li\n", err
);
2613 wait
= WaitForSingleObject(event
, 0);
2614 ok(wait
== WAIT_TIMEOUT
, "WaitForSingleObject returned %lx\n", wait
);
2616 client
= CreateFileA(PIPENAME
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
2617 OPEN_EXISTING
, 0, NULL
);
2618 ok(client
!= INVALID_HANDLE_VALUE
, "cf failed\n");
2620 wait
= WaitForSingleObject(event
, 0);
2621 ok(wait
== WAIT_OBJECT_0
, "WaitForSingleObject returned %lx\n", wait
);
2623 /* Start a read that can't complete immediately. */
2624 completion_called
= 0;
2626 ret
= ReadFileEx(server
, read_buf
, sizeof(read_buf
), &overlapped
, completion_routine
);
2627 ok(ret
== TRUE
, "ReadFileEx failed, err=%li\n", GetLastError());
2628 ok(completion_called
== 0, "completion routine called before ReadFileEx returned\n");
2630 ret
= WriteFile(client
, test_string
, strlen(test_string
), &num_bytes
, NULL
);
2631 ok(ret
== TRUE
, "WriteFile failed\n");
2632 ok(num_bytes
== strlen(test_string
), "only %li bytes written\n", num_bytes
);
2634 ok(completion_called
== 0, "completion routine called during WriteFile\n");
2636 wait
= WaitForSingleObjectEx(event
, 0, TRUE
);
2637 ok(wait
== WAIT_IO_COMPLETION
|| wait
== WAIT_OBJECT_0
, "WaitForSingleObjectEx returned %lx\n", wait
);
2639 ok(completion_called
== 1, "completion not called after writing pipe\n");
2640 ok(completion_errorcode
== 0, "completion called with error %lx\n", completion_errorcode
);
2641 ok(completion_num_bytes
== strlen(test_string
), "ReadFileEx returned only %ld bytes\n", completion_num_bytes
);
2642 ok(completion_lpoverlapped
== &overlapped
, "completion called with wrong overlapped pointer\n");
2643 ok(!memcmp(test_string
, read_buf
, strlen(test_string
)), "ReadFileEx read wrong bytes\n");
2645 /* Make writes until the pipe is full and the write fails */
2646 memset(write_buf
, 0xaa, sizeof(write_buf
));
2647 for (i
=0; i
<256; i
++)
2649 completion_called
= 0;
2651 ret
= WriteFileEx(server
, write_buf
, sizeof(write_buf
), &overlapped
, completion_routine
);
2652 err
= GetLastError();
2654 ok(completion_called
== 0, "completion routine called during WriteFileEx\n");
2656 wait
= WaitForSingleObjectEx(event
, 0, TRUE
);
2658 if (wait
== WAIT_TIMEOUT
)
2659 /* write couldn't complete immediately, presumably the pipe is full */
2662 ok(wait
== WAIT_IO_COMPLETION
|| wait
== WAIT_OBJECT_0
, "WaitForSingleObject returned %lx\n", wait
);
2664 ok(ret
== TRUE
, "WriteFileEx failed, err=%li\n", err
);
2665 ok(completion_errorcode
== 0, "completion called with error %lx\n", completion_errorcode
);
2666 ok(completion_lpoverlapped
== &overlapped
, "completion called with wrong overlapped pointer\n");
2669 ok(ret
== TRUE
, "WriteFileEx failed, err=%li\n", err
);
2670 ok(completion_called
== 0, "completion routine called but wait timed out\n");
2671 ok(completion_errorcode
== 0, "completion called with error %lx\n", completion_errorcode
);
2672 ok(completion_lpoverlapped
== &overlapped
, "completion called with wrong overlapped pointer\n");
2674 /* free up some space in the pipe */
2675 for (i
=0; i
<256; i
++)
2677 ret
= ReadFile(client
, read_buf
, sizeof(read_buf
), &num_bytes
, NULL
);
2678 ok(ret
== TRUE
, "ReadFile failed\n");
2680 ok(completion_called
== 0, "completion routine called during ReadFile\n");
2682 wait
= WaitForSingleObjectEx(event
, 0, TRUE
);
2683 ok(wait
== WAIT_IO_COMPLETION
|| wait
== WAIT_OBJECT_0
|| wait
== WAIT_TIMEOUT
,
2684 "WaitForSingleObject returned %lx\n", wait
);
2685 if (wait
!= WAIT_TIMEOUT
) break;
2688 ok(completion_called
== 1, "completion routine not called\n");
2689 ok(completion_errorcode
== 0, "completion called with error %lx\n", completion_errorcode
);
2690 ok(completion_lpoverlapped
== &overlapped
, "completion called with wrong overlapped pointer\n");
2692 num_bytes
= 0xdeadbeef;
2693 SetLastError(0xdeadbeef);
2694 ret
= ReadFile(INVALID_HANDLE_VALUE
, read_buf
, 0, &num_bytes
, NULL
);
2695 ok(!ret
, "ReadFile should fail\n");
2696 ok(GetLastError() == ERROR_INVALID_HANDLE
, "wrong error %lu\n", GetLastError());
2697 ok(num_bytes
== 0, "expected 0, got %lu\n", num_bytes
);
2699 S(U(overlapped
)).Offset
= 0;
2700 S(U(overlapped
)).OffsetHigh
= 0;
2701 overlapped
.Internal
= -1;
2702 overlapped
.InternalHigh
= -1;
2703 overlapped
.hEvent
= event
;
2704 num_bytes
= 0xdeadbeef;
2705 SetLastError(0xdeadbeef);
2706 ret
= ReadFile(server
, read_buf
, 0, &num_bytes
, &overlapped
);
2707 ok(!ret
, "ReadFile should fail\n");
2708 ok(GetLastError() == ERROR_IO_PENDING
, "expected ERROR_IO_PENDING, got %ld\n", GetLastError());
2709 ok(num_bytes
== 0, "bytes %lu\n", num_bytes
);
2710 ok((NTSTATUS
)overlapped
.Internal
== STATUS_PENDING
, "expected STATUS_PENDING, got %#Ix\n", overlapped
.Internal
);
2711 ok(overlapped
.InternalHigh
== -1, "expected -1, got %Iu\n", overlapped
.InternalHigh
);
2713 wait
= WaitForSingleObject(event
, 100);
2714 ok(wait
== WAIT_TIMEOUT
, "WaitForSingleObject returned %lx\n", wait
);
2716 num_bytes
= 0xdeadbeef;
2717 ret
= WriteFile(client
, test_string
, 1, &num_bytes
, NULL
);
2718 ok(ret
, "WriteFile failed\n");
2719 ok(num_bytes
== 1, "bytes %lu\n", num_bytes
);
2721 wait
= WaitForSingleObject(event
, 100);
2722 ok(wait
== WAIT_OBJECT_0
, "WaitForSingleObject returned %lx\n", wait
);
2724 ok(num_bytes
== 1, "bytes %lu\n", num_bytes
);
2725 ok((NTSTATUS
)overlapped
.Internal
== STATUS_SUCCESS
, "expected STATUS_SUCCESS, got %#Ix\n", overlapped
.Internal
);
2726 ok(overlapped
.InternalHigh
== 0, "expected 0, got %Iu\n", overlapped
.InternalHigh
);
2728 /* read the pending byte and clear the pipe */
2729 num_bytes
= 0xdeadbeef;
2730 ret
= ReadFile(server
, read_buf
, 1, &num_bytes
, &overlapped
);
2731 ok(ret
, "ReadFile failed\n");
2732 ok(num_bytes
== 1, "bytes %lu\n", num_bytes
);
2734 CloseHandle(client
);
2735 CloseHandle(server
);
2739 #define test_peek_pipe(a,b,c,d) _test_peek_pipe(__LINE__,a,b,c,d)
2740 static void _test_peek_pipe(unsigned line
, HANDLE pipe
, DWORD expected_read
, DWORD expected_avail
, DWORD expected_message_length
)
2742 DWORD bytes_read
= 0xdeadbeed, avail
= 0xdeadbeef, left
= 0xdeadbeed;
2744 FILE_PIPE_PEEK_BUFFER
*peek_buf
= (void*)buf
;
2749 r
= PeekNamedPipe(pipe
, buf
, sizeof(buf
), &bytes_read
, &avail
, &left
);
2750 ok_(__FILE__
,line
)(r
, "PeekNamedPipe failed: %lu\n", GetLastError());
2751 ok_(__FILE__
,line
)(bytes_read
== expected_read
, "bytes_read = %lu, expected %lu\n", bytes_read
, expected_read
);
2752 ok_(__FILE__
,line
)(avail
== expected_avail
, "avail = %lu, expected %lu\n", avail
, expected_avail
);
2753 ok_(__FILE__
,line
)(left
== expected_message_length
- expected_read
, "left = %ld, expected %ld\n",
2754 left
, expected_message_length
- expected_read
);
2756 status
= NtFsControlFile(pipe
, 0, NULL
, NULL
, &io
, FSCTL_PIPE_PEEK
, NULL
, 0, buf
, sizeof(buf
));
2757 ok_(__FILE__
,line
)(!status
|| status
== STATUS_PENDING
, "NtFsControlFile(FSCTL_PIPE_PEEK) failed: %lx\n", status
);
2758 ok_(__FILE__
,line
)(io
.Information
== FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER
, Data
[expected_read
]),
2759 "io.Information = %Iu\n", io
.Information
);
2760 ok_(__FILE__
,line
)(peek_buf
->ReadDataAvailable
== expected_avail
, "ReadDataAvailable = %lu, expected %lu\n",
2761 peek_buf
->ReadDataAvailable
, expected_avail
);
2762 ok_(__FILE__
,line
)(peek_buf
->MessageLength
== expected_message_length
, "MessageLength = %lu, expected %lu\n",
2763 peek_buf
->MessageLength
, expected_message_length
);
2767 r
= PeekNamedPipe(pipe
, buf
, 1, &bytes_read
, &avail
, &left
);
2768 ok_(__FILE__
,line
)(r
, "PeekNamedPipe failed: %lu\n", GetLastError());
2769 ok_(__FILE__
,line
)(bytes_read
== 1, "bytes_read = %lu, expected %lu\n", bytes_read
, expected_read
);
2770 ok_(__FILE__
,line
)(avail
== expected_avail
, "avail = %lu, expected %lu\n", avail
, expected_avail
);
2771 ok_(__FILE__
,line
)(left
== expected_message_length
-1, "left = %ld, expected %ld\n", left
, expected_message_length
-1);
2775 #define overlapped_read_sync(a,b,c,d,e) _overlapped_read_sync(__LINE__,a,b,c,d,e)
2776 static void _overlapped_read_sync(unsigned line
, HANDLE reader
, void *buf
, DWORD buf_size
, DWORD expected_result
, BOOL partial_read
)
2778 DWORD read_bytes
= 0xdeadbeef;
2779 OVERLAPPED overlapped
;
2782 memset(&overlapped
, 0, sizeof(overlapped
));
2783 overlapped
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
2784 res
= ReadFile(reader
, buf
, buf_size
, &read_bytes
, &overlapped
);
2786 ok_(__FILE__
,line
)(!res
&& GetLastError() == ERROR_MORE_DATA
, "ReadFile returned: %x (%lu)\n", res
, GetLastError());
2788 ok_(__FILE__
,line
)(res
, "ReadFile failed: %lu\n", GetLastError());
2790 ok_(__FILE__
,line
)(!read_bytes
, "read_bytes %lu expected 0\n", read_bytes
);
2792 ok_(__FILE__
,line
)(read_bytes
== expected_result
, "read_bytes %lu expected %lu\n", read_bytes
, expected_result
);
2794 read_bytes
= 0xdeadbeef;
2795 res
= GetOverlappedResult(reader
, &overlapped
, &read_bytes
, FALSE
);
2797 ok_(__FILE__
,line
)(!res
&& GetLastError() == ERROR_MORE_DATA
,
2798 "GetOverlappedResult returned: %x (%lu)\n", res
, GetLastError());
2800 ok_(__FILE__
,line
)(res
, "GetOverlappedResult failed: %lu\n", GetLastError());
2801 ok_(__FILE__
,line
)(read_bytes
== expected_result
, "read_bytes %lu expected %lu\n", read_bytes
, expected_result
);
2802 CloseHandle(overlapped
.hEvent
);
2805 #define overlapped_read_async(a,b,c,d) _overlapped_read_async(__LINE__,a,b,c,d)
2806 static void _overlapped_read_async(unsigned line
, HANDLE reader
, void *buf
, DWORD buf_size
, OVERLAPPED
*overlapped
)
2808 DWORD read_bytes
= 0xdeadbeef;
2811 memset(overlapped
, 0, sizeof(*overlapped
));
2812 overlapped
->hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
2813 res
= ReadFile(reader
, buf
, buf_size
, &read_bytes
, overlapped
);
2814 ok_(__FILE__
,line
)(!res
&& GetLastError() == ERROR_IO_PENDING
, "ReadFile returned %x(%lu)\n", res
, GetLastError());
2815 ok_(__FILE__
,line
)(!read_bytes
, "read_bytes %lu expected 0\n", read_bytes
);
2817 _test_not_signaled(line
, overlapped
->hEvent
);
2820 #define overlapped_write_sync(a,b,c) _overlapped_write_sync(__LINE__,a,b,c)
2821 static void _overlapped_write_sync(unsigned line
, HANDLE writer
, void *buf
, DWORD size
)
2823 DWORD written_bytes
= 0xdeadbeef;
2824 OVERLAPPED overlapped
;
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
, "WriteFile returned %x(%lu)\n", res
, GetLastError());
2831 ok_(__FILE__
,line
)(written_bytes
== size
, "WriteFile returned written_bytes = %lu\n", written_bytes
);
2833 written_bytes
= 0xdeadbeef;
2834 res
= GetOverlappedResult(writer
, &overlapped
, &written_bytes
, FALSE
);
2835 ok_(__FILE__
,line
)(res
, "GetOverlappedResult failed: %lu\n", GetLastError());
2836 ok_(__FILE__
,line
)(written_bytes
== size
, "GetOverlappedResult returned written_bytes %lu expected %lu\n", written_bytes
, size
);
2838 CloseHandle(overlapped
.hEvent
);
2841 #define overlapped_write_async(a,b,c,d) _overlapped_write_async(__LINE__,a,b,c,d)
2842 static void _overlapped_write_async(unsigned line
, HANDLE writer
, void *buf
, DWORD size
, OVERLAPPED
*overlapped
)
2844 DWORD written_bytes
= 0xdeadbeef;
2847 memset(overlapped
, 0, sizeof(*overlapped
));
2848 overlapped
->hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
2849 res
= WriteFile(writer
, buf
, size
, &written_bytes
, overlapped
);
2850 ok_(__FILE__
,line
)(!res
&& GetLastError() == ERROR_IO_PENDING
, "WriteFile returned %x(%lu)\n", res
, GetLastError());
2851 ok_(__FILE__
,line
)(!written_bytes
, "written_bytes = %lu\n", written_bytes
);
2853 _test_not_signaled(line
, overlapped
->hEvent
);
2856 #define test_flush_sync(a) _test_flush_sync(__LINE__,a)
2857 static void _test_flush_sync(unsigned line
, HANDLE pipe
)
2861 res
= FlushFileBuffers(pipe
);
2862 ok_(__FILE__
,line
)(res
, "FlushFileBuffers failed: %lu\n", GetLastError());
2865 static DWORD expected_flush_error
;
2867 static DWORD CALLBACK
flush_proc(HANDLE pipe
)
2871 res
= FlushFileBuffers(pipe
);
2872 if (expected_flush_error
== ERROR_SUCCESS
)
2874 ok(res
, "FlushFileBuffers failed: %lu\n", GetLastError());
2878 ok(!res
, "FlushFileBuffers should have failed\n");
2879 ok(GetLastError() == expected_flush_error
,
2880 "FlushFileBuffers set error %lu, expected %lu\n", GetLastError(), expected_flush_error
);
2885 #define test_flush_async(a,b) _test_flush_async(__LINE__,a,b)
2886 static HANDLE
_test_flush_async(unsigned line
, HANDLE pipe
, DWORD error
)
2891 expected_flush_error
= error
;
2892 thread
= CreateThread(NULL
, 0, flush_proc
, pipe
, 0, &tid
);
2893 ok_(__FILE__
,line
)(thread
!= NULL
, "CreateThread failed: %lu\n", GetLastError());
2896 _test_not_signaled(line
, thread
);
2900 #define test_flush_done(a) _test_flush_done(__LINE__,a)
2901 static void _test_flush_done(unsigned line
, HANDLE thread
)
2903 DWORD res
= WaitForSingleObject(thread
, 1000);
2904 ok_(__FILE__
,line
)(res
== WAIT_OBJECT_0
, "WaitForSingleObject returned %lu (%lu)\n", res
, GetLastError());
2905 CloseHandle(thread
);
2908 #define test_overlapped_result(a,b,c,d) _test_overlapped_result(__LINE__,a,b,c,d)
2909 static void _test_overlapped_result(unsigned line
, HANDLE handle
, OVERLAPPED
*overlapped
, DWORD expected_result
, BOOL partial_read
)
2911 DWORD result
= 0xdeadbeef;
2914 _test_signaled(line
, overlapped
->hEvent
);
2916 res
= GetOverlappedResult(handle
, overlapped
, &result
, FALSE
);
2918 ok_(__FILE__
,line
)(!res
&& GetLastError() == ERROR_MORE_DATA
, "GetOverlappedResult returned: %x (%lu)\n", res
, GetLastError());
2920 ok_(__FILE__
,line
)(res
, "GetOverlappedResult failed: %lu\n", GetLastError());
2921 ok_(__FILE__
,line
)(result
== expected_result
, "read_bytes = %lu, expected %lu\n", result
, expected_result
);
2922 CloseHandle(overlapped
->hEvent
);
2925 #define test_overlapped_failure(a,b,c) _test_overlapped_failure(__LINE__,a,b,c)
2926 static void _test_overlapped_failure(unsigned line
, HANDLE handle
, OVERLAPPED
*overlapped
, DWORD error
)
2931 _test_signaled(line
, overlapped
->hEvent
);
2933 res
= GetOverlappedResult(handle
, overlapped
, &result
, FALSE
);
2934 ok_(__FILE__
,line
)(!res
&& GetLastError() == error
, "GetOverlappedResult returned: %x (%lu), expected error %lu\n",
2935 res
, GetLastError(), error
);
2936 ok_(__FILE__
,line
)(!result
, "result = %lu\n", result
);
2937 CloseHandle(overlapped
->hEvent
);
2940 #define cancel_overlapped(a,b) _cancel_overlapped(__LINE__,a,b)
2941 static void _cancel_overlapped(unsigned line
, HANDLE handle
, OVERLAPPED
*overlapped
)
2945 res
= pCancelIoEx(handle
, overlapped
);
2946 ok_(__FILE__
,line
)(res
, "CancelIoEx failed: %lu\n", GetLastError());
2948 _test_overlapped_failure(line
, handle
, overlapped
, ERROR_OPERATION_ABORTED
);
2951 static void test_blocking_rw(HANDLE writer
, HANDLE reader
, DWORD buf_size
, BOOL msg_mode
, BOOL msg_read
)
2953 OVERLAPPED read_overlapped
, read_overlapped2
, write_overlapped
, write_overlapped2
;
2954 char buf
[10000], read_buf
[10000];
2955 HANDLE flush_thread
;
2958 memset(buf
, 0xaa, sizeof(buf
));
2960 /* test pending read with overlapped event */
2961 overlapped_read_async(reader
, read_buf
, 1000, &read_overlapped
);
2962 test_flush_sync(writer
);
2963 test_peek_pipe(reader
, 0, 0, 0);
2965 /* write more data than needed for read */
2966 overlapped_write_sync(writer
, buf
, 4000);
2967 test_overlapped_result(reader
, &read_overlapped
, 1000, msg_read
);
2968 test_peek_pipe(reader
, 3000, 3000, msg_mode
? 3000 : 0);
2970 /* test pending write with overlapped event */
2971 overlapped_write_async(writer
, buf
, buf_size
, &write_overlapped
);
2972 test_peek_pipe(reader
, 3000 + (msg_mode
? 0 : buf_size
), 3000 + buf_size
, msg_mode
? 3000 : 0);
2974 /* write one more byte */
2975 overlapped_write_async(writer
, buf
, 1, &write_overlapped2
);
2976 flush_thread
= test_flush_async(writer
, ERROR_SUCCESS
);
2977 test_not_signaled(write_overlapped
.hEvent
);
2978 test_peek_pipe(reader
, 3000 + (msg_mode
? 0 : buf_size
+ 1), 3000 + buf_size
+ 1,
2979 msg_mode
? 3000 : 0);
2981 /* empty write will not block */
2982 overlapped_write_sync(writer
, buf
, 0);
2983 test_not_signaled(write_overlapped
.hEvent
);
2984 test_not_signaled(write_overlapped2
.hEvent
);
2985 test_peek_pipe(reader
, 3000 + (msg_mode
? 0 : buf_size
+ 1), 3000 + buf_size
+ 1,
2986 msg_mode
? 3000 : 0);
2988 /* read remaining data from the first write */
2989 overlapped_read_sync(reader
, read_buf
, 3000, 3000, FALSE
);
2990 test_overlapped_result(writer
, &write_overlapped
, buf_size
, FALSE
);
2991 test_not_signaled(write_overlapped2
.hEvent
);
2992 test_not_signaled(flush_thread
);
2993 test_peek_pipe(reader
, buf_size
+ (msg_mode
? 0 : 1), buf_size
+ 1, msg_mode
? buf_size
: 0);
2995 /* read one byte so that the next write fits the buffer */
2996 overlapped_read_sync(reader
, read_buf
, 1, 1, msg_read
);
2997 test_overlapped_result(writer
, &write_overlapped2
, 1, FALSE
);
2998 test_peek_pipe(reader
, buf_size
+ (msg_mode
? -1 : 0), buf_size
, msg_mode
? buf_size
- 1 : 0);
3000 /* read the whole buffer */
3001 overlapped_read_sync(reader
, read_buf
, buf_size
, buf_size
-msg_read
, FALSE
);
3002 test_peek_pipe(reader
, msg_read
? 1 : 0, msg_read
? 1 : 0, msg_read
? 1 : 0);
3006 overlapped_read_sync(reader
, read_buf
, 1000, 1, FALSE
);
3007 test_peek_pipe(reader
, 0, 0, 0);
3012 /* we still have an empty message in queue */
3013 overlapped_read_sync(reader
, read_buf
, 1000, 0, FALSE
);
3014 test_peek_pipe(reader
, 0, 0, 0);
3016 test_flush_done(flush_thread
);
3018 /* pipe is empty, the next read will block */
3019 overlapped_read_async(reader
, read_buf
, 0, &read_overlapped
);
3020 overlapped_read_async(reader
, read_buf
, 1000, &read_overlapped2
);
3022 /* write one byte */
3023 overlapped_write_sync(writer
, buf
, 1);
3024 test_overlapped_result(reader
, &read_overlapped
, 0, msg_read
);
3025 test_overlapped_result(reader
, &read_overlapped2
, 1, FALSE
);
3026 test_peek_pipe(reader
, 0, 0, 0);
3028 /* write a message larger than buffer */
3029 overlapped_write_async(writer
, buf
, buf_size
+2000, &write_overlapped
);
3030 test_peek_pipe(reader
, buf_size
+ 2000, buf_size
+ 2000, msg_mode
? buf_size
+ 2000 : 0);
3032 /* read so that pending write is still larger than the buffer */
3033 overlapped_read_sync(reader
, read_buf
, 1999, 1999, msg_read
);
3034 test_not_signaled(write_overlapped
.hEvent
);
3035 test_peek_pipe(reader
, buf_size
+ 1, buf_size
+ 1, msg_mode
? buf_size
+ 1 : 0);
3037 /* read one more byte */
3038 overlapped_read_sync(reader
, read_buf
, 1, 1, msg_read
);
3039 test_overlapped_result(writer
, &write_overlapped
, buf_size
+2000, FALSE
);
3040 test_peek_pipe(reader
, buf_size
, buf_size
, msg_mode
? buf_size
: 0);
3042 /* read remaining data */
3043 overlapped_read_sync(reader
, read_buf
, buf_size
+1, buf_size
, FALSE
);
3044 test_peek_pipe(reader
, 0, 0, 0);
3046 /* simple pass of empty message */
3047 overlapped_write_sync(writer
, buf
, 0);
3048 test_peek_pipe(reader
, 0, 0, 0);
3050 overlapped_read_sync(reader
, read_buf
, 1, 0, FALSE
);
3052 /* pipe is empty, the next read will block */
3053 test_flush_sync(writer
);
3054 overlapped_read_async(reader
, read_buf
, 0, &read_overlapped
);
3055 overlapped_read_async(reader
, read_buf
, 1, &read_overlapped2
);
3057 /* 0 length write wakes one read in msg mode */
3058 overlapped_write_sync(writer
, buf
, 0);
3060 test_overlapped_result(reader
, &read_overlapped
, 0, FALSE
);
3062 test_not_signaled(read_overlapped
.hEvent
);
3063 test_not_signaled(read_overlapped2
.hEvent
);
3064 overlapped_write_sync(writer
, buf
, 1);
3065 test_overlapped_result(reader
, &read_overlapped2
, 1, FALSE
);
3067 overlapped_write_sync(writer
, buf
, 20);
3068 test_peek_pipe(reader
, 20, 20, msg_mode
? 20 : 0);
3069 overlapped_write_sync(writer
, buf
, 15);
3070 test_peek_pipe(reader
, msg_mode
? 20 : 35, 35, msg_mode
? 20 : 0);
3071 overlapped_read_sync(reader
, read_buf
, 10, 10, msg_read
);
3072 test_peek_pipe(reader
, msg_mode
? 10 : 25, 25, msg_mode
? 10 : 0);
3073 overlapped_read_sync(reader
, read_buf
, 10, 10, FALSE
);
3074 test_peek_pipe(reader
, 15, 15, msg_mode
? 15 : 0);
3075 overlapped_read_sync(reader
, read_buf
, 15, 15, FALSE
);
3078 win_skip("CancelIoEx not available\n");
3082 /* add one more pending read, then cancel the first one */
3083 overlapped_read_async(reader
, read_buf
, 1, &read_overlapped
);
3084 overlapped_read_async(reader
, read_buf
, 1, &read_overlapped2
);
3085 cancel_overlapped(reader
, &read_overlapped2
);
3086 test_not_signaled(read_overlapped
.hEvent
);
3087 overlapped_write_sync(writer
, buf
, 1);
3088 test_overlapped_result(reader
, &read_overlapped
, 1, FALSE
);
3090 /* Test that canceling the same operation twice gives a sensible error */
3091 SetLastError(0xdeadbeef);
3092 overlapped_read_async(reader
, read_buf
, 1, &read_overlapped2
);
3093 res
= pCancelIoEx(reader
, &read_overlapped2
);
3094 ok(res
, "CancelIoEx failed with error %ld\n", GetLastError());
3095 res
= pCancelIoEx(reader
, &read_overlapped2
);
3096 ok(!res
, "CancelIOEx succeeded unexpectedly\n");
3097 ok(GetLastError() == ERROR_NOT_FOUND
,
3098 "In CancelIoEx failure, expected ERROR_NOT_FOUND, got %ld\n", GetLastError());
3099 test_overlapped_failure(reader
, &read_overlapped2
, ERROR_OPERATION_ABORTED
);
3101 /* make two async writes, cancel the first one and make sure that we read from the second one */
3102 overlapped_write_async(writer
, buf
, buf_size
+2000, &write_overlapped
);
3103 overlapped_write_async(writer
, buf
, 1, &write_overlapped2
);
3104 test_peek_pipe(reader
, buf_size
+ 2000 + (msg_mode
? 0 : 1),
3105 buf_size
+ 2001, msg_mode
? buf_size
+ 2000 : 0);
3106 cancel_overlapped(writer
, &write_overlapped
);
3107 test_peek_pipe(reader
, 1, 1, msg_mode
? 1 : 0);
3108 overlapped_read_sync(reader
, read_buf
, 1000, 1, FALSE
);
3109 test_overlapped_result(writer
, &write_overlapped2
, 1, FALSE
);
3110 test_peek_pipe(reader
, 0, 0, 0);
3112 /* same as above, but partially read written data before canceling */
3113 overlapped_write_async(writer
, buf
, buf_size
+2000, &write_overlapped
);
3114 overlapped_write_async(writer
, buf
, 1, &write_overlapped2
);
3115 test_peek_pipe(reader
, buf_size
+ 2000 + (msg_mode
? 0 : 1),
3116 buf_size
+ 2001, msg_mode
? buf_size
+ 2000 : 0);
3117 overlapped_read_sync(reader
, read_buf
, 10, 10, msg_read
);
3118 test_not_signaled(write_overlapped
.hEvent
);
3119 cancel_overlapped(writer
, &write_overlapped
);
3120 test_peek_pipe(reader
, 1, 1, msg_mode
? 1 : 0);
3121 overlapped_read_sync(reader
, read_buf
, 1000, 1, FALSE
);
3122 test_overlapped_result(writer
, &write_overlapped2
, 1, FALSE
);
3123 test_peek_pipe(reader
, 0, 0, 0);
3125 /* empty queue by canceling write and make sure that flush is signaled */
3126 overlapped_write_async(writer
, buf
, buf_size
+2000, &write_overlapped
);
3127 flush_thread
= test_flush_async(writer
, ERROR_SUCCESS
);
3128 test_not_signaled(flush_thread
);
3129 cancel_overlapped(writer
, &write_overlapped
);
3130 test_peek_pipe(reader
, 0, 0, 0);
3131 test_flush_done(flush_thread
);
3134 #define overlapped_transact(a,b,c,d,e,f) _overlapped_transact(__LINE__,a,b,c,d,e,f)
3135 static void _overlapped_transact(unsigned line
, HANDLE caller
, void *write_buf
, DWORD write_size
,
3136 void *read_buf
, DWORD read_size
, OVERLAPPED
*overlapped
)
3140 memset(overlapped
, 0, sizeof(*overlapped
));
3141 overlapped
->hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
3142 res
= TransactNamedPipe(caller
, write_buf
, write_size
, read_buf
, read_size
, NULL
, overlapped
);
3143 ok_(__FILE__
,line
)(!res
&& GetLastError() == ERROR_IO_PENDING
,
3144 "TransactNamedPipe returned: %x(%lu)\n", res
, GetLastError());
3147 #define overlapped_transact_failure(a,b,c,d,e,f) _overlapped_transact_failure(__LINE__,a,b,c,d,e,f)
3148 static void _overlapped_transact_failure(unsigned line
, HANDLE caller
, void *write_buf
, DWORD write_size
,
3149 void *read_buf
, DWORD read_size
, DWORD expected_error
)
3151 OVERLAPPED overlapped
;
3154 memset(&overlapped
, 0, sizeof(overlapped
));
3155 overlapped
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
3156 res
= TransactNamedPipe(caller
, write_buf
, write_size
, read_buf
, read_size
, NULL
, &overlapped
);
3157 ok_(__FILE__
,line
)(!res
, "TransactNamedPipe succeeded\n");
3159 if (GetLastError() == ERROR_IO_PENDING
) /* win8+ */
3161 _test_overlapped_failure(line
, caller
, &overlapped
, expected_error
);
3165 ok_(__FILE__
,line
)(GetLastError() == expected_error
,
3166 "TransactNamedPipe returned error %lu, expected %lu\n",
3167 GetLastError(), expected_error
);
3168 CloseHandle(overlapped
.hEvent
);
3172 static void child_process_write_pipe(HANDLE pipe
)
3174 OVERLAPPED overlapped
;
3177 memset(buf
, 'x', sizeof(buf
));
3178 overlapped_write_async(pipe
, buf
, sizeof(buf
), &overlapped
);
3180 /* sleep until parent process terminates this process */
3184 static HANDLE
create_writepipe_process(HANDLE pipe
)
3186 STARTUPINFOA si
= { sizeof(si
) };
3187 PROCESS_INFORMATION info
;
3188 char **argv
, buf
[MAX_PATH
];
3191 winetest_get_mainargs(&argv
);
3192 sprintf(buf
, "\"%s\" pipe writepipe %Ix", argv
[0], (UINT_PTR
)pipe
);
3193 res
= CreateProcessA(NULL
, buf
, NULL
, NULL
, TRUE
, 0L, NULL
, NULL
, &si
, &info
);
3194 ok(res
, "CreateProcess failed: %lu\n", GetLastError());
3195 CloseHandle(info
.hThread
);
3197 return info
.hProcess
;
3200 static void create_overlapped_pipe(DWORD mode
, HANDLE
*client
, HANDLE
*server
)
3202 SECURITY_ATTRIBUTES sec_attr
= { sizeof(sec_attr
), NULL
, TRUE
};
3203 DWORD read_mode
= mode
& (PIPE_READMODE_BYTE
| PIPE_READMODE_MESSAGE
);
3204 OVERLAPPED overlapped
;
3207 *server
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
,
3208 PIPE_WAIT
| mode
, 1, 5000, 6000, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
3209 ok(*server
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed: %lu\n", GetLastError());
3210 test_signaled(*server
);
3212 memset(&overlapped
, 0, sizeof(overlapped
));
3213 overlapped
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
3214 res
= ConnectNamedPipe(*server
, &overlapped
);
3215 ok(!res
&& GetLastError() == ERROR_IO_PENDING
, "WriteFile returned %x(%lu)\n", res
, GetLastError());
3216 test_not_signaled(*server
);
3217 test_not_signaled(overlapped
.hEvent
);
3219 *client
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, &sec_attr
, OPEN_EXISTING
, FILE_FLAG_OVERLAPPED
, NULL
);
3220 ok(*client
!= INVALID_HANDLE_VALUE
, "CreateFile failed: %lu\n", GetLastError());
3222 res
= SetNamedPipeHandleState(*client
, &read_mode
, NULL
, NULL
);
3223 ok(res
, "SetNamedPipeHandleState failed: %lu\n", GetLastError());
3225 test_signaled(*client
);
3226 test_not_signaled(*server
);
3227 test_overlapped_result(*server
, &overlapped
, 0, FALSE
);
3230 static void test_overlapped_transport(BOOL msg_mode
, BOOL msg_read_mode
)
3232 OVERLAPPED overlapped
, overlapped2
;
3233 HANDLE server
, client
, flush
;
3239 DWORD create_flags
=
3240 (msg_mode
? PIPE_TYPE_MESSAGE
: PIPE_TYPE_BYTE
) |
3241 (msg_read_mode
? PIPE_READMODE_MESSAGE
: PIPE_READMODE_BYTE
);
3243 create_overlapped_pipe(create_flags
, &client
, &server
);
3245 trace("testing %s, %s server->client writes...\n",
3246 msg_mode
? "message mode" : "byte mode", msg_read_mode
? "message read" : "byte read");
3247 test_blocking_rw(server
, client
, 5000, msg_mode
, msg_read_mode
);
3248 trace("testing %s, %s client->server writes...\n",
3249 msg_mode
? "message mode" : "byte mode", msg_read_mode
? "message read" : "byte read");
3250 test_blocking_rw(client
, server
, 6000, msg_mode
, msg_read_mode
);
3252 CloseHandle(client
);
3253 CloseHandle(server
);
3255 /* close client with pending writes */
3256 memset(buf
, 0xaa, sizeof(buf
));
3257 create_overlapped_pipe(create_flags
, &client
, &server
);
3258 overlapped_write_async(server
, buf
, 7000, &overlapped
);
3259 flush
= test_flush_async(server
, ERROR_BROKEN_PIPE
);
3260 CloseHandle(client
);
3261 test_overlapped_failure(server
, &overlapped
, ERROR_BROKEN_PIPE
);
3262 test_flush_done(flush
);
3263 CloseHandle(server
);
3265 /* close server with pending writes */
3266 create_overlapped_pipe(create_flags
, &client
, &server
);
3267 overlapped_write_async(client
, buf
, 7000, &overlapped
);
3268 flush
= test_flush_async(client
, ERROR_BROKEN_PIPE
);
3269 CloseHandle(server
);
3270 test_overlapped_failure(client
, &overlapped
, ERROR_BROKEN_PIPE
);
3271 test_flush_done(flush
);
3272 CloseHandle(client
);
3274 /* disconnect with pending writes */
3275 create_overlapped_pipe(create_flags
, &client
, &server
);
3276 overlapped_write_async(client
, buf
, 7000, &overlapped
);
3277 overlapped_write_async(server
, buf
, 7000, &overlapped2
);
3278 flush
= test_flush_async(client
, ERROR_PIPE_NOT_CONNECTED
);
3279 res
= DisconnectNamedPipe(server
);
3280 ok(res
, "DisconnectNamedPipe failed: %lu\n", GetLastError());
3281 test_overlapped_failure(client
, &overlapped
, ERROR_PIPE_NOT_CONNECTED
);
3282 test_overlapped_failure(client
, &overlapped2
, ERROR_PIPE_NOT_CONNECTED
);
3283 test_flush_done(flush
);
3284 CloseHandle(server
);
3285 CloseHandle(client
);
3287 /* terminate process with pending write */
3288 create_overlapped_pipe(create_flags
, &client
, &server
);
3289 process
= create_writepipe_process(client
);
3290 /* successfully read part of write that is pending in child process */
3291 res
= ReadFile(server
, buf
, 10, &read_bytes
, NULL
);
3293 ok(res
, "ReadFile failed: %lu\n", GetLastError());
3295 ok(!res
&& GetLastError() == ERROR_MORE_DATA
, "ReadFile returned: %x %lu\n", res
, GetLastError());
3296 ok(read_bytes
== 10, "read_bytes = %lu\n", read_bytes
);
3297 TerminateProcess(process
, 0);
3298 wait_child_process(process
);
3299 /* after terminating process, there is no pending write and pipe buffer is empty */
3300 overlapped_read_async(server
, buf
, 10, &overlapped
);
3301 overlapped_write_sync(client
, buf
, 1);
3302 test_overlapped_result(server
, &overlapped
, 1, FALSE
);
3303 CloseHandle(process
);
3304 CloseHandle(server
);
3305 CloseHandle(client
);
3308 static void test_transact(HANDLE caller
, HANDLE callee
, DWORD write_buf_size
, DWORD read_buf_size
)
3310 OVERLAPPED overlapped
, overlapped2
, read_overlapped
, write_overlapped
;
3311 char buf
[10000], read_buf
[10000];
3313 memset(buf
, 0xaa, sizeof(buf
));
3315 /* simple transact call */
3316 overlapped_transact(caller
, (BYTE
*)"abc", 3, read_buf
, 100, &overlapped
);
3317 overlapped_write_sync(callee
, (BYTE
*)"test", 4);
3318 test_overlapped_result(caller
, &overlapped
, 4, FALSE
);
3319 ok(!memcmp(read_buf
, "test", 4), "unexpected read_buf\n");
3320 overlapped_read_sync(callee
, read_buf
, 1000, 3, FALSE
);
3321 ok(!memcmp(read_buf
, "abc", 3), "unexpected read_buf\n");
3323 /* transact fails if there is already data in read buffer */
3324 overlapped_write_sync(callee
, buf
, 1);
3325 overlapped_transact_failure(caller
, buf
, 2, read_buf
, 1, ERROR_PIPE_BUSY
);
3326 overlapped_read_sync(caller
, read_buf
, 1000, 1, FALSE
);
3328 /* transact doesn't block on write */
3329 overlapped_write_async(caller
, buf
, write_buf_size
+2000, &write_overlapped
);
3330 overlapped_transact(caller
, buf
, 2, read_buf
, 1, &overlapped
);
3331 test_not_signaled(overlapped
.hEvent
);
3332 overlapped_write_sync(callee
, buf
, 1);
3333 test_overlapped_result(caller
, &overlapped
, 1, FALSE
);
3334 overlapped_read_sync(callee
, read_buf
, sizeof(read_buf
), write_buf_size
+2000, FALSE
);
3335 test_overlapped_result(caller
, &write_overlapped
, write_buf_size
+2000, FALSE
);
3336 overlapped_read_sync(callee
, read_buf
, sizeof(read_buf
), 2, FALSE
);
3338 /* transact with already pending read */
3339 overlapped_read_async(callee
, read_buf
, 10, &read_overlapped
);
3340 overlapped_transact(caller
, buf
, 5, read_buf
, 6, &overlapped
);
3341 test_overlapped_result(callee
, &read_overlapped
, 5, FALSE
);
3342 test_not_signaled(overlapped
.hEvent
);
3343 overlapped_write_sync(callee
, buf
, 10);
3344 test_overlapped_result(caller
, &overlapped
, 6, TRUE
);
3345 overlapped_read_sync(caller
, read_buf
, sizeof(read_buf
), 4, FALSE
);
3347 /* 0-size messages */
3348 overlapped_transact(caller
, buf
, 5, read_buf
, 0, &overlapped
);
3349 overlapped_read_sync(callee
, read_buf
, sizeof(read_buf
), 5, FALSE
);
3350 overlapped_write_sync(callee
, buf
, 0);
3351 test_overlapped_result(caller
, &overlapped
, 0, FALSE
);
3353 overlapped_transact(caller
, buf
, 0, read_buf
, 0, &overlapped
);
3354 overlapped_read_sync(callee
, read_buf
, sizeof(read_buf
), 0, FALSE
);
3355 test_not_signaled(overlapped
.hEvent
);
3356 overlapped_write_sync(callee
, buf
, 0);
3357 test_overlapped_result(caller
, &overlapped
, 0, FALSE
);
3359 /* reply transact with another transact */
3360 overlapped_transact(caller
, buf
, 3, read_buf
, 100, &overlapped
);
3361 overlapped_read_sync(callee
, read_buf
, 1000, 3, FALSE
);
3362 overlapped_transact(callee
, buf
, 4, read_buf
, 100, &overlapped2
);
3363 test_overlapped_result(caller
, &overlapped
, 4, FALSE
);
3364 overlapped_write_sync(caller
, buf
, 1);
3365 test_overlapped_result(caller
, &overlapped2
, 1, FALSE
);
3367 if (!pCancelIoEx
) return;
3369 /* cancel keeps written data */
3370 overlapped_write_async(caller
, buf
, write_buf_size
+2000, &write_overlapped
);
3371 overlapped_transact(caller
, buf
, 2, read_buf
, 1, &overlapped
);
3372 test_not_signaled(overlapped
.hEvent
);
3373 cancel_overlapped(caller
, &overlapped
);
3374 overlapped_read_sync(callee
, read_buf
, sizeof(read_buf
), write_buf_size
+2000, FALSE
);
3375 test_overlapped_result(caller
, &write_overlapped
, write_buf_size
+2000, FALSE
);
3376 overlapped_read_sync(callee
, read_buf
, sizeof(read_buf
), 2, FALSE
);
3379 static void test_TransactNamedPipe(void)
3381 HANDLE client
, server
;
3384 create_overlapped_pipe(PIPE_TYPE_BYTE
, &client
, &server
);
3385 overlapped_transact_failure(client
, buf
, 2, buf
, 1, ERROR_BAD_PIPE
);
3386 CloseHandle(client
);
3387 CloseHandle(server
);
3389 create_overlapped_pipe(PIPE_TYPE_MESSAGE
| PIPE_READMODE_BYTE
, &client
, &server
);
3390 overlapped_transact_failure(client
, buf
, 2, buf
, 1, ERROR_BAD_PIPE
);
3391 CloseHandle(client
);
3392 CloseHandle(server
);
3394 trace("testing server->client transaction...\n");
3395 create_overlapped_pipe(PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
, &client
, &server
);
3396 test_transact(server
, client
, 5000, 6000);
3397 CloseHandle(client
);
3398 CloseHandle(server
);
3400 trace("testing client->server transaction...\n");
3401 create_overlapped_pipe(PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
, &client
, &server
);
3402 test_transact(client
, server
, 6000, 5000);
3403 CloseHandle(client
);
3404 CloseHandle(server
);
3407 static HANDLE
create_overlapped_server( OVERLAPPED
*overlapped
)
3412 pipe
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
, PIPE_READMODE_BYTE
| PIPE_WAIT
,
3413 1, 5000, 6000, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
3414 ok(pipe
!= INVALID_HANDLE_VALUE
, "got %lu\n", GetLastError());
3415 ret
= ConnectNamedPipe(pipe
, overlapped
);
3416 ok(!ret
&& GetLastError() == ERROR_IO_PENDING
, "got %lu\n", GetLastError());
3420 static void child_process_check_pid(DWORD server_pid
)
3422 DWORD current
= GetProcessId(GetCurrentProcess());
3427 pipe
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
3428 ok(pipe
!= INVALID_HANDLE_VALUE
, "got %lu\n", GetLastError());
3431 ret
= pGetNamedPipeClientProcessId(pipe
, &pid
);
3432 ok(ret
, "got %lu\n", GetLastError());
3433 ok(pid
== current
, "got %04lx\n", pid
);
3436 ret
= pGetNamedPipeServerProcessId(pipe
, &pid
);
3437 ok(ret
, "got %lu\n", GetLastError());
3438 ok(pid
== server_pid
, "got %04lx expected %04lx\n", pid
, server_pid
);
3442 static HANDLE
create_check_id_process(const char *verb
, DWORD id
)
3444 STARTUPINFOA si
= {sizeof(si
)};
3445 PROCESS_INFORMATION info
;
3446 char **argv
, buf
[MAX_PATH
];
3449 winetest_get_mainargs(&argv
);
3450 sprintf(buf
, "\"%s\" pipe %s %lx", argv
[0], verb
, id
);
3451 ret
= CreateProcessA(NULL
, buf
, NULL
, NULL
, TRUE
, 0, NULL
, NULL
, &si
, &info
);
3452 ok(ret
, "got %lu\n", GetLastError());
3453 CloseHandle(info
.hThread
);
3454 return info
.hProcess
;
3457 static void test_namedpipe_process_id(void)
3459 HANDLE client
, server
, process
;
3460 DWORD current
= GetProcessId(GetCurrentProcess());
3461 OVERLAPPED overlapped
;
3465 if (!pGetNamedPipeClientProcessId
)
3467 win_skip("GetNamedPipeClientProcessId not available\n");
3471 create_overlapped_pipe(PIPE_TYPE_BYTE
, &client
, &server
);
3473 SetLastError(0xdeadbeef);
3474 ret
= pGetNamedPipeClientProcessId(server
, NULL
);
3475 ok(!ret
, "success\n");
3476 todo_wine
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "got %lu\n", GetLastError());
3479 ret
= pGetNamedPipeClientProcessId(server
, &pid
);
3480 ok(ret
, "got %lu\n", GetLastError());
3481 ok(pid
== current
, "got %04lx expected %04lx\n", pid
, current
);
3484 ret
= pGetNamedPipeClientProcessId(client
, &pid
);
3485 ok(ret
, "got %lu\n", GetLastError());
3486 ok(pid
== current
, "got %04lx expected %04lx\n", pid
, current
);
3488 SetLastError(0xdeadbeef);
3489 ret
= pGetNamedPipeServerProcessId(server
, NULL
);
3490 ok(!ret
, "success\n");
3491 todo_wine
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "got %lu\n", GetLastError());
3494 ret
= pGetNamedPipeServerProcessId(client
, &pid
);
3495 ok(ret
, "got %lu\n", GetLastError());
3496 ok(pid
== current
, "got %04lx expected %04lx\n", pid
, current
);
3499 ret
= pGetNamedPipeServerProcessId(server
, &pid
);
3500 ok(ret
, "got %lu\n", GetLastError());
3501 ok(pid
== current
, "got %04lx expected %04lx\n", pid
, current
);
3503 /* closed client handle */
3504 CloseHandle(client
);
3506 ret
= pGetNamedPipeClientProcessId(server
, &pid
);
3507 ok(ret
, "got %lu\n", GetLastError());
3508 ok(pid
== current
, "got %04lx expected %04lx\n", pid
, current
);
3511 ret
= pGetNamedPipeServerProcessId(server
, &pid
);
3512 ok(ret
, "got %lu\n", GetLastError());
3513 ok(pid
== current
, "got %04lx expected %04lx\n", pid
, current
);
3514 CloseHandle(server
);
3516 /* disconnected server */
3517 create_overlapped_pipe(PIPE_TYPE_BYTE
, &client
, &server
);
3518 DisconnectNamedPipe(server
);
3520 SetLastError(0xdeadbeef);
3521 ret
= pGetNamedPipeClientProcessId(server
, &pid
);
3522 todo_wine
ok(!ret
, "success\n");
3523 todo_wine
ok(GetLastError() == ERROR_NOT_FOUND
, "got %lu\n", GetLastError());
3526 ret
= pGetNamedPipeServerProcessId(server
, &pid
);
3527 ok(ret
, "got %lu\n", GetLastError());
3528 ok(pid
== current
, "got %04lx expected %04lx\n", pid
, current
);
3530 SetLastError(0xdeadbeef);
3531 ret
= pGetNamedPipeClientProcessId(client
, &pid
);
3532 todo_wine
ok(!ret
, "success\n");
3533 todo_wine
ok(GetLastError() == ERROR_PIPE_NOT_CONNECTED
, "got %lu\n", GetLastError());
3535 SetLastError(0xdeadbeef);
3536 ret
= pGetNamedPipeServerProcessId(client
, &pid
);
3537 todo_wine
ok(!ret
, "success\n");
3538 todo_wine
ok(GetLastError() == ERROR_PIPE_NOT_CONNECTED
, "got %lu\n", GetLastError());
3539 CloseHandle(client
);
3540 CloseHandle(server
);
3542 /* closed server handle */
3543 create_overlapped_pipe(PIPE_TYPE_BYTE
, &client
, &server
);
3544 CloseHandle(server
);
3547 ret
= pGetNamedPipeClientProcessId(client
, &pid
);
3548 ok(ret
, "got %lu\n", GetLastError());
3549 ok(pid
== current
, "got %04lx expected %04lx\n", pid
, current
);
3552 ret
= pGetNamedPipeServerProcessId(client
, &pid
);
3553 ok(ret
, "got %lu\n", GetLastError());
3554 ok(pid
== current
, "got %04lx expected %04lx\n", pid
, current
);
3555 CloseHandle(client
);
3557 /* different process */
3558 memset(&overlapped
, 0, sizeof(overlapped
));
3559 overlapped
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
3560 server
= create_overlapped_server( &overlapped
);
3561 ok(server
!= INVALID_HANDLE_VALUE
, "got %lu\n", GetLastError());
3563 process
= create_check_id_process("checkpid", GetProcessId(GetCurrentProcess()));
3564 wait_child_process(process
);
3566 CloseHandle(overlapped
.hEvent
);
3567 CloseHandle(process
);
3568 CloseHandle(server
);
3571 static void child_process_check_session_id(DWORD server_id
)
3578 ProcessIdToSessionId(GetProcessId(GetCurrentProcess()), ¤t
);
3580 pipe
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
3581 ok(pipe
!= INVALID_HANDLE_VALUE
, "got %lu\n", GetLastError());
3584 ret
= pGetNamedPipeClientSessionId(pipe
, &id
);
3585 ok(ret
, "got %lu\n", GetLastError());
3586 ok(id
== current
, "got %04lx\n", id
);
3589 ret
= pGetNamedPipeServerSessionId(pipe
, &id
);
3590 ok(ret
, "got %lu\n", GetLastError());
3591 ok(id
== server_id
, "got %04lx expected %04lx\n", id
, server_id
);
3595 static void test_namedpipe_session_id(void)
3597 HANDLE client
, server
, process
;
3598 OVERLAPPED overlapped
;
3603 if (!pGetNamedPipeClientSessionId
)
3605 win_skip("GetNamedPipeClientSessionId not available\n");
3609 ProcessIdToSessionId(GetProcessId(GetCurrentProcess()), ¤t
);
3611 create_overlapped_pipe(PIPE_TYPE_BYTE
, &client
, &server
);
3613 if (0) /* crashes on recent Windows */
3615 SetLastError(0xdeadbeef);
3616 ret
= pGetNamedPipeClientSessionId(server
, NULL
);
3617 ok(!ret
, "success\n");
3621 ret
= pGetNamedPipeClientSessionId(server
, &id
);
3622 ok(ret
, "got %lu\n", GetLastError());
3623 ok(id
== current
, "got %lu expected %lu\n", id
, current
);
3626 ret
= pGetNamedPipeClientSessionId(client
, &id
);
3627 ok(ret
, "got %lu\n", GetLastError());
3628 ok(id
== current
, "got %lu expected %lu\n", id
, current
);
3630 SetLastError(0xdeadbeef);
3631 ret
= pGetNamedPipeServerSessionId(server
, NULL
);
3632 ok(!ret
, "success\n");
3633 todo_wine
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "got %lu\n", GetLastError());
3636 ret
= pGetNamedPipeServerSessionId(client
, &id
);
3637 ok(ret
, "got %lu\n", GetLastError());
3638 ok(id
== current
, "got %lu expected %lu\n", id
, current
);
3641 ret
= pGetNamedPipeServerSessionId(server
, &id
);
3642 ok(ret
, "got %lu\n", GetLastError());
3643 ok(id
== current
, "got %lu expected %lu\n", id
, current
);
3645 /* closed client handle */
3646 CloseHandle(client
);
3649 ret
= pGetNamedPipeClientSessionId(server
, &id
);
3650 ok(ret
, "got %lu\n", GetLastError());
3651 ok(id
== current
, "got %04lx expected %04lx\n", id
, current
);
3654 ret
= pGetNamedPipeServerSessionId(server
, &id
);
3655 ok(ret
, "got %lu\n", GetLastError());
3656 ok(id
== current
, "got %04lx expected %04lx\n", id
, current
);
3657 CloseHandle(server
);
3659 /* disconnected server */
3660 create_overlapped_pipe(PIPE_TYPE_BYTE
, &client
, &server
);
3661 DisconnectNamedPipe(server
);
3663 SetLastError(0xdeadbeef);
3664 ret
= pGetNamedPipeClientSessionId(server
, &id
);
3665 todo_wine
ok(!ret
, "success\n");
3666 todo_wine
ok(GetLastError() == ERROR_NOT_FOUND
, "got %lu\n", GetLastError());
3669 ret
= pGetNamedPipeServerSessionId(server
, &id
);
3670 ok(ret
, "got %lu\n", GetLastError());
3671 ok(id
== current
, "got %04lx expected %04lx\n", id
, current
);
3673 SetLastError(0xdeadbeef);
3674 ret
= pGetNamedPipeClientSessionId(client
, &id
);
3675 todo_wine
ok(!ret
, "success\n");
3676 todo_wine
ok(GetLastError() == ERROR_PIPE_NOT_CONNECTED
, "got %lu\n", GetLastError());
3678 SetLastError(0xdeadbeef);
3679 ret
= pGetNamedPipeServerSessionId(client
, &id
);
3680 todo_wine
ok(!ret
, "success\n");
3681 todo_wine
ok(GetLastError() == ERROR_PIPE_NOT_CONNECTED
, "got %lu\n", GetLastError());
3682 CloseHandle(client
);
3683 CloseHandle(server
);
3685 /* closed server handle */
3686 create_overlapped_pipe(PIPE_TYPE_BYTE
, &client
, &server
);
3687 CloseHandle(server
);
3690 ret
= pGetNamedPipeClientSessionId(client
, &id
);
3691 ok(ret
, "got %lu\n", GetLastError());
3692 ok(id
== current
, "got %04lx expected %04lx\n", id
, current
);
3695 ret
= pGetNamedPipeServerSessionId(client
, &id
);
3696 ok(ret
, "got %lu\n", GetLastError());
3697 ok(id
== current
, "got %04lx expected %04lx\n", id
, current
);
3698 CloseHandle(client
);
3700 /* different process */
3701 memset(&overlapped
, 0, sizeof(overlapped
));
3702 overlapped
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
3703 server
= create_overlapped_server( &overlapped
);
3704 ok(server
!= INVALID_HANDLE_VALUE
, "got %lu\n", GetLastError());
3706 process
= create_check_id_process("checksessionid", current
);
3707 wait_child_process(process
);
3709 CloseHandle(overlapped
.hEvent
);
3710 CloseHandle(process
);
3711 CloseHandle(server
);
3714 static void test_multiple_instances(void)
3716 HANDLE server
[4], client
;
3723 win_skip("Skipping multiple instance tests on too old Windows\n");
3727 for (i
= 0; i
< ARRAY_SIZE(server
); i
++)
3729 server
[i
] = CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
3730 PIPE_READMODE_BYTE
| PIPE_WAIT
, ARRAY_SIZE(server
), 1024, 1024,
3731 NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
3732 ok(server
[i
] != INVALID_HANDLE_VALUE
, "got invalid handle\n");
3735 client
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3736 ok(client
!= INVALID_HANDLE_VALUE
, "got invalid handle\n");
3738 /* Show that this has connected to server[0] not any other one */
3740 memset(&ov
, 0, sizeof(ov
));
3741 ret
= ConnectNamedPipe(server
[2], &ov
);
3742 ok(ret
== FALSE
, "got %d\n", ret
);
3743 ok(GetLastError() == ERROR_IO_PENDING
, "got %ld\n", GetLastError());
3745 memset(&ov
, 0, sizeof(ov
));
3746 ret
= ConnectNamedPipe(server
[0], &ov
);
3747 ok(ret
== FALSE
, "got %d\n", ret
);
3748 ok(GetLastError() == ERROR_PIPE_CONNECTED
, "got %ld\n", GetLastError());
3750 CloseHandle(client
);
3752 /* The next connected server is server[1], doesn't matter that server[2] has pending listeners */
3754 client
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3755 ok(client
!= INVALID_HANDLE_VALUE
, "got invalid handle\n");
3757 memset(&ov
, 0, sizeof(ov
));
3758 ret
= ConnectNamedPipe(server
[2], &ov
);
3759 ok(ret
== FALSE
, "got %d\n", ret
);
3760 ok(GetLastError() == ERROR_IO_PENDING
, "got %ld\n", GetLastError());
3762 memset(&ov
, 0, sizeof(ov
));
3763 ret
= ConnectNamedPipe(server
[1], &ov
);
3764 ok(ret
== FALSE
, "got %d\n", ret
);
3765 ok(GetLastError() == ERROR_PIPE_CONNECTED
, "got %ld\n", GetLastError());
3767 CloseHandle(client
);
3769 /* server[2] is connected next */
3771 client
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3772 ok(client
!= INVALID_HANDLE_VALUE
, "got invalid handle\n");
3774 memset(&ov
, 0, sizeof(ov
));
3775 ret
= ConnectNamedPipe(server
[2], &ov
);
3776 ok(ret
== FALSE
, "got %d\n", ret
);
3777 ok(GetLastError() == ERROR_PIPE_CONNECTED
, "got %ld\n", GetLastError());
3779 CloseHandle(client
);
3781 /* Disconnect in order server[0] and server[2] */
3783 DisconnectNamedPipe(server
[0]);
3784 DisconnectNamedPipe(server
[2]);
3786 /* Put into listening state server[2] and server[0] */
3788 memset(&ov
, 0, sizeof(ov
));
3789 ret
= ConnectNamedPipe(server
[2], &ov
);
3790 ok(ret
== FALSE
, "got %d\n", ret
);
3791 ok(GetLastError() == ERROR_IO_PENDING
, "got %ld\n", GetLastError());
3793 memset(&ov
, 0, sizeof(ov
));
3794 ret
= ConnectNamedPipe(server
[0], &ov
);
3795 ok(ret
== FALSE
, "got %d\n", ret
);
3796 ok(GetLastError() == ERROR_IO_PENDING
, "got %ld\n", GetLastError());
3798 /* server[3] is connected next */
3800 client
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3801 ok(client
!= INVALID_HANDLE_VALUE
, "got invalid handle\n");
3803 memset(&ov
, 0, sizeof(ov
));
3804 ret
= ConnectNamedPipe(server
[3], &ov
);
3805 ok(ret
== FALSE
, "got %d\n", ret
);
3806 ok(GetLastError() == ERROR_PIPE_CONNECTED
, "got %ld\n", GetLastError());
3808 CloseHandle(client
);
3810 /* server[2], which stasted listening first, will be connected next */
3812 client
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3813 ok(client
!= INVALID_HANDLE_VALUE
, "got invalid handle\n");
3815 memset(&ov
, 0, sizeof(ov
));
3816 ret
= ConnectNamedPipe(server
[2], &ov
);
3817 ok(ret
== FALSE
, "got %d\n", ret
);
3818 ok(GetLastError() == ERROR_PIPE_CONNECTED
, "got %ld\n", GetLastError());
3820 memset(&ov
, 0, sizeof(ov
));
3821 ret
= ConnectNamedPipe(server
[0], &ov
);
3822 ok(ret
== FALSE
, "got %d\n", ret
);
3823 ok(GetLastError() == ERROR_IO_PENDING
, "got %ld\n", GetLastError());
3825 CloseHandle(client
);
3827 /* Finally server[0] is connected */
3829 client
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3830 ok(client
!= INVALID_HANDLE_VALUE
, "got invalid handle\n");
3832 memset(&ov
, 0, sizeof(ov
));
3833 ret
= ConnectNamedPipe(server
[0], &ov
);
3834 ok(ret
== FALSE
, "got %d\n", ret
);
3835 ok(GetLastError() == ERROR_PIPE_CONNECTED
, "got %ld\n", GetLastError());
3837 CloseHandle(client
);
3839 /* No more listening pipes available */
3840 DisconnectNamedPipe(server
[0]);
3841 client
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3842 ok(client
== INVALID_HANDLE_VALUE
&& GetLastError() == ERROR_PIPE_BUSY
, "got %p(%lu)\n", client
, GetLastError());
3844 for (i
= 0; i
< ARRAY_SIZE(server
); i
++)
3846 DisconnectNamedPipe(server
[i
]);
3847 CloseHandle(server
[i
]);
3851 static DWORD WINAPI
wait_pipe_proc(void *arg
)
3854 ret
= WaitNamedPipeA(PIPENAME
, 1000);
3855 ok(ret
, "WaitNamedPipe failed (%lu)\n", GetLastError());
3859 static HANDLE
async_wait_pipe(void)
3864 thread
= CreateThread(NULL
, 0, wait_pipe_proc
, NULL
, 0, NULL
);
3865 ok(thread
!= NULL
, "CreateThread failed: %lu\n", GetLastError());
3867 ret
= WaitNamedPipeA(PIPENAME
, 1);
3868 ok(!ret
&& GetLastError() == ERROR_SEM_TIMEOUT
, "WaitNamedPipe failed %x(%lu)\n", ret
, GetLastError());
3873 static void test_wait_pipe(void)
3875 HANDLE server
[2], client
, wait
;
3880 ret
= WaitNamedPipeA(PIPENAME
, 0);
3881 ok(!ret
&& GetLastError() == ERROR_FILE_NOT_FOUND
, "WaitNamedPipe failed %x(%lu)\n", ret
, GetLastError());
3883 server
[0] = CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
3884 PIPE_READMODE_BYTE
| PIPE_WAIT
, ARRAY_SIZE(server
), 1024, 1024,
3885 NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
3886 ok(server
[0] != INVALID_HANDLE_VALUE
, "got invalid handle\n");
3888 ret
= WaitNamedPipeA(PIPENAME
, 1);
3889 ok(ret
, "WaitNamedPipe failed (%lu)\n", GetLastError());
3891 client
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3892 ok(client
!= INVALID_HANDLE_VALUE
, "got invalid handle\n");
3894 /* Creating a new pipe server wakes waiters */
3895 wait
= async_wait_pipe();
3896 server
[1] = CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
3897 PIPE_READMODE_BYTE
| PIPE_WAIT
, ARRAY_SIZE(server
), 1024, 1024,
3898 NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
3899 ok(server
[1] != INVALID_HANDLE_VALUE
, "got invalid handle\n");
3901 res
= WaitForSingleObject(wait
, 100);
3902 ok(res
== WAIT_OBJECT_0
, "WaitForSingleObject returned %lu\n", res
);
3905 CloseHandle(server
[1]);
3907 CloseHandle(client
);
3908 ret
= DisconnectNamedPipe(server
[0]);
3909 ok(ret
, "DisconnectNamedPipe failed (%lu)\n", GetLastError());
3911 /* Putting pipe server into waiting listening state wakes waiters */
3912 wait
= async_wait_pipe();
3913 memset(&ov
, 0, sizeof(ov
));
3914 ov
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
3915 ret
= ConnectNamedPipe(server
[0], &ov
);
3916 ok(ret
== FALSE
, "got %d\n", ret
);
3917 ok(GetLastError() == ERROR_IO_PENDING
, "got %ld\n", GetLastError());
3919 res
= WaitForSingleObject(wait
, 100);
3920 ok(res
== WAIT_OBJECT_0
, "WaitForSingleObject returned %lu\n", res
);
3921 CloseHandle(server
[0]);
3923 res
= WaitForSingleObject(ov
.hEvent
, 0);
3924 ok(res
== WAIT_OBJECT_0
, "WaitForSingleObject returned %lu\n", res
);
3925 CloseHandle(ov
.hEvent
);
3928 static void test_nowait(DWORD pipe_type
)
3930 HANDLE piperead
, pipewrite
, file
;
3933 char readbuf
[32768];
3934 static const char teststring
[] = "bits";
3936 /* CreateNamedPipe with PIPE_NOWAIT, and read from empty pipe */
3937 piperead
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
,
3938 /* dwPipeMode */ pipe_type
| PIPE_NOWAIT
,
3939 /* nMaxInstances */ 1,
3940 /* nOutBufSize */ 512,
3941 /* nInBufSize */ 512,
3942 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
3943 /* lpSecurityAttrib */ NULL
);
3944 ok(piperead
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
3945 pipewrite
= CreateFileA(PIPENAME
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3946 ok(pipewrite
!= INVALID_HANDLE_VALUE
, "CreateFileA failed\n");
3947 memset(&ol
, 0, sizeof(ol
));
3948 ol
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
3949 SetLastError(0xdeadbeef);
3950 ok(ReadFile(piperead
, readbuf
, sizeof(readbuf
), &read
, &ol
) == FALSE
, "ReadFile should fail\n");
3951 ok(GetLastError() == ERROR_NO_DATA
, "got %ld should be ERROR_NO_DATA\n", GetLastError());
3952 if (GetLastError() == ERROR_IO_PENDING
)
3955 /* test a small write/read */
3956 ok(WriteFile(pipewrite
, teststring
, sizeof(teststring
), &write
, NULL
), "WriteFile should succeed\n");
3957 ok(ReadFile(piperead
, readbuf
, sizeof(readbuf
), &read
, &ol
), "ReadFile should succeed\n");
3958 ok(read
== write
, "read/write bytes should match\n");
3959 ok(CloseHandle(ol
.hEvent
), "CloseHandle for the event failed\n");
3960 ok(CloseHandle(pipewrite
), "CloseHandle for the write pipe failed\n");
3961 ok(CloseHandle(piperead
), "CloseHandle for the read pipe failed\n");
3964 /* create write side with PIPE_NOWAIT, read side PIPE_WAIT, and test writes */
3965 pipewrite
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
,
3966 /* dwPipeMode */ pipe_type
| PIPE_NOWAIT
,
3967 /* nMaxInstances */ 1,
3968 /* nOutBufSize */ 512,
3969 /* nInBufSize */ 512,
3970 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
3971 /* lpSecurityAttrib */ NULL
);
3972 ok(pipewrite
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
3973 piperead
= CreateFileA(PIPENAME
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_OVERLAPPED
, 0);
3974 ok(piperead
!= INVALID_HANDLE_VALUE
, "CreateFileA failed\n");
3975 memset(&ol
, 0, sizeof(ol
));
3976 ol
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
3977 memset(&ol2
, 0, sizeof(ol2
));
3978 ol2
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
3980 /* write one byte larger than the buffer size, should fail */
3981 SetLastError(0xdeadbeef);
3982 ok(WriteFile(pipewrite
, readbuf
, 513, &write
, &ol
), "WriteFile should succeed\n");
3983 /* WriteFile only documents that 'write < sizeof(readbuf)' for this case, but Windows
3984 * doesn't seem to do partial writes ('write == 0' always)
3986 ok(write
< sizeof(readbuf
), "WriteFile should fail to write the whole buffer\n");
3987 ok(write
== 0, "WriteFile doesn't do partial writes here\n");
3988 if (GetLastError() == ERROR_IO_PENDING
)
3991 /* overlapped read of 32768, non-blocking write of 512 */
3992 SetLastError(0xdeadbeef);
3993 ok(ReadFile(piperead
, readbuf
, sizeof(readbuf
), &read
, &ol2
) == FALSE
, "ReadFile should fail\n");
3994 ok(GetLastError() == ERROR_IO_PENDING
, "got %ld should be ERROR_IO_PENDING\n", GetLastError());
3995 ok(WriteFile(pipewrite
, teststring
, sizeof(teststring
), &write
, &ol
), "WriteFile should succeed\n");
3996 ok(write
== sizeof(teststring
), "got %ld\n", write
);
3997 ok(GetOverlappedResult(piperead
, &ol2
, &read
, FALSE
), "GetOverlappedResult should succeed\n");
3998 ok(read
== sizeof(teststring
), "got %ld\n", read
);
3999 if (GetOverlappedResult(piperead
, &ol2
, &read
, FALSE
) == FALSE
)
4002 /* overlapped read of 32768, non-blocking write of 513 */
4003 SetLastError(0xdeadbeef);
4004 ok(ReadFile(piperead
, readbuf
, sizeof(readbuf
), &read
, &ol2
) == FALSE
, "ReadFile should fail\n");
4005 ok(GetLastError() == ERROR_IO_PENDING
, "got %ld should be ERROR_IO_PENDING\n", GetLastError());
4006 ok(WriteFile(pipewrite
, readbuf
, 513, &write
, &ol
), "WriteFile should succeed\n");
4007 ok(write
== 513, "got %ld, write should be %d\n", write
, 513);
4008 ok(GetOverlappedResult(piperead
, &ol2
, &read
, FALSE
), "GetOverlappedResult should succeed\n");
4009 ok(read
== 513, "got %ld, read should be %d\n", read
, 513);
4010 if (GetOverlappedResult(piperead
, &ol2
, &read
, FALSE
) == FALSE
)
4013 /* overlapped read of 1 byte, non-blocking write of 513 bytes */
4014 SetLastError(0xdeadbeef);
4015 ok(ReadFile(piperead
, readbuf
, 1, &read
, &ol2
) == FALSE
, "ReadFile should fail\n");
4016 ok(GetLastError() == ERROR_IO_PENDING
, "got %ld should be ERROR_IO_PENDING\n", GetLastError());
4017 ok(WriteFile(pipewrite
, readbuf
, 513, &write
, &ol
), "WriteFile should succeed\n");
4018 ok(write
== 513, "got %ld, write should be %d\n", write
, 513);
4019 ok(GetOverlappedResult(piperead
, &ol2
, &read
, FALSE
), "GetOverlappedResult should succeed\n");
4020 ok(read
== 1, "got %ld, read should be %d\n", read
, 1);
4021 if (GetOverlappedResult(piperead
, &ol2
, &read
, FALSE
) == FALSE
)
4023 /* read the remaining 512 bytes */
4024 SetLastError(0xdeadbeef);
4025 ok(ReadFile(piperead
, readbuf
, sizeof(readbuf
), &read
, &ol2
), "ReadFile should succeed\n");
4026 ok(read
== 512, "got %ld, write should be %d\n", write
, 512);
4027 if (GetOverlappedResult(piperead
, &ol2
, &read
, FALSE
) == FALSE
)
4030 /* overlapped read of 1 byte, non-blocking write of 514 bytes */
4031 SetLastError(0xdeadbeef);
4032 ok(ReadFile(piperead
, readbuf
, 1, &read
, &ol2
) == FALSE
, "ReadFile should fail\n");
4033 ok(GetLastError() == ERROR_IO_PENDING
, "got %ld should be ERROR_IO_PENDING\n", GetLastError());
4034 ok(WriteFile(pipewrite
, readbuf
, 514, &write
, &ol
), "WriteFile should succeed\n");
4035 if (pipe_type
== PIPE_TYPE_MESSAGE
)
4038 ok(write
== 0, "got %ld\n", write
);
4040 ok(!GetOverlappedResult(piperead
, &ol2
, &read
, FALSE
), "GetOverlappedResult should fail\n");
4042 ok(GetLastError() == ERROR_IO_INCOMPLETE
, "got %ld should be ERROR_IO_PENDING\n", GetLastError());
4044 ok(read
== 0, "got %ld, read should be %d\n", read
, 1);
4048 ok(write
== 1, "got %ld\n", write
);
4049 ok(GetOverlappedResult(piperead
, &ol2
, &read
, FALSE
), "GetOverlappedResult should fail\n");
4050 ok(read
== 1, "got %ld, read should be %d\n", read
, 1);
4052 if (GetOverlappedResult(piperead
, &ol2
, &read
, FALSE
) == FALSE
)
4055 /* write the exact buffer size, should succeed */
4056 SetLastError(0xdeadbeef);
4057 ok(WriteFile(pipewrite
, readbuf
, 512, &write
, &ol
), "WriteFile should succeed\n");
4058 ok(write
== 512, "WriteFile should write the whole buffer\n");
4059 if (GetLastError() == ERROR_IO_PENDING
)
4062 ok(CloseHandle(ol
.hEvent
), "CloseHandle for the event failed\n");
4063 ok(CloseHandle(ol2
.hEvent
), "CloseHandle for the event failed\n");
4064 ok(CloseHandle(pipewrite
), "CloseHandle for the write pipe failed\n");
4065 ok(CloseHandle(piperead
), "CloseHandle for the read pipe failed\n");
4068 /* CreateNamedPipe with PIPE_NOWAIT, test ConnectNamedPipe */
4069 pipewrite
= CreateNamedPipeA(PIPENAME
, FILE_FLAG_OVERLAPPED
| PIPE_ACCESS_DUPLEX
,
4070 /* dwPipeMode */ pipe_type
| PIPE_NOWAIT
,
4071 /* nMaxInstances */ 1,
4072 /* nOutBufSize */ 512,
4073 /* nInBufSize */ 512,
4074 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT
,
4075 /* lpSecurityAttrib */ NULL
);
4076 ok(pipewrite
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed\n");
4077 memset(&ol
, 0, sizeof(ol
));
4078 ol
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
4079 SetLastError(0xdeadbeef);
4080 ok(ConnectNamedPipe(pipewrite
, &ol
) == FALSE
, "ConnectNamedPipe should fail\n");
4081 ok(GetLastError() == ERROR_PIPE_LISTENING
, "got %ld should be ERROR_PIPE_LISTENING\n", GetLastError());
4082 if (GetLastError() == ERROR_IO_PENDING
)
4083 CancelIo(pipewrite
);
4085 /* connect and disconnect, then test ConnectNamedPipe again */
4086 file
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
4087 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFileA failed\n");
4088 ok(CloseHandle(file
), "CloseHandle failed\n");
4089 SetLastError(0xdeadbeef);
4090 ok(ConnectNamedPipe(pipewrite
,&ol
) == FALSE
, "ConnectNamedPipe should fail\n");
4091 ok(GetLastError() == ERROR_NO_DATA
, "got %ld should be ERROR_NO_DATA\n", GetLastError());
4092 if (GetLastError() == ERROR_IO_PENDING
)
4093 CancelIo(pipewrite
);
4095 /* call DisconnectNamedPipe and test ConnectNamedPipe again */
4096 ok(DisconnectNamedPipe(pipewrite
) == TRUE
, "DisconnectNamedPipe should succeed\n");
4097 SetLastError(0xdeadbeef);
4098 ok(ConnectNamedPipe(pipewrite
,&ol
) == FALSE
, "ConnectNamedPipe should fail\n");
4099 ok(GetLastError() == ERROR_PIPE_LISTENING
, "got %ld should be ERROR_PIPE_LISTENING\n", GetLastError());
4100 if (GetLastError() == ERROR_IO_PENDING
)
4101 CancelIo(pipewrite
);
4102 ok(CloseHandle(ol
.hEvent
), "CloseHandle for the event failed\n");
4103 ok(CloseHandle(pipewrite
), "CloseHandle for the write pipe failed\n");
4106 static void test_GetOverlappedResultEx(void)
4108 HANDLE client
, server
;
4114 if (!pGetOverlappedResultEx
)
4116 win_skip("GetOverlappedResultEx() is not available\n");
4120 create_overlapped_pipe(PIPE_TYPE_BYTE
, &client
, &server
);
4122 overlapped_write_async(client
, buffer
, sizeof(buffer
), &ovl
);
4124 user_apc_ran
= FALSE
;
4125 QueueUserAPC(user_apc
, GetCurrentThread(), 0);
4127 SetLastError(0xdeadbeef);
4128 ret
= pGetOverlappedResultEx(client
, &ovl
, &ret_size
, 0, FALSE
);
4129 ok(!ret
, "expected failure\n");
4130 ok(GetLastError() == ERROR_IO_INCOMPLETE
, "wrong error %lu\n", GetLastError());
4131 ok(!user_apc_ran
, "APC should not have run\n");
4133 SetLastError(0xdeadbeef);
4134 ret
= pGetOverlappedResultEx(client
, &ovl
, &ret_size
, 0, TRUE
);
4135 ok(!ret
, "expected failure\n");
4136 ok(GetLastError() == ERROR_IO_INCOMPLETE
, "wrong error %lu\n", GetLastError());
4137 ok(!user_apc_ran
, "APC should not have run\n");
4139 SetLastError(0xdeadbeef);
4140 ret
= pGetOverlappedResultEx(client
, &ovl
, &ret_size
, 10, FALSE
);
4141 ok(!ret
, "expected failure\n");
4142 ok(GetLastError() == WAIT_TIMEOUT
, "wrong error %lu\n", GetLastError());
4143 ok(!user_apc_ran
, "APC should not have run\n");
4145 SetLastError(0xdeadbeef);
4146 ret
= pGetOverlappedResultEx(client
, &ovl
, &ret_size
, 10, TRUE
);
4147 ok(!ret
, "expected failure\n");
4148 ok(GetLastError() == WAIT_IO_COMPLETION
, "wrong error %lu\n", GetLastError());
4149 ok(user_apc_ran
, "APC should have run\n");
4151 CloseHandle(ovl
.hEvent
);
4153 CloseHandle(client
);
4154 CloseHandle(server
);
4157 static void child_process_exit_process_async(DWORD parent_pid
, HANDLE parent_pipe
)
4159 OVERLAPPED overlapped
= {0};
4160 static char buffer
[1];
4161 HANDLE parent
, pipe
;
4164 parent
= OpenProcess(PROCESS_DUP_HANDLE
, FALSE
, parent_pid
);
4165 ok(!!parent
, "got parent %p\n", parent
);
4167 ret
= DuplicateHandle(parent
, parent_pipe
, GetCurrentProcess(), &pipe
, 0,
4168 FALSE
, DUPLICATE_SAME_ACCESS
| DUPLICATE_CLOSE_SOURCE
);
4169 ok(ret
, "got error %lu\n", GetLastError());
4171 overlapped
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
4173 ret
= ReadFile(pipe
, buffer
, sizeof(buffer
), NULL
, &overlapped
);
4174 ok(!ret
, "expected failure\n");
4175 ok(GetLastError() == ERROR_IO_PENDING
, "got error %lu\n", GetLastError());
4177 /* exit without closing the pipe handle */
4180 static void test_exit_process_async(void)
4182 HANDLE client
, server
, port
;
4183 OVERLAPPED
*overlapped
;
4184 PROCESS_INFORMATION pi
;
4185 STARTUPINFOA si
= {0};
4192 winetest_get_mainargs(&argv
);
4194 create_overlapped_pipe(PIPE_TYPE_BYTE
, &client
, &server
);
4195 port
= CreateIoCompletionPort(client
, NULL
, 123, 0);
4197 sprintf(cmdline
, "%s pipe exit_process_async %lx %p", argv
[0], GetCurrentProcessId(), client
);
4198 ret
= CreateProcessA(NULL
, cmdline
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &si
, &pi
);
4199 ok(ret
, "got error %lu\n", GetLastError());
4200 ret
= WaitForSingleObject(pi
.hProcess
, 1000);
4201 ok(!ret
, "wait timed out\n");
4202 CloseHandle(pi
.hThread
);
4203 CloseHandle(pi
.hProcess
);
4207 ret
= GetQueuedCompletionStatus(port
, &size
, &key
, &overlapped
, 1000);
4208 ok(!ret
, "expected failure\n");
4209 ok(GetLastError() == ERROR_OPERATION_ABORTED
, "got error %lu\n", GetLastError());
4210 ok(!size
, "got size %lu\n", size
);
4211 ok(key
== 123, "got key %Iu\n", key
);
4214 CloseHandle(server
);
4217 static DWORD CALLBACK
synchronousIoThreadMain(void *arg
)
4223 SetLastError(0xdeadbeef);
4224 ret
= ConnectNamedPipe(pipe
, NULL
);
4225 ok(!ret
, "expected failure\n");
4226 ok(GetLastError() == ERROR_OPERATION_ABORTED
, "got error %lu\n", GetLastError());
4230 static DWORD CALLBACK
synchronousIoThreadMain2(void *arg
)
4237 memset(&ov
, 0, sizeof(ov
));
4238 ov
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
4239 SetLastError(0xdeadbeef);
4240 ret
= ConnectNamedPipe(pipe
, &ov
);
4241 ok(!ret
, "expected failure\n");
4242 ok(GetLastError() == ERROR_IO_PENDING
, "got error %lu\n", GetLastError());
4243 ret
= WaitForSingleObject(ov
.hEvent
, 1000);
4244 ok(ret
== WAIT_OBJECT_0
, "WaitForSingleObject returned %u\n", ret
);
4245 CloseHandle(ov
.hEvent
);
4249 static void test_CancelSynchronousIo(void)
4258 SetLastError(0xdeadbeef);
4259 res
= pCancelSynchronousIo((HANDLE
)0xdeadbeef);
4260 ok(!res
, "CancelSynchronousIo succeeded unexpectedly\n");
4261 ok(GetLastError() == ERROR_INVALID_HANDLE
,
4262 "In CancelSynchronousIo failure, expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError());
4264 SetLastError(0xdeadbeef);
4265 res
= pCancelSynchronousIo(GetCurrentThread());
4266 ok(!res
, "CancelSynchronousIo succeeded unexpectedly\n");
4267 ok(GetLastError() == ERROR_NOT_FOUND
,
4268 "In CancelSynchronousIo failure, expected ERROR_NOT_FOUND, got %ld\n", GetLastError());
4270 /* synchronous i/o */
4271 pipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
,
4272 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
4273 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
4274 ok(pipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %lu\n", GetLastError());
4275 thread
= CreateThread(NULL
, 0, synchronousIoThreadMain
, pipe
, 0, NULL
);
4276 /* wait for I/O to start, which transitions the pipe handle from signaled to nonsignaled state. */
4277 while ((wait
= WaitForSingleObject(pipe
, 0)) == WAIT_OBJECT_0
) Sleep(1);
4278 ok(wait
== WAIT_TIMEOUT
, "WaitForSingleObject returned %lu (error %lu)\n", wait
, GetLastError());
4279 SetLastError(0xdeadbeef);
4280 res
= pCancelSynchronousIo(thread
);
4281 ok(res
, "CancelSynchronousIo failed with error %ld\n", GetLastError());
4282 ok(GetLastError() == 0xdeadbeef,
4283 "In CancelSynchronousIo failure, expected 0xdeadbeef got %ld\n", GetLastError());
4284 wait
= WaitForSingleObject(thread
, 1000);
4285 ok(wait
== WAIT_OBJECT_0
, "WaitForSingleObject returned %lx\n", wait
);
4286 CloseHandle(thread
);
4289 /* asynchronous i/o */
4290 pipe
= CreateNamedPipeA(PIPENAME
, PIPE_ACCESS_DUPLEX
| FILE_FLAG_OVERLAPPED
,
4291 PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
| PIPE_WAIT
,
4292 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
4293 ok(pipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipe failed with %lu\n", GetLastError());
4294 thread
= CreateThread(NULL
, 0, synchronousIoThreadMain2
, pipe
, 0, NULL
);
4295 /* wait for I/O to start, which transitions the pipe handle from signaled to nonsignaled state. */
4296 while ((wait
= WaitForSingleObject(pipe
, 0)) == WAIT_OBJECT_0
) Sleep(1);
4297 ok(wait
== WAIT_TIMEOUT
, "WaitForSingleObject returned %lu (error %lu)\n", wait
, GetLastError());
4298 SetLastError(0xdeadbeef);
4299 res
= pCancelSynchronousIo(thread
);
4300 ok(!res
, "CancelSynchronousIo succeeded unexpectedly\n");
4301 ok(GetLastError() == ERROR_NOT_FOUND
,
4302 "In CancelSynchronousIo failure, expected ERROR_NOT_FOUND, got %ld\n", GetLastError());
4303 file
= CreateFileA(PIPENAME
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
4304 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFile failed (%ld)\n", GetLastError());
4305 WaitForSingleObject(thread
, INFINITE
);
4306 CloseHandle(thread
);
4317 hmod
= GetModuleHandleA("advapi32.dll");
4318 pDuplicateTokenEx
= (void *) GetProcAddress(hmod
, "DuplicateTokenEx");
4319 hmod
= GetModuleHandleA("kernel32.dll");
4320 pCancelIoEx
= (void *) GetProcAddress(hmod
, "CancelIoEx");
4321 pCancelSynchronousIo
= (void *) GetProcAddress(hmod
, "CancelSynchronousIo");
4322 pGetNamedPipeClientProcessId
= (void *) GetProcAddress(hmod
, "GetNamedPipeClientProcessId");
4323 pGetNamedPipeServerProcessId
= (void *) GetProcAddress(hmod
, "GetNamedPipeServerProcessId");
4324 pGetNamedPipeClientSessionId
= (void *) GetProcAddress(hmod
, "GetNamedPipeClientSessionId");
4325 pGetNamedPipeServerSessionId
= (void *) GetProcAddress(hmod
, "GetNamedPipeServerSessionId");
4326 pGetOverlappedResultEx
= (void *)GetProcAddress(hmod
, "GetOverlappedResultEx");
4328 argc
= winetest_get_mainargs(&argv
);
4332 if (!strcmp(argv
[2], "writepipe"))
4335 sscanf(argv
[3], "%lx", &handle
);
4336 child_process_write_pipe(ULongToHandle(handle
));
4339 if (!strcmp(argv
[2], "checkpid"))
4341 DWORD pid
= GetProcessId(GetCurrentProcess());
4342 sscanf(argv
[3], "%lx", &pid
);
4343 child_process_check_pid(pid
);
4346 if (!strcmp(argv
[2], "checksessionid"))
4349 ProcessIdToSessionId(GetProcessId(GetCurrentProcess()), &id
);
4350 sscanf(argv
[3], "%lx", &id
);
4351 child_process_check_session_id(id
);
4354 if (!strcmp(argv
[2], "exit_process_async"))
4358 sscanf(argv
[3], "%lx", &pid
);
4359 sscanf(argv
[4], "%p", &handle
);
4360 child_process_exit_process_async(pid
, handle
);
4365 if (test_DisconnectNamedPipe())
4367 test_CreateNamedPipe_instances_must_match();
4369 test_CreateNamedPipe(PIPE_TYPE_BYTE
);
4370 test_CreateNamedPipe(PIPE_TYPE_MESSAGE
| PIPE_READMODE_MESSAGE
);
4374 test_impersonation();
4376 test_overlapped_error();
4377 test_NamedPipeHandleState();
4378 test_GetNamedPipeInfo();
4379 test_readfileex_pending();
4380 test_overlapped_transport(TRUE
, FALSE
);
4381 test_overlapped_transport(TRUE
, TRUE
);
4382 test_overlapped_transport(FALSE
, FALSE
);
4383 test_TransactNamedPipe();
4384 test_namedpipe_process_id();
4385 test_namedpipe_session_id();
4386 test_multiple_instances();
4388 test_nowait(PIPE_TYPE_BYTE
);
4389 test_nowait(PIPE_TYPE_MESSAGE
);
4390 test_GetOverlappedResultEx();
4391 test_exit_process_async();
4392 test_CancelSynchronousIo();