kernel32: GetLongPathName should fail when called with a wildcard.
[wine.git] / dlls / kernel32 / tests / pipe.c
blob7f77df1d0b36ffeeaf8c42092baad83a8e9452a9
1 /*
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
21 #include <stdarg.h>
22 #include <stdio.h>
24 #include "ntstatus.h"
25 #define WIN32_NO_STATUS
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winternl.h"
29 #include "winioctl.h"
30 #include "wine/test.h"
32 #define PIPENAME "\\\\.\\PiPe\\tests_pipe.c"
34 #define NB_SERVER_LOOPS 8
36 static HANDLE alarm_event;
37 static BOOL (WINAPI *pDuplicateTokenEx)(HANDLE,DWORD,LPSECURITY_ATTRIBUTES,
38 SECURITY_IMPERSONATION_LEVEL,TOKEN_TYPE,PHANDLE);
39 static DWORD (WINAPI *pQueueUserAPC)(PAPCFUNC pfnAPC, HANDLE hThread, ULONG_PTR dwData);
40 static BOOL (WINAPI *pCancelIoEx)(HANDLE handle, LPOVERLAPPED lpOverlapped);
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*);
46 static BOOL user_apc_ran;
47 static void CALLBACK user_apc(ULONG_PTR param)
49 user_apc_ran = TRUE;
53 enum rpcThreadOp
55 RPC_READFILE
58 struct rpcThreadArgs
60 ULONG_PTR returnValue;
61 DWORD lastError;
62 enum rpcThreadOp op;
63 ULONG_PTR args[5];
66 static DWORD CALLBACK rpcThreadMain(LPVOID arg)
68 struct rpcThreadArgs *rpcargs = (struct rpcThreadArgs *)arg;
69 if (winetest_debug > 1) trace("rpcThreadMain starting\n");
70 SetLastError( rpcargs->lastError );
72 switch (rpcargs->op)
74 case RPC_READFILE:
75 rpcargs->returnValue = (ULONG_PTR)ReadFile( (HANDLE)rpcargs->args[0], /* hFile */
76 (LPVOID)rpcargs->args[1], /* buffer */
77 (DWORD)rpcargs->args[2], /* bytesToRead */
78 (LPDWORD)rpcargs->args[3], /* bytesRead */
79 (LPOVERLAPPED)rpcargs->args[4] ); /* overlapped */
80 break;
82 default:
83 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
84 rpcargs->returnValue = 0;
85 break;
88 rpcargs->lastError = GetLastError();
89 if (winetest_debug > 1) trace("rpcThreadMain returning\n");
90 return 0;
93 /* Runs ReadFile(...) from a different thread */
94 static BOOL RpcReadFile(HANDLE hFile, LPVOID buffer, DWORD bytesToRead, LPDWORD bytesRead, LPOVERLAPPED overlapped)
96 struct rpcThreadArgs rpcargs;
97 HANDLE thread;
98 DWORD threadId, ret;
100 rpcargs.returnValue = 0;
101 rpcargs.lastError = GetLastError();
102 rpcargs.op = RPC_READFILE;
103 rpcargs.args[0] = (ULONG_PTR)hFile;
104 rpcargs.args[1] = (ULONG_PTR)buffer;
105 rpcargs.args[2] = (ULONG_PTR)bytesToRead;
106 rpcargs.args[3] = (ULONG_PTR)bytesRead;
107 rpcargs.args[4] = (ULONG_PTR)overlapped;
109 thread = CreateThread(NULL, 0, rpcThreadMain, (void *)&rpcargs, 0, &threadId);
110 ok(thread != NULL, "CreateThread failed. %d\n", GetLastError());
111 ret = WaitForSingleObject(thread, INFINITE);
112 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed with %d.\n", GetLastError());
113 CloseHandle(thread);
115 SetLastError(rpcargs.lastError);
116 return (BOOL)rpcargs.returnValue;
119 #define test_not_signaled(h) _test_not_signaled(__LINE__,h)
120 static void _test_not_signaled(unsigned line, HANDLE handle)
122 DWORD res = WaitForSingleObject(handle, 0);
123 ok_(__FILE__,line)(res == WAIT_TIMEOUT, "WaitForSingleObject returned %u (%u)\n", res, GetLastError());
126 #define test_signaled(h) _test_signaled(__LINE__,h)
127 static void _test_signaled(unsigned line, HANDLE handle)
129 DWORD res = WaitForSingleObject(handle, 0);
130 ok_(__FILE__,line)(res == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", res);
133 #define test_pipe_info(a,b,c,d,e) _test_pipe_info(__LINE__,a,b,c,d,e)
134 static void _test_pipe_info(unsigned line, HANDLE pipe, DWORD ex_flags, DWORD ex_out_buf_size, DWORD ex_in_buf_size, DWORD ex_max_instances)
136 DWORD flags = 0xdeadbeef, out_buf_size = 0xdeadbeef, in_buf_size = 0xdeadbeef, max_instances = 0xdeadbeef;
137 BOOL res;
139 res = GetNamedPipeInfo(pipe, &flags, &out_buf_size, &in_buf_size, &max_instances);
140 ok_(__FILE__,line)(res, "GetNamedPipeInfo failed: %x\n", res);
141 ok_(__FILE__,line)(flags == ex_flags, "flags = %x, expected %x\n", flags, ex_flags);
142 ok_(__FILE__,line)(out_buf_size == ex_out_buf_size, "out_buf_size = %x, expected %u\n", out_buf_size, ex_out_buf_size);
143 ok_(__FILE__,line)(in_buf_size == ex_in_buf_size, "in_buf_size = %x, expected %u\n", in_buf_size, ex_in_buf_size);
144 ok_(__FILE__,line)(max_instances == ex_max_instances, "max_instances = %x, expected %u\n", max_instances, ex_max_instances);
147 #define test_file_access(a,b) _test_file_access(__LINE__,a,b)
148 static void _test_file_access(unsigned line, HANDLE handle, DWORD expected_access)
150 FILE_ACCESS_INFORMATION info;
151 IO_STATUS_BLOCK io;
152 NTSTATUS status;
154 memset(&info, 0x11, sizeof(info));
155 status = NtQueryInformationFile(handle, &io, &info, sizeof(info), FileAccessInformation);
156 ok_(__FILE__,line)(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status);
157 ok_(__FILE__,line)(info.AccessFlags == expected_access, "got access %08x expected %08x\n",
158 info.AccessFlags, expected_access);
161 static void test_CreateNamedPipe(int pipemode)
163 HANDLE hnp;
164 HANDLE hFile;
165 static const char obuf[] = "Bit Bucket";
166 static const char obuf2[] = "More bits";
167 char ibuf[32], *pbuf;
168 DWORD written;
169 DWORD readden;
170 DWORD avail;
171 DWORD left;
172 DWORD lpmode;
173 BOOL ret;
175 if (pipemode == PIPE_TYPE_BYTE)
176 trace("test_CreateNamedPipe starting in byte mode\n");
177 else
178 trace("test_CreateNamedPipe starting in message mode\n");
180 /* Wait for nonexistent pipe */
181 ret = WaitNamedPipeA(PIPENAME, 2000);
182 ok(ret == 0, "WaitNamedPipe returned %d for nonexistent pipe\n", ret);
183 ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
185 /* Bad parameter checks */
186 hnp = CreateNamedPipeA("not a named pipe", PIPE_ACCESS_DUPLEX, pipemode | PIPE_WAIT,
187 /* nMaxInstances */ 1,
188 /* nOutBufSize */ 1024,
189 /* nInBufSize */ 1024,
190 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
191 /* lpSecurityAttrib */ NULL);
192 ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_NAME,
193 "CreateNamedPipe should fail if name doesn't start with \\\\.\\pipe\n");
195 if (pipemode == PIPE_TYPE_BYTE)
197 /* Bad parameter checks */
198 hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_MESSAGE,
199 /* nMaxInstances */ 1,
200 /* nOutBufSize */ 1024,
201 /* nInBufSize */ 1024,
202 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
203 /* lpSecurityAttrib */ NULL);
204 ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_PARAMETER,
205 "CreateNamedPipe should fail with PIPE_TYPE_BYTE | PIPE_READMODE_MESSAGE\n");
208 hnp = CreateNamedPipeA(NULL,
209 PIPE_ACCESS_DUPLEX, pipemode | PIPE_WAIT,
210 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL);
211 ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
212 "CreateNamedPipe should fail if name is NULL\n");
214 hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
215 ok(hFile == INVALID_HANDLE_VALUE
216 && GetLastError() == ERROR_FILE_NOT_FOUND,
217 "connecting to nonexistent named pipe should fail with ERROR_FILE_NOT_FOUND\n");
219 /* Functional checks */
221 hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, pipemode | PIPE_WAIT,
222 /* nMaxInstances */ 1,
223 /* nOutBufSize */ 1024,
224 /* nInBufSize */ 1024,
225 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
226 /* lpSecurityAttrib */ NULL);
227 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
228 test_signaled(hnp);
230 test_file_access(hnp, SYNCHRONIZE | READ_CONTROL | FILE_WRITE_ATTRIBUTES
231 | FILE_READ_ATTRIBUTES | FILE_WRITE_PROPERTIES | FILE_READ_PROPERTIES
232 | FILE_APPEND_DATA | FILE_WRITE_DATA | FILE_READ_DATA);
234 ret = PeekNamedPipe(hnp, NULL, 0, NULL, &readden, NULL);
235 ok(!ret && GetLastError() == ERROR_BAD_PIPE, "PeekNamedPipe returned %x (%u)\n",
236 ret, GetLastError());
238 ret = WaitNamedPipeA(PIPENAME, 2000);
239 ok(ret, "WaitNamedPipe failed (%d)\n", GetLastError());
241 hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
242 ok(hFile != INVALID_HANDLE_VALUE, "CreateFile failed (%d)\n", GetLastError());
244 ok(!WaitNamedPipeA(PIPENAME, 100), "WaitNamedPipe succeeded\n");
246 ok(GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %u\n", GetLastError());
248 /* Test ConnectNamedPipe() in both directions */
249 ok(!ConnectNamedPipe(hnp, NULL), "ConnectNamedPipe(server) succeeded\n");
250 ok(GetLastError() == ERROR_PIPE_CONNECTED, "expected ERROR_PIPE_CONNECTED, got %u\n", GetLastError());
251 ok(!ConnectNamedPipe(hFile, NULL), "ConnectNamedPipe(client) succeeded\n");
252 ok(GetLastError() == ERROR_INVALID_FUNCTION, "expected ERROR_INVALID_FUNCTION, got %u\n", GetLastError());
254 /* don't try to do i/o if one side couldn't be opened, as it hangs */
255 if (hFile != INVALID_HANDLE_VALUE) {
256 HANDLE hFile2;
258 /* Make sure we can read and write a few bytes in both directions */
259 memset(ibuf, 0, sizeof(ibuf));
260 ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile\n");
261 ok(written == sizeof(obuf), "write file len\n");
262 ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
263 ok(readden == sizeof(obuf), "read got %d bytes\n", readden);
264 ok(memcmp(obuf, ibuf, written) == 0, "content check\n");
266 memset(ibuf, 0, sizeof(ibuf));
267 ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), "WriteFile\n");
268 ok(written == sizeof(obuf2), "write file len\n");
269 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
270 ok(readden == sizeof(obuf2), "read got %d bytes\n", readden);
271 ok(memcmp(obuf2, ibuf, written) == 0, "content check\n");
273 /* Now the same again, but with an additional call to PeekNamedPipe */
274 memset(ibuf, 0, sizeof(ibuf));
275 ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile\n");
276 ok(written == sizeof(obuf), "write file len 1\n");
277 ok(PeekNamedPipe(hFile, NULL, 0, NULL, &avail, &left), "Peek\n");
278 ok(avail == sizeof(obuf), "peek 1 got %d bytes\n", avail);
279 if (pipemode == PIPE_TYPE_BYTE)
280 ok(left == 0, "peek 1 got %d bytes left\n", left);
281 else
282 ok(left == sizeof(obuf), "peek 1 got %d bytes left\n", left);
283 ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
284 ok(readden == sizeof(obuf), "read 1 got %d bytes\n", readden);
285 ok(memcmp(obuf, ibuf, written) == 0, "content 1 check\n");
287 memset(ibuf, 0, sizeof(ibuf));
288 ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), "WriteFile\n");
289 ok(written == sizeof(obuf2), "write file len 2\n");
290 ok(PeekNamedPipe(hnp, NULL, 0, NULL, &avail, &left), "Peek\n");
291 ok(avail == sizeof(obuf2), "peek 2 got %d bytes\n", avail);
292 if (pipemode == PIPE_TYPE_BYTE)
293 ok(left == 0, "peek 2 got %d bytes left\n", left);
294 else
295 ok(left == sizeof(obuf2), "peek 2 got %d bytes left\n", left);
296 ok(PeekNamedPipe(hnp, (LPVOID)1, 0, NULL, &avail, &left), "Peek\n");
297 ok(avail == sizeof(obuf2), "peek 2 got %d bytes\n", avail);
298 if (pipemode == PIPE_TYPE_BYTE)
299 ok(left == 0, "peek 2 got %d bytes left\n", left);
300 else
301 ok(left == sizeof(obuf2), "peek 2 got %d bytes left\n", left);
302 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
303 ok(readden == sizeof(obuf2), "read 2 got %d bytes\n", readden);
304 ok(memcmp(obuf2, ibuf, written) == 0, "content 2 check\n");
306 /* Test how ReadFile behaves when the buffer is not big enough for the whole message */
307 memset(ibuf, 0, sizeof(ibuf));
308 ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), "WriteFile\n");
309 ok(written == sizeof(obuf2), "write file len\n");
310 ok(PeekNamedPipe(hFile, ibuf, 4, &readden, &avail, &left), "Peek\n");
311 ok(readden == 4, "peek got %d bytes\n", readden);
312 ok(avail == sizeof(obuf2), "peek got %d bytes available\n", avail);
313 if (pipemode == PIPE_TYPE_BYTE)
314 ok(left == -4, "peek got %d bytes left\n", left);
315 else
316 ok(left == sizeof(obuf2)-4, "peek got %d bytes left\n", left);
317 ok(ReadFile(hFile, ibuf, 4, &readden, NULL), "ReadFile\n");
318 ok(readden == 4, "read got %d bytes\n", readden);
319 ok(ReadFile(hFile, ibuf + 4, sizeof(ibuf) - 4, &readden, NULL), "ReadFile\n");
320 ok(readden == sizeof(obuf2) - 4, "read got %d bytes\n", readden);
321 ok(memcmp(obuf2, ibuf, written) == 0, "content check\n");
323 memset(ibuf, 0, sizeof(ibuf));
324 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile\n");
325 ok(written == sizeof(obuf), "write file len\n");
326 ok(PeekNamedPipe(hnp, ibuf, 4, &readden, &avail, &left), "Peek\n");
327 ok(readden == 4, "peek got %d bytes\n", readden);
328 ok(avail == sizeof(obuf), "peek got %d bytes available\n", avail);
329 if (pipemode == PIPE_TYPE_BYTE)
331 ok(left == -4, "peek got %d bytes left\n", left);
332 ok(ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile\n");
334 else
336 ok(left == sizeof(obuf)-4, "peek got %d bytes left\n", left);
337 SetLastError(0xdeadbeef);
338 ok(!ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile\n");
339 ok(GetLastError() == ERROR_MORE_DATA, "wrong error\n");
341 ok(readden == 4, "read got %d bytes\n", readden);
342 ok(ReadFile(hnp, ibuf + 4, sizeof(ibuf) - 4, &readden, NULL), "ReadFile\n");
343 ok(readden == sizeof(obuf) - 4, "read got %d bytes\n", readden);
344 ok(memcmp(obuf, ibuf, written) == 0, "content check\n");
346 /* Similar to above, but use a read buffer size small enough to read in three parts */
347 memset(ibuf, 0, sizeof(ibuf));
348 ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), "WriteFile\n");
349 ok(written == sizeof(obuf2), "write file len\n");
350 if (pipemode == PIPE_TYPE_BYTE)
352 ok(ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile\n");
353 ok(readden == 4, "read got %d bytes\n", readden);
354 ok(ReadFile(hnp, ibuf + 4, 4, &readden, NULL), "ReadFile\n");
356 else
358 SetLastError(0xdeadbeef);
359 ok(!ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile\n");
360 ok(GetLastError() == ERROR_MORE_DATA, "wrong error\n");
361 ok(readden == 4, "read got %d bytes\n", readden);
362 SetLastError(0xdeadbeef);
363 ok(!ReadFile(hnp, ibuf + 4, 4, &readden, NULL), "ReadFile\n");
364 ok(GetLastError() == ERROR_MORE_DATA, "wrong error\n");
366 ok(readden == 4, "read got %d bytes\n", readden);
367 ok(ReadFile(hnp, ibuf + 8, sizeof(ibuf) - 8, &readden, NULL), "ReadFile\n");
368 ok(readden == sizeof(obuf2) - 8, "read got %d bytes\n", readden);
369 ok(memcmp(obuf2, ibuf, written) == 0, "content check\n");
371 /* Test reading of multiple writes */
372 memset(ibuf, 0, sizeof(ibuf));
373 ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile3a\n");
374 ok(written == sizeof(obuf), "write file len 3a\n");
375 ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), " WriteFile3b\n");
376 ok(written == sizeof(obuf2), "write file len 3b\n");
377 ok(PeekNamedPipe(hFile, ibuf, 4, &readden, &avail, &left), "Peek3\n");
378 ok(readden == 4, "peek3 got %d bytes\n", readden);
379 if (pipemode == PIPE_TYPE_BYTE)
380 ok(left == -4, "peek3 got %d bytes left\n", left);
381 else
382 ok(left == sizeof(obuf)-4, "peek3 got %d bytes left\n", left);
383 ok(avail == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes available\n", avail);
384 ok(PeekNamedPipe(hFile, ibuf, sizeof(ibuf), &readden, &avail, &left), "Peek3\n");
385 if (pipemode == PIPE_TYPE_BYTE) {
386 ok(readden == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes\n", readden);
387 ok(left == (DWORD) -(sizeof(obuf) + sizeof(obuf2)), "peek3 got %d bytes left\n", left);
389 else
391 ok(readden == sizeof(obuf), "peek3 got %d bytes\n", readden);
392 ok(left == 0, "peek3 got %d bytes left\n", left);
394 ok(avail == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes available\n", avail);
395 pbuf = ibuf;
396 ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "pipe content 3a check\n");
397 if (pipemode == PIPE_TYPE_BYTE && readden >= sizeof(obuf)+sizeof(obuf2)) {
398 pbuf += sizeof(obuf);
399 ok(memcmp(obuf2, pbuf, sizeof(obuf2)) == 0, "pipe content 3b check\n");
401 ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
402 ok(readden == sizeof(obuf) + sizeof(obuf2), "read 3 got %d bytes\n", readden);
403 pbuf = ibuf;
404 ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 3a check\n");
405 pbuf += sizeof(obuf);
406 ok(memcmp(obuf2, pbuf, sizeof(obuf2)) == 0, "content 3b check\n");
408 /* Multiple writes in the reverse direction */
409 memset(ibuf, 0, sizeof(ibuf));
410 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile4a\n");
411 ok(written == sizeof(obuf), "write file len 4a\n");
412 ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), " WriteFile4b\n");
413 ok(written == sizeof(obuf2), "write file len 4b\n");
414 ok(PeekNamedPipe(hnp, ibuf, 4, &readden, &avail, &left), "Peek3\n");
415 ok(readden == 4, "peek3 got %d bytes\n", readden);
416 if (pipemode == PIPE_TYPE_BYTE)
417 ok(left == -4, "peek3 got %d bytes left\n", left);
418 else
419 ok(left == sizeof(obuf)-4, "peek3 got %d bytes left\n", left);
420 ok(avail == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes available\n", avail);
421 ok(PeekNamedPipe(hnp, ibuf, sizeof(ibuf), &readden, &avail, &left), "Peek4\n");
422 if (pipemode == PIPE_TYPE_BYTE) {
423 ok(readden == sizeof(obuf) + sizeof(obuf2), "peek4 got %d bytes\n", readden);
424 ok(left == (DWORD) -(sizeof(obuf) + sizeof(obuf2)), "peek4 got %d bytes left\n", left);
426 else
428 ok(readden == sizeof(obuf), "peek4 got %d bytes\n", readden);
429 ok(left == 0, "peek4 got %d bytes left\n", left);
431 ok(avail == sizeof(obuf) + sizeof(obuf2), "peek4 got %d bytes available\n", avail);
432 pbuf = ibuf;
433 ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "pipe content 4a check\n");
434 if (pipemode == PIPE_TYPE_BYTE && readden >= sizeof(obuf)+sizeof(obuf2)) {
435 pbuf += sizeof(obuf);
436 ok(memcmp(obuf2, pbuf, sizeof(obuf2)) == 0, "pipe content 4b check\n");
438 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
439 if (pipemode == PIPE_TYPE_BYTE) {
440 ok(readden == sizeof(obuf) + sizeof(obuf2), "read 4 got %d bytes\n", readden);
442 else {
443 ok(readden == sizeof(obuf), "read 4 got %d bytes\n", readden);
445 pbuf = ibuf;
446 ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 4a check\n");
447 if (pipemode == PIPE_TYPE_BYTE) {
448 pbuf += sizeof(obuf);
449 ok(memcmp(obuf2, pbuf, sizeof(obuf2)) == 0, "content 4b check\n");
452 /* Test reading of multiple writes after a mode change
453 (CreateFile always creates a byte mode pipe) */
454 lpmode = PIPE_READMODE_MESSAGE;
455 if (pipemode == PIPE_TYPE_BYTE) {
456 /* trying to change the client end of a byte pipe to message mode should fail */
457 ok(!SetNamedPipeHandleState(hFile, &lpmode, NULL, NULL), "Change mode\n");
459 else {
460 ok(SetNamedPipeHandleState(hFile, &lpmode, NULL, NULL), "Change mode\n");
462 memset(ibuf, 0, sizeof(ibuf));
463 ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile5a\n");
464 ok(written == sizeof(obuf), "write file len 3a\n");
465 ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), " WriteFile5b\n");
466 ok(written == sizeof(obuf2), "write file len 3b\n");
467 ok(PeekNamedPipe(hFile, ibuf, sizeof(ibuf), &readden, &avail, &left), "Peek5\n");
468 ok(readden == sizeof(obuf), "peek5 got %d bytes\n", readden);
469 ok(avail == sizeof(obuf) + sizeof(obuf2), "peek5 got %d bytes available\n", avail);
470 ok(left == 0, "peek5 got %d bytes left\n", left);
471 pbuf = ibuf;
472 ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 5a check\n");
473 ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
474 ok(readden == sizeof(obuf), "read 5 got %d bytes\n", readden);
475 pbuf = ibuf;
476 ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 5a check\n");
477 if (readden <= sizeof(obuf))
478 ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
480 /* Multiple writes in the reverse direction */
481 /* the write of obuf2 from write4 should still be in the buffer */
482 ok(PeekNamedPipe(hnp, ibuf, sizeof(ibuf), &readden, &avail, NULL), "Peek6a\n");
483 ok(readden == sizeof(obuf2), "peek6a got %d bytes\n", readden);
484 ok(avail == sizeof(obuf2), "peek6a got %d bytes available\n", avail);
485 if (avail > 0) {
486 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
487 ok(readden == sizeof(obuf2), "read 6a got %d bytes\n", readden);
488 pbuf = ibuf;
489 ok(memcmp(obuf2, pbuf, sizeof(obuf2)) == 0, "content 6a check\n");
491 memset(ibuf, 0, sizeof(ibuf));
492 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile6a\n");
493 ok(written == sizeof(obuf), "write file len 6a\n");
494 ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), " WriteFile6b\n");
495 ok(written == sizeof(obuf2), "write file len 6b\n");
496 ok(PeekNamedPipe(hnp, ibuf, sizeof(ibuf), &readden, &avail, NULL), "Peek6\n");
497 ok(readden == sizeof(obuf), "peek6 got %d bytes\n", readden);
499 ok(avail == sizeof(obuf) + sizeof(obuf2), "peek6b got %d bytes available\n", avail);
500 pbuf = ibuf;
501 ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 6a check\n");
502 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
503 ok(readden == sizeof(obuf), "read 6b got %d bytes\n", readden);
504 pbuf = ibuf;
505 ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 6a check\n");
506 if (readden <= sizeof(obuf))
507 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
509 /* Test how ReadFile behaves when the buffer is not big enough for the whole message */
510 memset(ibuf, 0, sizeof(ibuf));
511 ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), "WriteFile 7\n");
512 ok(written == sizeof(obuf2), "write file len 7\n");
513 SetLastError(0xdeadbeef);
514 ok(!ReadFile(hFile, ibuf, 4, &readden, NULL), "ReadFile 7\n");
515 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 7\n");
516 ok(readden == 4, "read got %d bytes 7\n", readden);
517 ok(ReadFile(hFile, ibuf + 4, sizeof(ibuf) - 4, &readden, NULL), "ReadFile 7\n");
518 ok(readden == sizeof(obuf2) - 4, "read got %d bytes 7\n", readden);
519 ok(memcmp(obuf2, ibuf, written) == 0, "content check 7\n");
521 memset(ibuf, 0, sizeof(ibuf));
522 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile 8\n");
523 ok(written == sizeof(obuf), "write file len 8\n");
524 SetLastError(0xdeadbeef);
525 ok(!ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile 8\n");
526 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 8\n");
527 ok(readden == 4, "read got %d bytes 8\n", readden);
528 ok(ReadFile(hnp, ibuf + 4, sizeof(ibuf) - 4, &readden, NULL), "ReadFile 8\n");
529 ok(readden == sizeof(obuf) - 4, "read got %d bytes 8\n", readden);
530 ok(memcmp(obuf, ibuf, written) == 0, "content check 8\n");
532 /* The following test shows that when doing a partial read of a message, the rest
533 * is still in the pipe, and can be received from a second thread. This shows
534 * especially that the content is _not_ stored in thread-local-storage until it is
535 * completely transmitted. The same method works even across multiple processes. */
536 memset(ibuf, 0, sizeof(ibuf));
537 ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile 9\n");
538 ok(written == sizeof(obuf), "write file len 9\n");
539 ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), "WriteFile 9\n");
540 ok(written == sizeof(obuf2), "write file len 9\n");
541 SetLastError(0xdeadbeef);
542 ok(!ReadFile(hFile, ibuf, 4, &readden, NULL), "ReadFile 9\n");
543 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 9\n");
544 ok(readden == 4, "read got %d bytes 9\n", readden);
545 SetLastError(0xdeadbeef);
546 ret = RpcReadFile(hFile, ibuf + 4, 4, &readden, NULL);
547 ok(!ret, "RpcReadFile 9\n");
548 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 9\n");
549 ok(readden == 4, "read got %d bytes 9\n", readden);
550 ret = RpcReadFile(hFile, ibuf + 8, sizeof(ibuf), &readden, NULL);
551 ok(ret, "RpcReadFile 9\n");
552 ok(readden == sizeof(obuf) - 8, "read got %d bytes 9\n", readden);
553 ok(memcmp(obuf, ibuf, sizeof(obuf)) == 0, "content check 9\n");
554 if (readden <= sizeof(obuf) - 8) /* blocks forever if second part was already received */
556 memset(ibuf, 0, sizeof(ibuf));
557 SetLastError(0xdeadbeef);
558 ret = RpcReadFile(hFile, ibuf, 4, &readden, NULL);
559 ok(!ret, "RpcReadFile 9\n");
560 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 9\n");
561 ok(readden == 4, "read got %d bytes 9\n", readden);
562 SetLastError(0xdeadbeef);
563 ok(!ReadFile(hFile, ibuf + 4, 4, &readden, NULL), "ReadFile 9\n");
564 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 9\n");
565 ok(readden == 4, "read got %d bytes 9\n", readden);
566 ret = RpcReadFile(hFile, ibuf + 8, sizeof(ibuf), &readden, NULL);
567 ok(ret, "RpcReadFile 9\n");
568 ok(readden == sizeof(obuf2) - 8, "read got %d bytes 9\n", readden);
569 ok(memcmp(obuf2, ibuf, sizeof(obuf2)) == 0, "content check 9\n");
572 /* Now the reverse direction */
573 memset(ibuf, 0, sizeof(ibuf));
574 ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), "WriteFile 10\n");
575 ok(written == sizeof(obuf2), "write file len 10\n");
576 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile 10\n");
577 ok(written == sizeof(obuf), "write file len 10\n");
578 SetLastError(0xdeadbeef);
579 ok(!ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile 10\n");
580 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 10\n");
581 ok(readden == 4, "read got %d bytes 10\n", readden);
582 SetLastError(0xdeadbeef);
583 ret = RpcReadFile(hnp, ibuf + 4, 4, &readden, NULL);
584 ok(!ret, "RpcReadFile 10\n");
585 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 10\n");
586 ok(readden == 4, "read got %d bytes 10\n", readden);
587 ret = RpcReadFile(hnp, ibuf + 8, sizeof(ibuf), &readden, NULL);
588 ok(ret, "RpcReadFile 10\n");
589 ok(readden == sizeof(obuf2) - 8, "read got %d bytes 10\n", readden);
590 ok(memcmp(obuf2, ibuf, sizeof(obuf2)) == 0, "content check 10\n");
591 if (readden <= sizeof(obuf2) - 8) /* blocks forever if second part was already received */
593 memset(ibuf, 0, sizeof(ibuf));
594 SetLastError(0xdeadbeef);
595 ret = RpcReadFile(hnp, ibuf, 4, &readden, NULL);
596 ok(!ret, "RpcReadFile 10\n");
597 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 10\n");
598 ok(readden == 4, "read got %d bytes 10\n", readden);
599 SetLastError(0xdeadbeef);
600 ok(!ReadFile(hnp, ibuf + 4, 4, &readden, NULL), "ReadFile 10\n");
601 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 10\n");
602 ok(readden == 4, "read got %d bytes 10\n", readden);
603 ret = RpcReadFile(hnp, ibuf + 8, sizeof(ibuf), &readden, NULL);
604 ok(ret, "RpcReadFile 10\n");
605 ok(readden == sizeof(obuf) - 8, "read got %d bytes 10\n", readden);
606 ok(memcmp(obuf, ibuf, sizeof(obuf)) == 0, "content check 10\n");
611 /* Picky conformance tests */
613 /* Verify that you can't connect to pipe again
614 * until server calls DisconnectNamedPipe+ConnectNamedPipe
615 * or creates a new pipe
616 * case 1: other client not yet closed
618 hFile2 = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
619 ok(hFile2 == INVALID_HANDLE_VALUE,
620 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n");
621 ok(GetLastError() == ERROR_PIPE_BUSY,
622 "connecting to named pipe before other client closes should fail with ERROR_PIPE_BUSY\n");
624 ok(CloseHandle(hFile), "CloseHandle\n");
626 /* case 2: other client already closed */
627 hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
628 ok(hFile == INVALID_HANDLE_VALUE,
629 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n");
630 ok(GetLastError() == ERROR_PIPE_BUSY,
631 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail with ERROR_PIPE_BUSY\n");
633 ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n");
635 /* case 3: server has called DisconnectNamedPipe but not ConnectNamed Pipe */
636 hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
637 ok(hFile == INVALID_HANDLE_VALUE,
638 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n");
639 ok(GetLastError() == ERROR_PIPE_BUSY,
640 "connecting to named pipe after other client closes but before ConnectNamedPipe should fail with ERROR_PIPE_BUSY\n");
642 /* to be complete, we'd call ConnectNamedPipe here and loop,
643 * but by default that's blocking, so we'd either have
644 * to turn on the uncommon nonblocking mode, or
645 * use another thread.
649 ok(CloseHandle(hnp), "CloseHandle\n");
651 hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_INBOUND, pipemode | PIPE_WAIT,
652 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL);
653 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
654 test_signaled(hnp);
656 test_file_access(hnp, SYNCHRONIZE | READ_CONTROL | FILE_READ_ATTRIBUTES | FILE_READ_PROPERTIES
657 | FILE_READ_DATA);
659 CloseHandle(hnp);
661 hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_OUTBOUND, pipemode | PIPE_WAIT,
662 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL);
663 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
664 test_signaled(hnp);
666 test_file_access(hnp, SYNCHRONIZE | READ_CONTROL | FILE_WRITE_ATTRIBUTES
667 | FILE_WRITE_PROPERTIES | FILE_APPEND_DATA | FILE_WRITE_DATA);
669 hFile = CreateFileA(PIPENAME, 0, 0, NULL, OPEN_EXISTING, 0, 0);
670 ok(hFile != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError());
671 test_file_access(hFile, SYNCHRONIZE | FILE_READ_ATTRIBUTES);
672 CloseHandle(hFile);
674 CloseHandle(hnp);
676 if (winetest_debug > 1) trace("test_CreateNamedPipe returning\n");
679 static void test_CreateNamedPipe_instances_must_match(void)
681 HANDLE hnp, hnp2;
683 /* Check no mismatch */
684 hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
685 /* nMaxInstances */ 2,
686 /* nOutBufSize */ 1024,
687 /* nInBufSize */ 1024,
688 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
689 /* lpSecurityAttrib */ NULL);
690 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
692 hnp2 = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
693 /* nMaxInstances */ 2,
694 /* nOutBufSize */ 1024,
695 /* nInBufSize */ 1024,
696 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
697 /* lpSecurityAttrib */ NULL);
698 ok(hnp2 != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
700 ok(CloseHandle(hnp), "CloseHandle\n");
701 ok(CloseHandle(hnp2), "CloseHandle\n");
703 /* Check nMaxInstances */
704 hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
705 /* nMaxInstances */ 1,
706 /* nOutBufSize */ 1024,
707 /* nInBufSize */ 1024,
708 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
709 /* lpSecurityAttrib */ NULL);
710 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
712 hnp2 = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
713 /* nMaxInstances */ 1,
714 /* nOutBufSize */ 1024,
715 /* nInBufSize */ 1024,
716 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
717 /* lpSecurityAttrib */ NULL);
718 ok(hnp2 == INVALID_HANDLE_VALUE
719 && GetLastError() == ERROR_PIPE_BUSY, "nMaxInstances not obeyed\n");
721 ok(CloseHandle(hnp), "CloseHandle\n");
723 /* Check PIPE_ACCESS_* */
724 hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
725 /* nMaxInstances */ 2,
726 /* nOutBufSize */ 1024,
727 /* nInBufSize */ 1024,
728 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
729 /* lpSecurityAttrib */ NULL);
730 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
732 hnp2 = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE | PIPE_WAIT,
733 /* nMaxInstances */ 2,
734 /* nOutBufSize */ 1024,
735 /* nInBufSize */ 1024,
736 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
737 /* lpSecurityAttrib */ NULL);
738 ok(hnp2 == INVALID_HANDLE_VALUE
739 && GetLastError() == ERROR_ACCESS_DENIED, "PIPE_ACCESS_* mismatch allowed\n");
741 ok(CloseHandle(hnp), "CloseHandle\n");
743 /* check everything else */
744 hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
745 /* nMaxInstances */ 4,
746 /* nOutBufSize */ 1024,
747 /* nInBufSize */ 1024,
748 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
749 /* lpSecurityAttrib */ NULL);
750 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
752 hnp2 = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE,
753 /* nMaxInstances */ 3,
754 /* nOutBufSize */ 102,
755 /* nInBufSize */ 24,
756 /* nDefaultWait */ 1234,
757 /* lpSecurityAttrib */ NULL);
758 ok(hnp2 != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
760 ok(CloseHandle(hnp), "CloseHandle\n");
761 ok(CloseHandle(hnp2), "CloseHandle\n");
764 static void test_ReadFile(void)
766 HANDLE server, client;
767 OVERLAPPED overlapped;
768 DWORD size;
769 BOOL res;
771 static char buf[512];
773 server = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX,
774 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
775 1, 1024, 1024, NMPWAIT_WAIT_FOREVER, NULL);
776 ok(server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %u\n", GetLastError());
778 client = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL,
779 OPEN_EXISTING, 0, 0);
780 ok(client != INVALID_HANDLE_VALUE, "CreateFile failed with %u\n", GetLastError());
782 ok(WriteFile(client, buf, sizeof(buf), &size, NULL), "WriteFile\n");
784 res = ReadFile(server, buf, 1, &size, NULL);
785 ok(!res && GetLastError() == ERROR_MORE_DATA, "ReadFile returned %x(%u)\n", res, GetLastError());
786 ok(size == 1, "size = %u\n", size);
788 /* pass both overlapped and ret read */
789 memset(&overlapped, 0, sizeof(overlapped));
790 res = ReadFile(server, buf, 1, &size, &overlapped);
791 ok(!res && GetLastError() == ERROR_MORE_DATA, "ReadFile returned %x(%u)\n", res, GetLastError());
792 ok(size == 0, "size = %u\n", size);
793 ok((NTSTATUS)overlapped.Internal == STATUS_BUFFER_OVERFLOW, "Internal = %lx\n", overlapped.Internal);
794 ok(overlapped.InternalHigh == 1, "InternalHigh = %lx\n", overlapped.InternalHigh);
796 DisconnectNamedPipe(server);
798 memset(&overlapped, 0, sizeof(overlapped));
799 overlapped.InternalHigh = 0xdeadbeef;
800 res = ReadFile(server, buf, 1, &size, &overlapped);
801 ok(!res && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "ReadFile returned %x(%u)\n", res, GetLastError());
802 ok(size == 0, "size = %u\n", size);
803 ok(overlapped.Internal == STATUS_PENDING, "Internal = %lx\n", overlapped.Internal);
804 ok(overlapped.InternalHigh == 0xdeadbeef, "InternalHigh = %lx\n", overlapped.InternalHigh);
806 memset(&overlapped, 0, sizeof(overlapped));
807 overlapped.InternalHigh = 0xdeadbeef;
808 res = WriteFile(server, buf, 1, &size, &overlapped);
809 ok(!res && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "ReadFile returned %x(%u)\n", res, GetLastError());
810 ok(size == 0, "size = %u\n", size);
811 ok(overlapped.Internal == STATUS_PENDING, "Internal = %lx\n", overlapped.Internal);
812 ok(overlapped.InternalHigh == 0xdeadbeef, "InternalHigh = %lx\n", overlapped.InternalHigh);
814 CloseHandle(server);
815 CloseHandle(client);
818 /** implementation of alarm() */
819 static DWORD CALLBACK alarmThreadMain(LPVOID arg)
821 DWORD_PTR timeout = (DWORD_PTR) arg;
822 if (winetest_debug > 1) trace("alarmThreadMain\n");
823 if (WaitForSingleObject( alarm_event, timeout ) == WAIT_TIMEOUT)
825 ok(FALSE, "alarm\n");
826 ExitProcess(1);
828 return 1;
831 static HANDLE hnp = INVALID_HANDLE_VALUE;
833 /** Trivial byte echo server - disconnects after each session */
834 static DWORD CALLBACK serverThreadMain1(LPVOID arg)
836 int i;
838 if (winetest_debug > 1) trace("serverThreadMain1 start\n");
839 /* Set up a simple echo server */
840 hnp = CreateNamedPipeA(PIPENAME "serverThreadMain1", PIPE_ACCESS_DUPLEX,
841 PIPE_TYPE_BYTE | PIPE_WAIT,
842 /* nMaxInstances */ 1,
843 /* nOutBufSize */ 1024,
844 /* nInBufSize */ 1024,
845 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
846 /* lpSecurityAttrib */ NULL);
848 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
849 for (i = 0; i < NB_SERVER_LOOPS; i++) {
850 char buf[512];
851 DWORD written;
852 DWORD readden;
853 BOOL success;
855 /* Wait for client to connect */
856 if (winetest_debug > 1) trace("Server calling ConnectNamedPipe...\n");
857 ok(ConnectNamedPipe(hnp, NULL)
858 || GetLastError() == ERROR_PIPE_CONNECTED, "ConnectNamedPipe\n");
859 if (winetest_debug > 1) trace("ConnectNamedPipe returned.\n");
861 /* Echo bytes once */
862 memset(buf, 0, sizeof(buf));
864 if (winetest_debug > 1) trace("Server reading...\n");
865 success = ReadFile(hnp, buf, sizeof(buf), &readden, NULL);
866 if (winetest_debug > 1) trace("Server done reading.\n");
867 ok(success, "ReadFile\n");
868 ok(readden, "short read\n");
870 if (winetest_debug > 1) trace("Server writing...\n");
871 ok(WriteFile(hnp, buf, readden, &written, NULL), "WriteFile\n");
872 if (winetest_debug > 1) trace("Server done writing.\n");
873 ok(written == readden, "write file len\n");
875 /* finish this connection, wait for next one */
876 ok(FlushFileBuffers(hnp), "FlushFileBuffers\n");
877 if (winetest_debug > 1) trace("Server done flushing.\n");
878 ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n");
879 if (winetest_debug > 1) trace("Server done disconnecting.\n");
881 return 0;
884 /** Trivial byte echo server - closes after each connection */
885 static DWORD CALLBACK serverThreadMain2(LPVOID arg)
887 int i;
888 HANDLE hnpNext = 0;
890 trace("serverThreadMain2\n");
891 /* Set up a simple echo server */
892 hnp = CreateNamedPipeA(PIPENAME "serverThreadMain2", PIPE_ACCESS_DUPLEX,
893 PIPE_TYPE_BYTE | PIPE_WAIT,
894 /* nMaxInstances */ 2,
895 /* nOutBufSize */ 1024,
896 /* nInBufSize */ 1024,
897 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
898 /* lpSecurityAttrib */ NULL);
899 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
901 for (i = 0; i < NB_SERVER_LOOPS; i++) {
902 char buf[512];
903 DWORD written;
904 DWORD readden;
905 DWORD ret;
906 BOOL success;
909 user_apc_ran = FALSE;
910 if (i == 0 && pQueueUserAPC) {
911 if (winetest_debug > 1) trace("Queueing an user APC\n"); /* verify the pipe is non alerable */
912 ret = pQueueUserAPC(&user_apc, GetCurrentThread(), 0);
913 ok(ret, "QueueUserAPC failed: %d\n", GetLastError());
916 /* Wait for client to connect */
917 if (winetest_debug > 1) trace("Server calling ConnectNamedPipe...\n");
918 ok(ConnectNamedPipe(hnp, NULL)
919 || GetLastError() == ERROR_PIPE_CONNECTED, "ConnectNamedPipe\n");
920 if (winetest_debug > 1) trace("ConnectNamedPipe returned.\n");
922 /* Echo bytes once */
923 memset(buf, 0, sizeof(buf));
925 if (winetest_debug > 1) trace("Server reading...\n");
926 success = ReadFile(hnp, buf, sizeof(buf), &readden, NULL);
927 if (winetest_debug > 1) trace("Server done reading.\n");
928 ok(success, "ReadFile\n");
930 if (winetest_debug > 1) trace("Server writing...\n");
931 ok(WriteFile(hnp, buf, readden, &written, NULL), "WriteFile\n");
932 if (winetest_debug > 1) trace("Server done writing.\n");
933 ok(written == readden, "write file len\n");
935 /* finish this connection, wait for next one */
936 ok(FlushFileBuffers(hnp), "FlushFileBuffers\n");
937 ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n");
939 ok(user_apc_ran == FALSE, "UserAPC ran, pipe using alertable io mode\n");
941 if (i == 0 && pQueueUserAPC)
942 SleepEx(0, TRUE); /* get rid of apc */
944 /* Set up next echo server */
945 hnpNext =
946 CreateNamedPipeA(PIPENAME "serverThreadMain2", PIPE_ACCESS_DUPLEX,
947 PIPE_TYPE_BYTE | PIPE_WAIT,
948 /* nMaxInstances */ 2,
949 /* nOutBufSize */ 1024,
950 /* nInBufSize */ 1024,
951 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
952 /* lpSecurityAttrib */ NULL);
954 ok(hnpNext != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
956 ok(CloseHandle(hnp), "CloseHandle\n");
957 hnp = hnpNext;
959 return 0;
962 /** Trivial byte echo server - uses overlapped named pipe calls */
963 static DWORD CALLBACK serverThreadMain3(LPVOID arg)
965 int i;
966 HANDLE hEvent;
968 if (winetest_debug > 1) trace("serverThreadMain3\n");
969 /* Set up a simple echo server */
970 hnp = CreateNamedPipeA(PIPENAME "serverThreadMain3", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
971 PIPE_TYPE_BYTE | PIPE_WAIT,
972 /* nMaxInstances */ 1,
973 /* nOutBufSize */ 1024,
974 /* nInBufSize */ 1024,
975 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
976 /* lpSecurityAttrib */ NULL);
977 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
979 hEvent = CreateEventW(NULL, /* security attribute */
980 TRUE, /* manual reset event */
981 FALSE, /* initial state */
982 NULL); /* name */
983 ok(hEvent != NULL, "CreateEvent\n");
985 for (i = 0; i < NB_SERVER_LOOPS; i++) {
986 char buf[512];
987 DWORD written;
988 DWORD readden;
989 DWORD dummy;
990 BOOL success;
991 OVERLAPPED oOverlap;
992 int letWFSOEwait = (i & 2);
993 int letGORwait = (i & 1);
994 DWORD err;
996 memset(&oOverlap, 0, sizeof(oOverlap));
997 oOverlap.hEvent = hEvent;
999 /* Wait for client to connect */
1000 if (i == 0) {
1001 if (winetest_debug > 1) trace("Server calling non-overlapped ConnectNamedPipe on overlapped pipe...\n");
1002 success = ConnectNamedPipe(hnp, NULL);
1003 err = GetLastError();
1004 ok(success || (err == ERROR_PIPE_CONNECTED), "ConnectNamedPipe failed: %d\n", err);
1005 if (winetest_debug > 1) trace("ConnectNamedPipe operation complete.\n");
1006 } else {
1007 if (winetest_debug > 1) trace("Server calling overlapped ConnectNamedPipe...\n");
1008 success = ConnectNamedPipe(hnp, &oOverlap);
1009 err = GetLastError();
1010 ok(!success && (err == ERROR_IO_PENDING || err == ERROR_PIPE_CONNECTED), "overlapped ConnectNamedPipe\n");
1011 if (winetest_debug > 1) trace("overlapped ConnectNamedPipe returned.\n");
1012 if (!success && (err == ERROR_IO_PENDING)) {
1013 if (letWFSOEwait)
1015 DWORD ret;
1016 do {
1017 ret = WaitForSingleObjectEx(hEvent, INFINITE, TRUE);
1018 } while (ret == WAIT_IO_COMPLETION);
1019 ok(ret == 0, "wait ConnectNamedPipe returned %x\n", ret);
1021 success = GetOverlappedResult(hnp, &oOverlap, &dummy, letGORwait);
1022 if (!letGORwait && !letWFSOEwait && !success) {
1023 ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult\n");
1024 success = GetOverlappedResult(hnp, &oOverlap, &dummy, TRUE);
1027 ok(success || (err == ERROR_PIPE_CONNECTED), "GetOverlappedResult ConnectNamedPipe\n");
1028 if (winetest_debug > 1) trace("overlapped ConnectNamedPipe operation complete.\n");
1031 /* Echo bytes once */
1032 memset(buf, 0, sizeof(buf));
1034 if (winetest_debug > 1) trace("Server reading...\n");
1035 success = ReadFile(hnp, buf, sizeof(buf), &readden, &oOverlap);
1036 if (winetest_debug > 1) trace("Server ReadFile returned...\n");
1037 err = GetLastError();
1038 ok(success || err == ERROR_IO_PENDING, "overlapped ReadFile\n");
1039 if (winetest_debug > 1) trace("overlapped ReadFile returned.\n");
1040 if (!success && (err == ERROR_IO_PENDING)) {
1041 if (letWFSOEwait)
1043 DWORD ret;
1044 do {
1045 ret = WaitForSingleObjectEx(hEvent, INFINITE, TRUE);
1046 } while (ret == WAIT_IO_COMPLETION);
1047 ok(ret == 0, "wait ReadFile returned %x\n", ret);
1049 success = GetOverlappedResult(hnp, &oOverlap, &readden, letGORwait);
1050 if (!letGORwait && !letWFSOEwait && !success) {
1051 ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult\n");
1052 success = GetOverlappedResult(hnp, &oOverlap, &readden, TRUE);
1055 if (winetest_debug > 1) trace("Server done reading.\n");
1056 ok(success, "overlapped ReadFile\n");
1058 if (winetest_debug > 1) trace("Server writing...\n");
1059 success = WriteFile(hnp, buf, readden, &written, &oOverlap);
1060 if (winetest_debug > 1) trace("Server WriteFile returned...\n");
1061 err = GetLastError();
1062 ok(success || err == ERROR_IO_PENDING, "overlapped WriteFile\n");
1063 if (winetest_debug > 1) trace("overlapped WriteFile returned.\n");
1064 if (!success && (err == ERROR_IO_PENDING)) {
1065 if (letWFSOEwait)
1067 DWORD ret;
1068 do {
1069 ret = WaitForSingleObjectEx(hEvent, INFINITE, TRUE);
1070 } while (ret == WAIT_IO_COMPLETION);
1071 ok(ret == 0, "wait WriteFile returned %x\n", ret);
1073 success = GetOverlappedResult(hnp, &oOverlap, &written, letGORwait);
1074 if (!letGORwait && !letWFSOEwait && !success) {
1075 ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult\n");
1076 success = GetOverlappedResult(hnp, &oOverlap, &written, TRUE);
1079 if (winetest_debug > 1) trace("Server done writing.\n");
1080 ok(success, "overlapped WriteFile\n");
1081 ok(written == readden, "write file len\n");
1083 /* finish this connection, wait for next one */
1084 ok(FlushFileBuffers(hnp), "FlushFileBuffers\n");
1085 ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n");
1087 return 0;
1090 /** Trivial byte echo server - uses i/o completion ports */
1091 static DWORD CALLBACK serverThreadMain4(LPVOID arg)
1093 int i;
1094 HANDLE hcompletion;
1095 BOOL ret;
1097 if (winetest_debug > 1) trace("serverThreadMain4\n");
1098 /* Set up a simple echo server */
1099 hnp = CreateNamedPipeA(PIPENAME "serverThreadMain4", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
1100 PIPE_TYPE_BYTE | PIPE_WAIT,
1101 /* nMaxInstances */ 1,
1102 /* nOutBufSize */ 1024,
1103 /* nInBufSize */ 1024,
1104 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
1105 /* lpSecurityAttrib */ NULL);
1106 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
1108 hcompletion = CreateIoCompletionPort(hnp, NULL, 12345, 1);
1109 ok(hcompletion != NULL, "CreateIoCompletionPort failed, error=%i\n", GetLastError());
1111 for (i = 0; i < NB_SERVER_LOOPS; i++) {
1112 char buf[512];
1113 DWORD written;
1114 DWORD readden;
1115 DWORD dummy;
1116 BOOL success;
1117 OVERLAPPED oConnect;
1118 OVERLAPPED oRead;
1119 OVERLAPPED oWrite;
1120 OVERLAPPED *oResult;
1121 DWORD err;
1122 ULONG_PTR compkey;
1124 memset(&oConnect, 0, sizeof(oConnect));
1125 memset(&oRead, 0, sizeof(oRead));
1126 memset(&oWrite, 0, sizeof(oWrite));
1128 /* Wait for client to connect */
1129 if (winetest_debug > 1) trace("Server calling overlapped ConnectNamedPipe...\n");
1130 success = ConnectNamedPipe(hnp, &oConnect);
1131 err = GetLastError();
1132 ok(!success && (err == ERROR_IO_PENDING || err == ERROR_PIPE_CONNECTED),
1133 "overlapped ConnectNamedPipe got %u err %u\n", success, err );
1134 if (!success && err == ERROR_IO_PENDING) {
1135 if (winetest_debug > 1) trace("ConnectNamedPipe GetQueuedCompletionStatus\n");
1136 success = GetQueuedCompletionStatus(hcompletion, &dummy, &compkey, &oResult, 0);
1137 if (!success)
1139 ok( GetLastError() == WAIT_TIMEOUT,
1140 "ConnectNamedPipe GetQueuedCompletionStatus wrong error %u\n", GetLastError());
1141 success = GetQueuedCompletionStatus(hcompletion, &dummy, &compkey, &oResult, 10000);
1143 ok(success, "ConnectNamedPipe GetQueuedCompletionStatus failed, errno=%i\n", GetLastError());
1144 if (success)
1146 ok(compkey == 12345, "got completion key %i instead of 12345\n", (int)compkey);
1147 ok(oResult == &oConnect, "got overlapped pointer %p instead of %p\n", oResult, &oConnect);
1150 if (winetest_debug > 1) trace("overlapped ConnectNamedPipe operation complete.\n");
1152 /* Echo bytes once */
1153 memset(buf, 0, sizeof(buf));
1155 if (winetest_debug > 1) trace("Server reading...\n");
1156 success = ReadFile(hnp, buf, sizeof(buf), &readden, &oRead);
1157 if (winetest_debug > 1) trace("Server ReadFile returned...\n");
1158 err = GetLastError();
1159 ok(success || err == ERROR_IO_PENDING, "overlapped ReadFile, err=%i\n", err);
1160 success = GetQueuedCompletionStatus(hcompletion, &readden, &compkey,
1161 &oResult, 10000);
1162 ok(success, "ReadFile GetQueuedCompletionStatus failed, errno=%i\n", GetLastError());
1163 if (success)
1165 ok(compkey == 12345, "got completion key %i instead of 12345\n", (int)compkey);
1166 ok(oResult == &oRead, "got overlapped pointer %p instead of %p\n", oResult, &oRead);
1168 if (winetest_debug > 1) trace("Server done reading.\n");
1170 if (winetest_debug > 1) trace("Server writing...\n");
1171 success = WriteFile(hnp, buf, readden, &written, &oWrite);
1172 if (winetest_debug > 1) trace("Server WriteFile returned...\n");
1173 err = GetLastError();
1174 ok(success || err == ERROR_IO_PENDING, "overlapped WriteFile failed, err=%u\n", err);
1175 success = GetQueuedCompletionStatus(hcompletion, &written, &compkey,
1176 &oResult, 10000);
1177 ok(success, "WriteFile GetQueuedCompletionStatus failed, errno=%i\n", GetLastError());
1178 if (success)
1180 ok(compkey == 12345, "got completion key %i instead of 12345\n", (int)compkey);
1181 ok(oResult == &oWrite, "got overlapped pointer %p instead of %p\n", oResult, &oWrite);
1182 ok(written == readden, "write file len\n");
1184 if (winetest_debug > 1) trace("Server done writing.\n");
1186 /* Client will finish this connection, the following ops will trigger broken pipe errors. */
1188 /* Wait for the pipe to break. */
1189 while (PeekNamedPipe(hnp, NULL, 0, NULL, &written, &written));
1191 if (winetest_debug > 1) trace("Server writing on disconnected pipe...\n");
1192 SetLastError(ERROR_SUCCESS);
1193 success = WriteFile(hnp, buf, readden, &written, &oWrite);
1194 err = GetLastError();
1195 ok(!success && err == ERROR_NO_DATA,
1196 "overlapped WriteFile on disconnected pipe returned %u, err=%i\n", success, err);
1198 /* No completion status is queued on immediate error. */
1199 SetLastError(ERROR_SUCCESS);
1200 oResult = (OVERLAPPED *)0xdeadbeef;
1201 success = GetQueuedCompletionStatus(hcompletion, &written, &compkey,
1202 &oResult, 0);
1203 err = GetLastError();
1204 ok(!success && err == WAIT_TIMEOUT && !oResult,
1205 "WriteFile GetQueuedCompletionStatus returned %u, err=%i, oResult %p\n",
1206 success, err, oResult);
1208 if (winetest_debug > 1) trace("Server reading from disconnected pipe...\n");
1209 SetLastError(ERROR_SUCCESS);
1210 success = ReadFile(hnp, buf, sizeof(buf), &readden, &oRead);
1211 if (winetest_debug > 1) trace("Server ReadFile from disconnected pipe returned...\n");
1212 err = GetLastError();
1213 ok(!success && err == ERROR_BROKEN_PIPE,
1214 "overlapped ReadFile on disconnected pipe returned %u, err=%i\n", success, err);
1216 SetLastError(ERROR_SUCCESS);
1217 oResult = (OVERLAPPED *)0xdeadbeef;
1218 success = GetQueuedCompletionStatus(hcompletion, &readden, &compkey,
1219 &oResult, 0);
1220 err = GetLastError();
1221 ok(!success && err == WAIT_TIMEOUT && !oResult,
1222 "ReadFile GetQueuedCompletionStatus returned %u, err=%i, oResult %p\n",
1223 success, err, oResult);
1225 /* finish this connection, wait for next one */
1226 ok(FlushFileBuffers(hnp), "FlushFileBuffers\n");
1227 success = DisconnectNamedPipe(hnp);
1228 ok(success, "DisconnectNamedPipe failed, err %u\n", GetLastError());
1231 ret = CloseHandle(hnp);
1232 ok(ret, "CloseHandle named pipe failed, err=%i\n", GetLastError());
1233 ret = CloseHandle(hcompletion);
1234 ok(ret, "CloseHandle completion failed, err=%i\n", GetLastError());
1236 return 0;
1239 static int completion_called;
1240 static DWORD completion_errorcode;
1241 static DWORD completion_num_bytes;
1242 static LPOVERLAPPED completion_lpoverlapped;
1244 static VOID WINAPI completion_routine(DWORD errorcode, DWORD num_bytes, LPOVERLAPPED lpoverlapped)
1246 completion_called++;
1247 completion_errorcode = errorcode;
1248 completion_num_bytes = num_bytes;
1249 completion_lpoverlapped = lpoverlapped;
1250 SetEvent(lpoverlapped->hEvent);
1253 /** Trivial byte echo server - uses ReadFileEx/WriteFileEx */
1254 static DWORD CALLBACK serverThreadMain5(LPVOID arg)
1256 int i;
1257 HANDLE hEvent;
1259 if (winetest_debug > 1) trace("serverThreadMain5\n");
1260 /* Set up a simple echo server */
1261 hnp = CreateNamedPipeA(PIPENAME "serverThreadMain5", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
1262 PIPE_TYPE_BYTE | PIPE_WAIT,
1263 /* nMaxInstances */ 1,
1264 /* nOutBufSize */ 1024,
1265 /* nInBufSize */ 1024,
1266 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
1267 /* lpSecurityAttrib */ NULL);
1268 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
1270 hEvent = CreateEventW(NULL, /* security attribute */
1271 TRUE, /* manual reset event */
1272 FALSE, /* initial state */
1273 NULL); /* name */
1274 ok(hEvent != NULL, "CreateEvent\n");
1276 for (i = 0; i < NB_SERVER_LOOPS; i++) {
1277 char buf[512];
1278 DWORD readden;
1279 BOOL success;
1280 OVERLAPPED oOverlap;
1281 DWORD err;
1283 memset(&oOverlap, 0, sizeof(oOverlap));
1284 oOverlap.hEvent = hEvent;
1286 /* Wait for client to connect */
1287 if (winetest_debug > 1) trace("Server calling ConnectNamedPipe...\n");
1288 success = ConnectNamedPipe(hnp, NULL);
1289 err = GetLastError();
1290 ok(success || (err == ERROR_PIPE_CONNECTED), "ConnectNamedPipe failed: %d\n", err);
1291 if (winetest_debug > 1) trace("ConnectNamedPipe operation complete.\n");
1293 /* Echo bytes once */
1294 memset(buf, 0, sizeof(buf));
1296 if (winetest_debug > 1) trace("Server reading...\n");
1297 completion_called = 0;
1298 ResetEvent(hEvent);
1299 success = ReadFileEx(hnp, buf, sizeof(buf), &oOverlap, completion_routine);
1300 if (winetest_debug > 1) trace("Server ReadFileEx returned...\n");
1301 ok(success, "ReadFileEx failed, err=%i\n", GetLastError());
1302 ok(completion_called == 0, "completion routine called before ReadFileEx return\n");
1303 if (winetest_debug > 1) trace("ReadFileEx returned.\n");
1304 if (success) {
1305 DWORD ret;
1306 do {
1307 ret = WaitForSingleObjectEx(hEvent, INFINITE, TRUE);
1308 } while (ret == WAIT_IO_COMPLETION);
1309 ok(ret == 0, "wait ReadFileEx returned %x\n", ret);
1311 ok(completion_called == 1, "completion routine called %i times\n", completion_called);
1312 ok(completion_errorcode == ERROR_SUCCESS, "completion routine got error %d\n", completion_errorcode);
1313 ok(completion_num_bytes != 0, "read 0 bytes\n");
1314 ok(completion_lpoverlapped == &oOverlap, "got wrong overlapped pointer %p\n", completion_lpoverlapped);
1315 readden = completion_num_bytes;
1316 if (winetest_debug > 1) trace("Server done reading.\n");
1318 if (winetest_debug > 1) trace("Server writing...\n");
1319 completion_called = 0;
1320 ResetEvent(hEvent);
1321 success = WriteFileEx(hnp, buf, readden, &oOverlap, completion_routine);
1322 if (winetest_debug > 1) trace("Server WriteFileEx returned...\n");
1323 ok(success, "WriteFileEx failed, err=%i\n", GetLastError());
1324 ok(completion_called == 0, "completion routine called before ReadFileEx return\n");
1325 if (winetest_debug > 1) trace("overlapped WriteFile returned.\n");
1326 if (success) {
1327 DWORD ret;
1328 do {
1329 ret = WaitForSingleObjectEx(hEvent, INFINITE, TRUE);
1330 } while (ret == WAIT_IO_COMPLETION);
1331 ok(ret == 0, "wait WriteFileEx returned %x\n", ret);
1333 if (winetest_debug > 1) trace("Server done writing.\n");
1334 ok(completion_called == 1, "completion routine called %i times\n", completion_called);
1335 ok(completion_errorcode == ERROR_SUCCESS, "completion routine got error %d\n", completion_errorcode);
1336 ok(completion_num_bytes == readden, "read %i bytes wrote %i\n", readden, completion_num_bytes);
1337 ok(completion_lpoverlapped == &oOverlap, "got wrong overlapped pointer %p\n", completion_lpoverlapped);
1339 /* finish this connection, wait for next one */
1340 ok(FlushFileBuffers(hnp), "FlushFileBuffers\n");
1341 ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n");
1343 return 0;
1346 static void exercizeServer(const char *pipename, HANDLE serverThread)
1348 int i;
1350 if (winetest_debug > 1) trace("exercizeServer starting\n");
1351 for (i = 0; i < NB_SERVER_LOOPS; i++) {
1352 HANDLE hFile=INVALID_HANDLE_VALUE;
1353 static const char obuf[] = "Bit Bucket";
1354 char ibuf[32];
1355 DWORD written;
1356 DWORD readden;
1357 int loop;
1359 for (loop = 0; loop < 3; loop++) {
1360 DWORD err;
1361 if (winetest_debug > 1) trace("Client connecting...\n");
1362 /* Connect to the server */
1363 hFile = CreateFileA(pipename, GENERIC_READ | GENERIC_WRITE, 0,
1364 NULL, OPEN_EXISTING, 0, 0);
1365 if (hFile != INVALID_HANDLE_VALUE)
1366 break;
1367 err = GetLastError();
1368 if (loop == 0)
1369 ok(err == ERROR_PIPE_BUSY || err == ERROR_FILE_NOT_FOUND, "connecting to pipe\n");
1370 else
1371 ok(err == ERROR_PIPE_BUSY, "connecting to pipe\n");
1372 if (winetest_debug > 1) trace("connect failed, retrying\n");
1373 Sleep(200);
1375 ok(hFile != INVALID_HANDLE_VALUE, "client opening named pipe\n");
1377 /* Make sure it can echo */
1378 memset(ibuf, 0, sizeof(ibuf));
1379 if (winetest_debug > 1) trace("Client writing...\n");
1380 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile to client end of pipe\n");
1381 ok(written == sizeof(obuf), "write file len\n");
1382 if (winetest_debug > 1) trace("Client reading...\n");
1383 ok(ReadFile(hFile, ibuf, sizeof(obuf), &readden, NULL), "ReadFile from client end of pipe\n");
1384 ok(readden == sizeof(obuf), "read file len\n");
1385 ok(memcmp(obuf, ibuf, written) == 0, "content check\n");
1387 if (winetest_debug > 1) trace("Client closing...\n");
1388 ok(CloseHandle(hFile), "CloseHandle\n");
1391 ok(WaitForSingleObject(serverThread,INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject\n");
1392 CloseHandle(hnp);
1393 if (winetest_debug > 1) trace("exercizeServer returning\n");
1396 static void test_NamedPipe_2(void)
1398 HANDLE serverThread;
1399 DWORD serverThreadId;
1400 HANDLE alarmThread;
1401 DWORD alarmThreadId;
1403 trace("test_NamedPipe_2 starting\n");
1404 /* Set up a twenty second timeout */
1405 alarm_event = CreateEventW( NULL, TRUE, FALSE, NULL );
1406 SetLastError(0xdeadbeef);
1407 alarmThread = CreateThread(NULL, 0, alarmThreadMain, (void *) 20000, 0, &alarmThreadId);
1408 ok(alarmThread != NULL, "CreateThread failed: %d\n", GetLastError());
1410 /* The servers we're about to exercise do try to clean up carefully,
1411 * but to reduce the chance of a test failure due to a pipe handle
1412 * leak in the test code, we'll use a different pipe name for each server.
1415 /* Try server #1 */
1416 SetLastError(0xdeadbeef);
1417 serverThread = CreateThread(NULL, 0, serverThreadMain1, (void *)8, 0, &serverThreadId);
1418 ok(serverThread != NULL, "CreateThread failed: %d\n", GetLastError());
1419 exercizeServer(PIPENAME "serverThreadMain1", serverThread);
1421 /* Try server #2 */
1422 SetLastError(0xdeadbeef);
1423 serverThread = CreateThread(NULL, 0, serverThreadMain2, 0, 0, &serverThreadId);
1424 ok(serverThread != NULL, "CreateThread failed: %d\n", GetLastError());
1425 exercizeServer(PIPENAME "serverThreadMain2", serverThread);
1427 /* Try server #3 */
1428 SetLastError(0xdeadbeef);
1429 serverThread = CreateThread(NULL, 0, serverThreadMain3, 0, 0, &serverThreadId);
1430 ok(serverThread != NULL, "CreateThread failed: %d\n", GetLastError());
1431 exercizeServer(PIPENAME "serverThreadMain3", serverThread);
1433 /* Try server #4 */
1434 SetLastError(0xdeadbeef);
1435 serverThread = CreateThread(NULL, 0, serverThreadMain4, 0, 0, &serverThreadId);
1436 ok(serverThread != NULL, "CreateThread failed: %d\n", GetLastError());
1437 exercizeServer(PIPENAME "serverThreadMain4", serverThread);
1439 /* Try server #5 */
1440 SetLastError(0xdeadbeef);
1441 serverThread = CreateThread(NULL, 0, serverThreadMain5, 0, 0, &serverThreadId);
1442 ok(serverThread != NULL, "CreateThread failed: %d\n", GetLastError());
1443 exercizeServer(PIPENAME "serverThreadMain5", serverThread);
1445 ok(SetEvent( alarm_event ), "SetEvent\n");
1446 CloseHandle( alarm_event );
1447 if (winetest_debug > 1) trace("test_NamedPipe_2 returning\n");
1450 static int test_DisconnectNamedPipe(void)
1452 HANDLE hnp;
1453 HANDLE hFile;
1454 static const char obuf[] = "Bit Bucket";
1455 char ibuf[32];
1456 DWORD written;
1457 DWORD readden;
1458 DWORD ret;
1460 SetLastError(0xdeadbeef);
1461 hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
1462 /* nMaxInstances */ 1,
1463 /* nOutBufSize */ 1024,
1464 /* nInBufSize */ 1024,
1465 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
1466 /* lpSecurityAttrib */ NULL);
1467 if ((hnp == INVALID_HANDLE_VALUE /* Win98 */ || !hnp /* Win95 */)
1468 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) {
1470 win_skip("Named pipes are not implemented\n");
1471 return 1;
1474 ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL) == 0
1475 && GetLastError() == ERROR_PIPE_LISTENING, "WriteFile to not-yet-connected pipe\n");
1476 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL) == 0
1477 && GetLastError() == ERROR_PIPE_LISTENING, "ReadFile from not-yet-connected pipe\n");
1479 hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
1480 ok(hFile != INVALID_HANDLE_VALUE, "CreateFile failed\n");
1482 /* don't try to do i/o if one side couldn't be opened, as it hangs */
1483 if (hFile != INVALID_HANDLE_VALUE) {
1485 /* see what happens if server calls DisconnectNamedPipe
1486 * when there are bytes in the pipe
1489 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile\n");
1490 ok(written == sizeof(obuf), "write file len\n");
1491 ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe while messages waiting\n");
1492 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL) == 0
1493 && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "WriteFile to disconnected pipe\n");
1494 ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL) == 0
1495 && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "WriteFile to disconnected pipe\n");
1496 ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL) == 0
1497 && GetLastError() == ERROR_PIPE_NOT_CONNECTED,
1498 "ReadFile from disconnected pipe with bytes waiting\n");
1499 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL) == 0
1500 && GetLastError() == ERROR_PIPE_NOT_CONNECTED,
1501 "ReadFile from disconnected pipe with bytes waiting\n");
1503 ok(!DisconnectNamedPipe(hnp) && GetLastError() == ERROR_PIPE_NOT_CONNECTED,
1504 "DisconnectNamedPipe worked twice\n");
1505 ret = WaitForSingleObject(hFile, 0);
1506 ok(ret == WAIT_TIMEOUT, "WaitForSingleObject returned %X\n", ret);
1508 ret = PeekNamedPipe(hFile, NULL, 0, NULL, &readden, NULL);
1509 ok(!ret && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "PeekNamedPipe returned %x (%u)\n",
1510 ret, GetLastError());
1511 ret = PeekNamedPipe(hnp, NULL, 0, NULL, &readden, NULL);
1512 ok(!ret && GetLastError() == ERROR_BAD_PIPE, "PeekNamedPipe returned %x (%u)\n",
1513 ret, GetLastError());
1514 ok(CloseHandle(hFile), "CloseHandle\n");
1517 ok(CloseHandle(hnp), "CloseHandle\n");
1519 return 0;
1521 static void test_CreatePipe(void)
1523 SECURITY_ATTRIBUTES pipe_attr;
1524 HANDLE piperead, pipewrite;
1525 DWORD written;
1526 DWORD read;
1527 DWORD i, size;
1528 BYTE *buffer;
1529 char readbuf[32];
1531 user_apc_ran = FALSE;
1532 if (pQueueUserAPC)
1533 ok(pQueueUserAPC(user_apc, GetCurrentThread(), 0), "couldn't create user apc\n");
1535 pipe_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
1536 pipe_attr.bInheritHandle = TRUE;
1537 pipe_attr.lpSecurityDescriptor = NULL;
1538 ok(CreatePipe(&piperead, &pipewrite, &pipe_attr, 0) != 0, "CreatePipe failed\n");
1539 test_pipe_info(piperead, FILE_PIPE_SERVER_END, 4096, 4096, 1);
1540 test_pipe_info(pipewrite, 0, 4096, 4096, 1);
1541 test_file_access(piperead, SYNCHRONIZE | READ_CONTROL | FILE_WRITE_ATTRIBUTES
1542 | FILE_READ_ATTRIBUTES | FILE_READ_PROPERTIES | FILE_READ_DATA);
1543 test_file_access(pipewrite, SYNCHRONIZE | READ_CONTROL | FILE_WRITE_ATTRIBUTES
1544 | FILE_READ_ATTRIBUTES | FILE_WRITE_PROPERTIES | FILE_APPEND_DATA
1545 | FILE_WRITE_DATA);
1547 ok(WriteFile(pipewrite,PIPENAME,sizeof(PIPENAME), &written, NULL), "Write to anonymous pipe failed\n");
1548 ok(written == sizeof(PIPENAME), "Write to anonymous pipe wrote %d bytes\n", written);
1549 ok(ReadFile(piperead,readbuf,sizeof(readbuf),&read, NULL), "Read from non empty pipe failed\n");
1550 ok(read == sizeof(PIPENAME), "Read from anonymous pipe got %d bytes\n", read);
1551 ok(CloseHandle(pipewrite), "CloseHandle for the write pipe failed\n");
1552 ok(CloseHandle(piperead), "CloseHandle for the read pipe failed\n");
1554 /* Now write another chunk*/
1555 ok(CreatePipe(&piperead, &pipewrite, &pipe_attr, 0) != 0, "CreatePipe failed\n");
1556 ok(WriteFile(pipewrite,PIPENAME,sizeof(PIPENAME), &written, NULL), "Write to anonymous pipe failed\n");
1557 ok(written == sizeof(PIPENAME), "Write to anonymous pipe wrote %d bytes\n", written);
1558 /* and close the write end, read should still succeed*/
1559 ok(CloseHandle(pipewrite), "CloseHandle for the Write Pipe failed\n");
1560 ok(ReadFile(piperead,readbuf,sizeof(readbuf),&read, NULL), "Read from broken pipe with pending data failed\n");
1561 ok(read == sizeof(PIPENAME), "Read from anonymous pipe got %d bytes\n", read);
1562 /* But now we need to get informed that the pipe is closed */
1563 ok(ReadFile(piperead,readbuf,sizeof(readbuf),&read, NULL) == 0, "Broken pipe not detected\n");
1564 ok(CloseHandle(piperead), "CloseHandle for the read pipe failed\n");
1566 /* Try bigger chunks */
1567 size = 32768;
1568 buffer = HeapAlloc( GetProcessHeap(), 0, size );
1569 for (i = 0; i < size; i++) buffer[i] = i;
1570 ok(CreatePipe(&piperead, &pipewrite, &pipe_attr, (size + 24)) != 0, "CreatePipe failed\n");
1571 ok(WriteFile(pipewrite, buffer, size, &written, NULL), "Write to anonymous pipe failed\n");
1572 ok(written == size, "Write to anonymous pipe wrote %d bytes\n", written);
1573 /* and close the write end, read should still succeed*/
1574 ok(CloseHandle(pipewrite), "CloseHandle for the Write Pipe failed\n");
1575 memset( buffer, 0, size );
1576 ok(ReadFile(piperead, buffer, size, &read, NULL), "Read from broken pipe with pending data failed\n");
1577 ok(read == size, "Read from anonymous pipe got %d bytes\n", read);
1578 for (i = 0; i < size; i++) ok( buffer[i] == (BYTE)i, "invalid data %x at %x\n", buffer[i], i );
1579 /* But now we need to get informed that the pipe is closed */
1580 ok(ReadFile(piperead,readbuf,sizeof(readbuf),&read, NULL) == 0, "Broken pipe not detected\n");
1581 ok(CloseHandle(piperead), "CloseHandle for the read pipe failed\n");
1582 HeapFree(GetProcessHeap(), 0, buffer);
1584 ok(user_apc_ran == FALSE, "user apc ran, pipe using alertable io mode\n");
1585 SleepEx(0, TRUE); /* get rid of apc */
1587 ok(CreatePipe(&piperead, &pipewrite, &pipe_attr, 1) != 0, "CreatePipe failed\n");
1588 test_pipe_info(piperead, FILE_PIPE_SERVER_END, 1, 1, 1);
1589 test_pipe_info(pipewrite, 0, 1, 1, 1);
1590 ok(CloseHandle(pipewrite), "CloseHandle for the Write Pipe failed\n");
1591 ok(CloseHandle(piperead), "CloseHandle for the read pipe failed\n");
1594 static void test_CloseHandle(void)
1596 static const char testdata[] = "Hello World";
1597 DWORD state, numbytes;
1598 HANDLE hpipe, hfile;
1599 char buffer[32];
1600 BOOL ret;
1602 hpipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX,
1603 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
1604 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL);
1605 ok(hpipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %u\n", GetLastError());
1607 hfile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
1608 ok(hfile != INVALID_HANDLE_VALUE, "CreateFile failed with %u\n", GetLastError());
1610 numbytes = 0xdeadbeef;
1611 ret = WriteFile(hpipe, testdata, sizeof(testdata), &numbytes, NULL);
1612 ok(ret, "WriteFile failed with %u\n", GetLastError());
1613 ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes);
1615 numbytes = 0xdeadbeef;
1616 ret = PeekNamedPipe(hfile, NULL, 0, NULL, &numbytes, NULL);
1617 ok(ret, "PeekNamedPipe failed with %u\n", GetLastError());
1618 ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes);
1620 ret = CloseHandle(hpipe);
1621 ok(ret, "CloseHandle failed with %u\n", GetLastError());
1623 numbytes = 0xdeadbeef;
1624 memset(buffer, 0, sizeof(buffer));
1625 ret = ReadFile(hfile, buffer, 0, &numbytes, NULL);
1626 ok(ret, "ReadFile failed with %u\n", GetLastError());
1627 ok(numbytes == 0, "expected 0, got %u\n", numbytes);
1629 numbytes = 0xdeadbeef;
1630 ret = PeekNamedPipe(hfile, NULL, 0, NULL, &numbytes, NULL);
1631 ok(ret, "PeekNamedPipe failed with %u\n", GetLastError());
1632 ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes);
1634 numbytes = 0xdeadbeef;
1635 memset(buffer, 0, sizeof(buffer));
1636 ret = ReadFile(hfile, buffer, sizeof(buffer), &numbytes, NULL);
1637 ok(ret, "ReadFile failed with %u\n", GetLastError());
1638 ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes);
1640 ret = GetNamedPipeHandleStateA(hfile, &state, NULL, NULL, NULL, NULL, 0);
1641 ok(ret, "GetNamedPipeHandleState failed with %u\n", GetLastError());
1642 state = PIPE_READMODE_MESSAGE | PIPE_WAIT;
1643 ret = SetNamedPipeHandleState(hfile, &state, NULL, NULL);
1644 ok(ret, "SetNamedPipeHandleState failed with %u\n", GetLastError());
1646 SetLastError(0xdeadbeef);
1647 ret = ReadFile(hfile, buffer, 0, &numbytes, NULL);
1648 ok(!ret, "ReadFile unexpectedly succeeded\n");
1649 ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1651 numbytes = 0xdeadbeef;
1652 ret = PeekNamedPipe(hfile, NULL, 0, NULL, &numbytes, NULL);
1653 ok(!ret && GetLastError() == ERROR_BROKEN_PIPE, "PeekNamedPipe returned %x (%u)\n",
1654 ret, GetLastError());
1655 ok(numbytes == 0xdeadbeef, "numbytes = %u\n", numbytes);
1657 SetLastError(0xdeadbeef);
1658 ret = WriteFile(hfile, testdata, sizeof(testdata), &numbytes, NULL);
1659 ok(!ret, "WriteFile unexpectedly succeeded\n");
1660 ok(GetLastError() == ERROR_NO_DATA, "expected ERROR_NO_DATA, got %u\n", GetLastError());
1662 CloseHandle(hfile);
1664 hpipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX,
1665 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
1666 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL);
1667 ok(hpipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %u\n", GetLastError());
1669 hfile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
1670 ok(hfile != INVALID_HANDLE_VALUE, "CreateFile failed with %u\n", GetLastError());
1672 numbytes = 0xdeadbeef;
1673 ret = WriteFile(hpipe, testdata, 0, &numbytes, NULL);
1674 ok(ret, "WriteFile failed with %u\n", GetLastError());
1675 ok(numbytes == 0, "expected 0, got %u\n", numbytes);
1677 ret = CloseHandle(hpipe);
1678 ok(ret, "CloseHandle failed with %u\n", GetLastError());
1680 numbytes = 0xdeadbeef;
1681 memset(buffer, 0, sizeof(buffer));
1682 ret = ReadFile(hfile, buffer, sizeof(buffer), &numbytes, NULL);
1683 ok(ret, "ReadFile failed with %u\n", GetLastError());
1684 ok(numbytes == 0, "expected 0, got %u\n", numbytes);
1686 SetLastError(0xdeadbeef);
1687 ret = ReadFile(hfile, buffer, 0, &numbytes, NULL);
1688 ok(!ret, "ReadFile unexpectedly succeeded\n");
1689 ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1691 ret = GetNamedPipeHandleStateA(hfile, &state, NULL, NULL, NULL, NULL, 0);
1692 ok(ret, "GetNamedPipeHandleState failed with %u\n", GetLastError());
1693 state = PIPE_READMODE_MESSAGE | PIPE_WAIT;
1694 ret = SetNamedPipeHandleState(hfile, &state, NULL, NULL);
1695 ok(ret, "SetNamedPipeHandleState failed with %u\n", GetLastError());
1697 SetLastError(0xdeadbeef);
1698 ret = ReadFile(hfile, buffer, 0, &numbytes, NULL);
1699 ok(!ret, "ReadFile unexpectedly succeeded\n");
1700 ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1702 SetLastError(0xdeadbeef);
1703 ret = WriteFile(hfile, testdata, sizeof(testdata), &numbytes, NULL);
1704 ok(!ret, "WriteFile unexpectedly succeeded\n");
1705 ok(GetLastError() == ERROR_NO_DATA, "expected ERROR_NO_DATA, got %u\n", GetLastError());
1707 CloseHandle(hfile);
1709 /* repeat test with hpipe <-> hfile swapped */
1711 hpipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX,
1712 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
1713 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL);
1714 ok(hpipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %u\n", GetLastError());
1716 hfile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
1717 ok(hfile != INVALID_HANDLE_VALUE, "CreateFile failed with %u\n", GetLastError());
1719 numbytes = 0xdeadbeef;
1720 ret = WriteFile(hfile, testdata, sizeof(testdata), &numbytes, NULL);
1721 ok(ret, "WriteFile failed with %u\n", GetLastError());
1722 ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes);
1724 numbytes = 0xdeadbeef;
1725 ret = PeekNamedPipe(hpipe, NULL, 0, NULL, &numbytes, NULL);
1726 ok(ret, "PeekNamedPipe failed with %u\n", GetLastError());
1727 ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes);
1729 ret = CloseHandle(hfile);
1730 ok(ret, "CloseHandle failed with %u\n", GetLastError());
1732 numbytes = 0xdeadbeef;
1733 memset(buffer, 0, sizeof(buffer));
1734 ret = ReadFile(hpipe, buffer, 0, &numbytes, NULL);
1735 ok(ret || GetLastError() == ERROR_MORE_DATA /* >= Win 8 */,
1736 "ReadFile failed with %u\n", GetLastError());
1737 ok(numbytes == 0, "expected 0, got %u\n", numbytes);
1739 numbytes = 0xdeadbeef;
1740 ret = PeekNamedPipe(hpipe, NULL, 0, NULL, &numbytes, NULL);
1741 ok(ret, "PeekNamedPipe failed with %u\n", GetLastError());
1742 ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes);
1744 numbytes = 0xdeadbeef;
1745 memset(buffer, 0, sizeof(buffer));
1746 ret = ReadFile(hpipe, buffer, sizeof(buffer), &numbytes, NULL);
1747 ok(ret, "ReadFile failed with %u\n", GetLastError());
1748 ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes);
1750 ret = GetNamedPipeHandleStateA(hpipe, &state, NULL, NULL, NULL, NULL, 0);
1751 ok(ret, "GetNamedPipeHandleState failed with %u\n", GetLastError());
1752 state = PIPE_READMODE_MESSAGE | PIPE_WAIT;
1753 ret = SetNamedPipeHandleState(hpipe, &state, NULL, NULL);
1754 ok(ret, "SetNamedPipeHandleState failed with %u\n", GetLastError());
1756 SetLastError(0xdeadbeef);
1757 ret = ReadFile(hpipe, buffer, 0, &numbytes, NULL);
1758 ok(!ret, "ReadFile unexpectedly succeeded\n");
1759 ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1761 numbytes = 0xdeadbeef;
1762 ret = PeekNamedPipe(hpipe, NULL, 0, NULL, &numbytes, NULL);
1763 ok(!ret && GetLastError() == ERROR_BROKEN_PIPE, "PeekNamedPipe returned %x (%u)\n",
1764 ret, GetLastError());
1765 ok(numbytes == 0xdeadbeef, "numbytes = %u\n", numbytes);
1767 SetLastError(0xdeadbeef);
1768 ret = WriteFile(hpipe, testdata, sizeof(testdata), &numbytes, NULL);
1769 ok(!ret, "WriteFile unexpectedly succeeded\n");
1770 ok(GetLastError() == ERROR_NO_DATA, "expected ERROR_NO_DATA, got %u\n", GetLastError());
1772 CloseHandle(hpipe);
1774 hpipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX,
1775 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
1776 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL);
1777 ok(hpipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %u\n", GetLastError());
1779 hfile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
1780 ok(hfile != INVALID_HANDLE_VALUE, "CreateFile failed with %u\n", GetLastError());
1782 numbytes = 0xdeadbeef;
1783 ret = WriteFile(hfile, testdata, 0, &numbytes, NULL);
1784 ok(ret, "WriteFile failed with %u\n", GetLastError());
1785 ok(numbytes == 0, "expected 0, got %u\n", numbytes);
1787 ret = CloseHandle(hfile);
1788 ok(ret, "CloseHandle failed with %u\n", GetLastError());
1790 numbytes = 0xdeadbeef;
1791 memset(buffer, 0, sizeof(buffer));
1792 ret = ReadFile(hpipe, buffer, sizeof(buffer), &numbytes, NULL);
1793 ok(ret, "ReadFile failed with %u\n", GetLastError());
1794 ok(numbytes == 0, "expected 0, got %u\n", numbytes);
1796 SetLastError(0xdeadbeef);
1797 ret = ReadFile(hpipe, buffer, 0, &numbytes, NULL);
1798 ok(!ret, "ReadFile unexpectedly succeeded\n");
1799 ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1801 ret = GetNamedPipeHandleStateA(hpipe, &state, NULL, NULL, NULL, NULL, 0);
1802 ok(ret, "GetNamedPipeHandleState failed with %u\n", GetLastError());
1803 state = PIPE_READMODE_MESSAGE | PIPE_WAIT;
1804 ret = SetNamedPipeHandleState(hpipe, &state, NULL, NULL);
1805 ok(ret, "SetNamedPipeHandleState failed with %u\n", GetLastError());
1807 SetLastError(0xdeadbeef);
1808 ret = ReadFile(hpipe, buffer, 0, &numbytes, NULL);
1809 ok(!ret, "ReadFile unexpectedly succeeded\n");
1810 ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1812 SetLastError(0xdeadbeef);
1813 ret = WriteFile(hpipe, testdata, sizeof(testdata), &numbytes, NULL);
1814 ok(!ret, "WriteFile unexpectedly succeeded\n");
1815 ok(GetLastError() == ERROR_NO_DATA, "expected ERROR_NO_DATA, got %u\n", GetLastError());
1817 CloseHandle(hpipe);
1820 struct named_pipe_client_params
1822 DWORD security_flags;
1823 HANDLE token;
1824 BOOL revert;
1827 #define PIPE_NAME "\\\\.\\pipe\\named_pipe_test"
1829 static DWORD CALLBACK named_pipe_client_func(LPVOID p)
1831 struct named_pipe_client_params *params = p;
1832 HANDLE pipe;
1833 BOOL ret;
1834 const char message[] = "Test";
1835 DWORD bytes_read, bytes_written;
1836 char dummy;
1837 TOKEN_PRIVILEGES *Privileges = NULL;
1839 if (params->token)
1841 if (params->revert)
1843 /* modify the token so we can tell if the pipe impersonation
1844 * token reverts to the process token */
1845 ret = AdjustTokenPrivileges(params->token, TRUE, NULL, 0, NULL, NULL);
1846 ok(ret, "AdjustTokenPrivileges failed with error %d\n", GetLastError());
1848 ret = SetThreadToken(NULL, params->token);
1849 ok(ret, "SetThreadToken failed with error %d\n", GetLastError());
1851 else
1853 DWORD Size = 0;
1854 HANDLE process_token;
1856 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES, &process_token);
1857 ok(ret, "OpenProcessToken failed with error %d\n", GetLastError());
1859 ret = GetTokenInformation(process_token, TokenPrivileges, NULL, 0, &Size);
1860 ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetTokenInformation(TokenPrivileges) failed with %d\n", GetLastError());
1861 Privileges = HeapAlloc(GetProcessHeap(), 0, Size);
1862 ret = GetTokenInformation(process_token, TokenPrivileges, Privileges, Size, &Size);
1863 ok(ret, "GetTokenInformation(TokenPrivileges) failed with %d\n", GetLastError());
1865 ret = AdjustTokenPrivileges(process_token, TRUE, NULL, 0, NULL, NULL);
1866 ok(ret, "AdjustTokenPrivileges failed with error %d\n", GetLastError());
1868 CloseHandle(process_token);
1871 pipe = CreateFileA(PIPE_NAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, params->security_flags, NULL);
1872 ok(pipe != INVALID_HANDLE_VALUE, "CreateFile for pipe failed with error %d\n", GetLastError());
1874 ret = WriteFile(pipe, message, sizeof(message), &bytes_written, NULL);
1875 ok(ret, "WriteFile failed with error %d\n", GetLastError());
1877 ret = ReadFile(pipe, &dummy, sizeof(dummy), &bytes_read, NULL);
1878 ok(ret, "ReadFile failed with error %d\n", GetLastError());
1880 if (params->token)
1882 if (params->revert)
1884 ret = RevertToSelf();
1885 ok(ret, "RevertToSelf failed with error %d\n", GetLastError());
1887 else
1889 ret = AdjustTokenPrivileges(params->token, TRUE, NULL, 0, NULL, NULL);
1890 ok(ret, "AdjustTokenPrivileges failed with error %d\n", GetLastError());
1893 else
1895 HANDLE process_token;
1897 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &process_token);
1898 ok(ret, "OpenProcessToken failed with error %d\n", GetLastError());
1900 ret = AdjustTokenPrivileges(process_token, FALSE, Privileges, 0, NULL, NULL);
1901 ok(ret, "AdjustTokenPrivileges failed with error %d\n", GetLastError());
1903 HeapFree(GetProcessHeap(), 0, Privileges);
1905 CloseHandle(process_token);
1908 ret = WriteFile(pipe, message, sizeof(message), &bytes_written, NULL);
1909 ok(ret, "WriteFile failed with error %d\n", GetLastError());
1911 ret = ReadFile(pipe, &dummy, sizeof(dummy), &bytes_read, NULL);
1912 ok(ret, "ReadFile failed with error %d\n", GetLastError());
1914 CloseHandle(pipe);
1916 return 0;
1919 static HANDLE make_impersonation_token(DWORD Access, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
1921 HANDLE ProcessToken;
1922 HANDLE Token = NULL;
1923 BOOL ret;
1925 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &ProcessToken);
1926 ok(ret, "OpenProcessToken failed with error %d\n", GetLastError());
1928 ret = pDuplicateTokenEx(ProcessToken, Access, NULL, ImpersonationLevel, TokenImpersonation, &Token);
1929 ok(ret, "DuplicateToken failed with error %d\n", GetLastError());
1931 CloseHandle(ProcessToken);
1933 return Token;
1936 static void test_ImpersonateNamedPipeClient(HANDLE hClientToken, DWORD security_flags, BOOL revert, void (*test_func)(int, HANDLE))
1938 HANDLE hPipeServer;
1939 BOOL ret;
1940 DWORD dwTid;
1941 HANDLE hThread;
1942 char buffer[256];
1943 DWORD dwBytesRead;
1944 DWORD error;
1945 struct named_pipe_client_params params;
1946 char dummy = 0;
1947 DWORD dwBytesWritten;
1948 HANDLE hToken = NULL;
1949 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
1950 DWORD size;
1952 hPipeServer = CreateNamedPipeA(PIPE_NAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 100, 100, NMPWAIT_USE_DEFAULT_WAIT, NULL);
1953 ok(hPipeServer != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with error %d\n", GetLastError());
1955 params.security_flags = security_flags;
1956 params.token = hClientToken;
1957 params.revert = revert;
1958 hThread = CreateThread(NULL, 0, named_pipe_client_func, &params, 0, &dwTid);
1959 ok(hThread != NULL, "CreateThread failed with error %d\n", GetLastError());
1961 SetLastError(0xdeadbeef);
1962 ret = ImpersonateNamedPipeClient(hPipeServer);
1963 error = GetLastError();
1964 ok(ret /* win2k3 */ || (error == ERROR_CANNOT_IMPERSONATE),
1965 "ImpersonateNamedPipeClient should have failed with ERROR_CANNOT_IMPERSONATE instead of %d\n", GetLastError());
1967 ret = ConnectNamedPipe(hPipeServer, NULL);
1968 ok(ret || (GetLastError() == ERROR_PIPE_CONNECTED), "ConnectNamedPipe failed with error %d\n", GetLastError());
1970 ret = ReadFile(hPipeServer, buffer, sizeof(buffer), &dwBytesRead, NULL);
1971 ok(ret, "ReadFile failed with error %d\n", GetLastError());
1973 ret = ImpersonateNamedPipeClient(hPipeServer);
1974 ok(ret, "ImpersonateNamedPipeClient failed with error %d\n", GetLastError());
1976 ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken);
1977 ok(ret, "OpenThreadToken failed with error %d\n", GetLastError());
1979 (*test_func)(0, hToken);
1981 ImpersonationLevel = 0xdeadbeef; /* to avoid false positives */
1982 ret = GetTokenInformation(hToken, TokenImpersonationLevel, &ImpersonationLevel, sizeof(ImpersonationLevel), &size);
1983 ok(ret, "GetTokenInformation(TokenImpersonationLevel) failed with error %d\n", GetLastError());
1984 ok(ImpersonationLevel == SecurityImpersonation, "ImpersonationLevel should have been SecurityImpersonation(%d) instead of %d\n", SecurityImpersonation, ImpersonationLevel);
1986 CloseHandle(hToken);
1988 RevertToSelf();
1990 ret = WriteFile(hPipeServer, &dummy, sizeof(dummy), &dwBytesWritten, NULL);
1991 ok(ret, "WriteFile failed with error %d\n", GetLastError());
1993 ret = ReadFile(hPipeServer, buffer, sizeof(buffer), &dwBytesRead, NULL);
1994 ok(ret, "ReadFile failed with error %d\n", GetLastError());
1996 ret = ImpersonateNamedPipeClient(hPipeServer);
1997 ok(ret, "ImpersonateNamedPipeClient failed with error %d\n", GetLastError());
1999 ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken);
2000 ok(ret, "OpenThreadToken failed with error %d\n", GetLastError());
2002 (*test_func)(1, hToken);
2004 CloseHandle(hToken);
2006 RevertToSelf();
2008 ret = WriteFile(hPipeServer, &dummy, sizeof(dummy), &dwBytesWritten, NULL);
2009 ok(ret, "WriteFile failed with error %d\n", GetLastError());
2011 WaitForSingleObject(hThread, INFINITE);
2013 ret = ImpersonateNamedPipeClient(hPipeServer);
2014 ok(ret, "ImpersonateNamedPipeClient failed with error %d\n", GetLastError());
2016 RevertToSelf();
2018 CloseHandle(hThread);
2019 CloseHandle(hPipeServer);
2022 static BOOL are_all_privileges_disabled(HANDLE hToken)
2024 BOOL ret;
2025 TOKEN_PRIVILEGES *Privileges = NULL;
2026 DWORD Size = 0;
2027 BOOL all_privs_disabled = TRUE;
2028 DWORD i;
2030 ret = GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &Size);
2031 if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
2033 Privileges = HeapAlloc(GetProcessHeap(), 0, Size);
2034 ret = GetTokenInformation(hToken, TokenPrivileges, Privileges, Size, &Size);
2035 if (!ret)
2037 HeapFree(GetProcessHeap(), 0, Privileges);
2038 return FALSE;
2041 else
2042 return FALSE;
2044 for (i = 0; i < Privileges->PrivilegeCount; i++)
2046 if (Privileges->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED)
2048 all_privs_disabled = FALSE;
2049 break;
2053 HeapFree(GetProcessHeap(), 0, Privileges);
2055 return all_privs_disabled;
2058 static DWORD get_privilege_count(HANDLE hToken)
2060 TOKEN_STATISTICS Statistics;
2061 DWORD Size = sizeof(Statistics);
2062 BOOL ret;
2064 ret = GetTokenInformation(hToken, TokenStatistics, &Statistics, Size, &Size);
2065 ok(ret, "GetTokenInformation(TokenStatistics)\n");
2066 if (!ret) return -1;
2068 return Statistics.PrivilegeCount;
2071 static void test_no_sqos_no_token(int call_index, HANDLE hToken)
2073 DWORD priv_count;
2075 switch (call_index)
2077 case 0:
2078 priv_count = get_privilege_count(hToken);
2079 todo_wine
2080 ok(priv_count == 0, "privilege count should have been 0 instead of %d\n", priv_count);
2081 break;
2082 case 1:
2083 priv_count = get_privilege_count(hToken);
2084 ok(priv_count > 0, "privilege count should now be > 0 instead of 0\n");
2085 ok(!are_all_privileges_disabled(hToken), "impersonated token should not have been modified\n");
2086 break;
2087 default:
2088 ok(0, "shouldn't happen\n");
2092 static void test_no_sqos(int call_index, HANDLE hToken)
2094 switch (call_index)
2096 case 0:
2097 ok(!are_all_privileges_disabled(hToken), "token should be a copy of the process one\n");
2098 break;
2099 case 1:
2100 todo_wine
2101 ok(are_all_privileges_disabled(hToken), "impersonated token should have been modified\n");
2102 break;
2103 default:
2104 ok(0, "shouldn't happen\n");
2108 static void test_static_context(int call_index, HANDLE hToken)
2110 switch (call_index)
2112 case 0:
2113 ok(!are_all_privileges_disabled(hToken), "token should be a copy of the process one\n");
2114 break;
2115 case 1:
2116 ok(!are_all_privileges_disabled(hToken), "impersonated token should not have been modified\n");
2117 break;
2118 default:
2119 ok(0, "shouldn't happen\n");
2123 static void test_dynamic_context(int call_index, HANDLE hToken)
2125 switch (call_index)
2127 case 0:
2128 ok(!are_all_privileges_disabled(hToken), "token should be a copy of the process one\n");
2129 break;
2130 case 1:
2131 todo_wine
2132 ok(are_all_privileges_disabled(hToken), "impersonated token should have been modified\n");
2133 break;
2134 default:
2135 ok(0, "shouldn't happen\n");
2139 static void test_dynamic_context_no_token(int call_index, HANDLE hToken)
2141 switch (call_index)
2143 case 0:
2144 ok(are_all_privileges_disabled(hToken), "token should be a copy of the process one\n");
2145 break;
2146 case 1:
2147 ok(!are_all_privileges_disabled(hToken), "process token modification should have been detected and impersonation token updated\n");
2148 break;
2149 default:
2150 ok(0, "shouldn't happen\n");
2154 static void test_no_sqos_revert(int call_index, HANDLE hToken)
2156 DWORD priv_count;
2157 switch (call_index)
2159 case 0:
2160 priv_count = get_privilege_count(hToken);
2161 todo_wine
2162 ok(priv_count == 0, "privilege count should have been 0 instead of %d\n", priv_count);
2163 break;
2164 case 1:
2165 priv_count = get_privilege_count(hToken);
2166 ok(priv_count > 0, "privilege count should now be > 0 instead of 0\n");
2167 ok(!are_all_privileges_disabled(hToken), "impersonated token should not have been modified\n");
2168 break;
2169 default:
2170 ok(0, "shouldn't happen\n");
2174 static void test_static_context_revert(int call_index, HANDLE hToken)
2176 switch (call_index)
2178 case 0:
2179 todo_wine
2180 ok(are_all_privileges_disabled(hToken), "privileges should have been disabled\n");
2181 break;
2182 case 1:
2183 todo_wine
2184 ok(are_all_privileges_disabled(hToken), "impersonated token should not have been modified\n");
2185 break;
2186 default:
2187 ok(0, "shouldn't happen\n");
2191 static void test_dynamic_context_revert(int call_index, HANDLE hToken)
2193 switch (call_index)
2195 case 0:
2196 todo_wine
2197 ok(are_all_privileges_disabled(hToken), "privileges should have been disabled\n");
2198 break;
2199 case 1:
2200 ok(!are_all_privileges_disabled(hToken), "impersonated token should now be process token\n");
2201 break;
2202 default:
2203 ok(0, "shouldn't happen\n");
2207 static void test_impersonation(void)
2209 HANDLE hClientToken;
2210 HANDLE hProcessToken;
2211 BOOL ret;
2213 if( !pDuplicateTokenEx ) {
2214 skip("DuplicateTokenEx not found\n");
2215 return;
2218 ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hProcessToken);
2219 if (!ret)
2221 skip("couldn't open process token, skipping impersonation tests\n");
2222 return;
2225 if (!get_privilege_count(hProcessToken) || are_all_privileges_disabled(hProcessToken))
2227 skip("token didn't have any privileges or they were all disabled. token not suitable for impersonation tests\n");
2228 CloseHandle(hProcessToken);
2229 return;
2231 CloseHandle(hProcessToken);
2233 test_ImpersonateNamedPipeClient(NULL, 0, FALSE, test_no_sqos_no_token);
2234 hClientToken = make_impersonation_token(TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, SecurityImpersonation);
2235 test_ImpersonateNamedPipeClient(hClientToken, 0, FALSE, test_no_sqos);
2236 CloseHandle(hClientToken);
2237 hClientToken = make_impersonation_token(TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, SecurityImpersonation);
2238 test_ImpersonateNamedPipeClient(hClientToken,
2239 SECURITY_SQOS_PRESENT | SECURITY_IMPERSONATION, FALSE,
2240 test_static_context);
2241 CloseHandle(hClientToken);
2242 hClientToken = make_impersonation_token(TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, SecurityImpersonation);
2243 test_ImpersonateNamedPipeClient(hClientToken,
2244 SECURITY_SQOS_PRESENT | SECURITY_CONTEXT_TRACKING | SECURITY_IMPERSONATION,
2245 FALSE, test_dynamic_context);
2246 CloseHandle(hClientToken);
2247 test_ImpersonateNamedPipeClient(NULL,
2248 SECURITY_SQOS_PRESENT | SECURITY_CONTEXT_TRACKING | SECURITY_IMPERSONATION,
2249 FALSE, test_dynamic_context_no_token);
2251 hClientToken = make_impersonation_token(TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, SecurityImpersonation);
2252 test_ImpersonateNamedPipeClient(hClientToken, 0, TRUE, test_no_sqos_revert);
2253 CloseHandle(hClientToken);
2254 hClientToken = make_impersonation_token(TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, SecurityImpersonation);
2255 test_ImpersonateNamedPipeClient(hClientToken,
2256 SECURITY_SQOS_PRESENT | SECURITY_IMPERSONATION, TRUE,
2257 test_static_context_revert);
2258 CloseHandle(hClientToken);
2259 hClientToken = make_impersonation_token(TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, SecurityImpersonation);
2260 test_ImpersonateNamedPipeClient(hClientToken,
2261 SECURITY_SQOS_PRESENT | SECURITY_CONTEXT_TRACKING | SECURITY_IMPERSONATION,
2262 TRUE, test_dynamic_context_revert);
2263 CloseHandle(hClientToken);
2266 struct overlapped_server_args
2268 HANDLE pipe_created;
2271 static DWORD CALLBACK overlapped_server(LPVOID arg)
2273 OVERLAPPED ol;
2274 HANDLE pipe;
2275 int ret, err;
2276 struct overlapped_server_args *a = arg;
2277 DWORD num;
2278 char buf[100];
2280 pipe = CreateNamedPipeA("\\\\.\\pipe\\my pipe", FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, 1, 0, 0, 100000, NULL);
2281 ok(pipe != NULL, "pipe NULL\n");
2283 ol.hEvent = CreateEventA(0, 1, 0, 0);
2284 ok(ol.hEvent != NULL, "event NULL\n");
2285 ret = ConnectNamedPipe(pipe, &ol);
2286 err = GetLastError();
2287 ok(ret == 0, "ret %d\n", ret);
2288 ok(err == ERROR_IO_PENDING, "gle %d\n", err);
2289 SetEvent(a->pipe_created);
2291 ret = WaitForSingleObjectEx(ol.hEvent, INFINITE, 1);
2292 ok(ret == WAIT_OBJECT_0, "ret %x\n", ret);
2294 ret = GetOverlappedResult(pipe, &ol, &num, 1);
2295 ok(ret == 1, "ret %d\n", ret);
2297 /* This should block */
2298 ret = ReadFile(pipe, buf, sizeof(buf), &num, NULL);
2299 ok(ret == 1, "ret %d\n", ret);
2301 DisconnectNamedPipe(pipe);
2303 ret = ConnectNamedPipe(pipe, &ol);
2304 err = GetLastError();
2305 ok(ret == 0, "ret %d\n", ret);
2306 ok(err == ERROR_IO_PENDING, "gle %d\n", err);
2307 CancelIo(pipe);
2308 ret = WaitForSingleObjectEx(ol.hEvent, INFINITE, 1);
2309 ok(ret == WAIT_OBJECT_0, "ret %x\n", ret);
2311 ret = GetOverlappedResult(pipe, &ol, &num, 1);
2312 err = GetLastError();
2313 ok(ret == 0, "ret %d\n", ret);
2314 ok(err == ERROR_OPERATION_ABORTED, "gle %d\n", err);
2316 CloseHandle(ol.hEvent);
2317 CloseHandle(pipe);
2318 return 1;
2321 static void test_overlapped(void)
2323 DWORD tid, num;
2324 HANDLE thread, pipe;
2325 BOOL ret;
2326 struct overlapped_server_args args;
2328 args.pipe_created = CreateEventA(0, 1, 0, 0);
2329 thread = CreateThread(NULL, 0, overlapped_server, &args, 0, &tid);
2331 WaitForSingleObject(args.pipe_created, INFINITE);
2332 pipe = CreateFileA("\\\\.\\pipe\\my pipe", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
2333 ok(pipe != INVALID_HANDLE_VALUE, "cf failed\n");
2335 /* Sleep to try to get the ReadFile in the server to occur before the following WriteFile */
2336 Sleep(1);
2338 ret = WriteFile(pipe, "x", 1, &num, NULL);
2339 ok(ret, "WriteFile failed with error %d\n", GetLastError());
2341 WaitForSingleObject(thread, INFINITE);
2342 CloseHandle(pipe);
2343 CloseHandle(args.pipe_created);
2344 CloseHandle(thread);
2347 static void test_overlapped_error(void)
2349 HANDLE pipe, file, event;
2350 DWORD err, numbytes;
2351 OVERLAPPED overlapped;
2352 BOOL ret;
2354 event = CreateEventA(NULL, TRUE, FALSE, NULL);
2355 ok(event != NULL, "CreateEventA failed with %u\n", GetLastError());
2357 pipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
2358 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
2359 1, 1024, 1024, NMPWAIT_WAIT_FOREVER, NULL);
2360 ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %u\n", GetLastError());
2362 memset(&overlapped, 0, sizeof(overlapped));
2363 overlapped.hEvent = event;
2364 ret = ConnectNamedPipe(pipe, &overlapped);
2365 err = GetLastError();
2366 ok(ret == FALSE, "ConnectNamedPipe succeeded\n");
2367 ok(err == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %u\n", err);
2369 file = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL,
2370 OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
2371 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed with %u\n", GetLastError());
2373 numbytes = 0xdeadbeef;
2374 ret = GetOverlappedResult(pipe, &overlapped, &numbytes, TRUE);
2375 ok(ret == TRUE, "GetOverlappedResult failed\n");
2376 ok(numbytes == 0, "expected 0, got %u\n", numbytes);
2377 ok(overlapped.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08lx\n", overlapped.Internal);
2379 CloseHandle(file);
2380 CloseHandle(pipe);
2382 pipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
2383 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
2384 1, 1024, 1024, NMPWAIT_WAIT_FOREVER, NULL);
2385 ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %u\n", GetLastError());
2387 file = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL,
2388 OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
2389 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed with %u\n", GetLastError());
2391 memset(&overlapped, 0, sizeof(overlapped));
2392 overlapped.hEvent = event;
2393 ret = ConnectNamedPipe(pipe, &overlapped);
2394 err = GetLastError();
2395 ok(ret == FALSE, "ConnectNamedPipe succeeded\n");
2396 ok(err == ERROR_PIPE_CONNECTED, "expected ERROR_PIPE_CONNECTED, got %u\n", err);
2397 ok(overlapped.Internal == STATUS_PENDING, "expected STATUS_PENDING, got %08lx\n", overlapped.Internal);
2399 CloseHandle(file);
2400 CloseHandle(pipe);
2402 CloseHandle(event);
2405 static void test_NamedPipeHandleState(void)
2407 HANDLE server, client;
2408 BOOL ret;
2409 DWORD state, instances, maxCollectionCount, collectDataTimeout;
2410 char userName[MAX_PATH];
2412 server = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX,
2413 /* dwOpenMode */ PIPE_TYPE_BYTE | PIPE_WAIT,
2414 /* nMaxInstances */ 1,
2415 /* nOutBufSize */ 1024,
2416 /* nInBufSize */ 1024,
2417 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
2418 /* lpSecurityAttrib */ NULL);
2419 ok(server != INVALID_HANDLE_VALUE, "cf failed\n");
2420 ret = GetNamedPipeHandleStateA(server, NULL, NULL, NULL, NULL, NULL, 0);
2421 ok(ret, "GetNamedPipeHandleState failed: %d\n", GetLastError());
2422 ret = GetNamedPipeHandleStateA(server, &state, &instances, NULL, NULL, NULL,
2424 ok(ret, "GetNamedPipeHandleState failed: %d\n", GetLastError());
2425 if (ret)
2427 ok(state == 0, "unexpected state %08x\n", state);
2428 ok(instances == 1, "expected 1 instances, got %d\n", instances);
2430 /* Some parameters have no meaning, and therefore can't be retrieved,
2431 * on a local pipe.
2433 SetLastError(0xdeadbeef);
2434 ret = GetNamedPipeHandleStateA(server, &state, &instances, &maxCollectionCount,
2435 &collectDataTimeout, userName, ARRAY_SIZE(userName));
2436 todo_wine
2437 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
2438 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2439 /* A byte-mode pipe server can't be changed to message mode. */
2440 state = PIPE_READMODE_MESSAGE;
2441 SetLastError(0xdeadbeef);
2442 ret = SetNamedPipeHandleState(server, &state, NULL, NULL);
2443 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
2444 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2446 client = CreateFileA(PIPENAME, GENERIC_READ|GENERIC_WRITE, 0, NULL,
2447 OPEN_EXISTING, 0, NULL);
2448 ok(client != INVALID_HANDLE_VALUE, "cf failed\n");
2450 state = PIPE_READMODE_BYTE;
2451 ret = SetNamedPipeHandleState(client, &state, NULL, NULL);
2452 ok(ret, "SetNamedPipeHandleState failed: %d\n", GetLastError());
2453 /* A byte-mode pipe client can't be changed to message mode, either. */
2454 state = PIPE_READMODE_MESSAGE;
2455 SetLastError(0xdeadbeef);
2456 ret = SetNamedPipeHandleState(server, &state, NULL, NULL);
2457 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
2458 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2460 CloseHandle(client);
2461 CloseHandle(server);
2463 server = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX,
2464 /* dwOpenMode */ PIPE_TYPE_MESSAGE | PIPE_WAIT,
2465 /* nMaxInstances */ 1,
2466 /* nOutBufSize */ 1024,
2467 /* nInBufSize */ 1024,
2468 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
2469 /* lpSecurityAttrib */ NULL);
2470 ok(server != INVALID_HANDLE_VALUE, "cf failed\n");
2471 ret = GetNamedPipeHandleStateA(server, NULL, NULL, NULL, NULL, NULL, 0);
2472 ok(ret, "GetNamedPipeHandleState failed: %d\n", GetLastError());
2473 ret = GetNamedPipeHandleStateA(server, &state, &instances, NULL, NULL, NULL,
2475 ok(ret, "GetNamedPipeHandleState failed: %d\n", GetLastError());
2476 if (ret)
2478 ok(state == 0, "unexpected state %08x\n", state);
2479 ok(instances == 1, "expected 1 instances, got %d\n", instances);
2481 /* In contrast to byte-mode pipes, a message-mode pipe server can be
2482 * changed to byte mode.
2484 state = PIPE_READMODE_BYTE;
2485 ret = SetNamedPipeHandleState(server, &state, NULL, NULL);
2486 ok(ret, "SetNamedPipeHandleState failed: %d\n", GetLastError());
2488 client = CreateFileA(PIPENAME, GENERIC_READ|GENERIC_WRITE, 0, NULL,
2489 OPEN_EXISTING, 0, NULL);
2490 ok(client != INVALID_HANDLE_VALUE, "cf failed\n");
2492 state = PIPE_READMODE_MESSAGE;
2493 ret = SetNamedPipeHandleState(client, &state, NULL, NULL);
2494 ok(ret, "SetNamedPipeHandleState failed: %d\n", GetLastError());
2495 /* A message-mode pipe client can also be changed to byte mode.
2497 state = PIPE_READMODE_BYTE;
2498 ret = SetNamedPipeHandleState(client, &state, NULL, NULL);
2499 ok(ret, "SetNamedPipeHandleState failed: %d\n", GetLastError());
2501 CloseHandle(client);
2502 CloseHandle(server);
2505 static void test_GetNamedPipeInfo(void)
2507 HANDLE server;
2509 server = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX,
2510 /* dwOpenMode */ PIPE_TYPE_BYTE | PIPE_WAIT,
2511 /* nMaxInstances */ 1,
2512 /* nOutBufSize */ 1024,
2513 /* nInBufSize */ 1024,
2514 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
2515 /* lpSecurityAttrib */ NULL);
2516 ok(server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
2518 test_pipe_info(server, PIPE_SERVER_END | PIPE_TYPE_BYTE, 1024, 1024, 1);
2520 CloseHandle(server);
2522 server = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX,
2523 /* dwOpenMode */ PIPE_TYPE_MESSAGE | PIPE_NOWAIT,
2524 /* nMaxInstances */ 3,
2525 /* nOutBufSize */ 1024,
2526 /* nInBufSize */ 1024,
2527 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
2528 /* lpSecurityAttrib */ NULL);
2529 ok(server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
2531 test_pipe_info(server, PIPE_SERVER_END | PIPE_TYPE_MESSAGE, 1024, 1024, 3);
2533 CloseHandle(server);
2535 server = CreateNamedPipeA(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX,
2536 /* dwOpenMode */ PIPE_TYPE_MESSAGE | PIPE_WAIT,
2537 /* nMaxInstances */ 1,
2538 /* nOutBufSize */ 0,
2539 /* nInBufSize */ 0,
2540 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
2541 /* lpSecurityAttrib */ NULL);
2542 ok(server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
2544 test_pipe_info(server, PIPE_SERVER_END | PIPE_TYPE_MESSAGE, 0, 0, 1);
2546 CloseHandle(server);
2548 server = CreateNamedPipeA(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX,
2549 /* dwOpenMode */ PIPE_TYPE_MESSAGE | PIPE_WAIT,
2550 /* nMaxInstances */ 1,
2551 /* nOutBufSize */ 0xf000,
2552 /* nInBufSize */ 0xf000,
2553 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
2554 /* lpSecurityAttrib */ NULL);
2555 ok(server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
2557 test_pipe_info(server, PIPE_SERVER_END | PIPE_TYPE_MESSAGE, 0xf000, 0xf000, 1);
2559 CloseHandle(server);
2562 static void test_readfileex_pending(void)
2564 HANDLE server, client, event;
2565 BOOL ret;
2566 DWORD err, wait, num_bytes;
2567 OVERLAPPED overlapped;
2568 char read_buf[1024];
2569 char write_buf[1024];
2570 const char test_string[] = "test";
2571 int i;
2573 server = CreateNamedPipeA(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX,
2574 /* dwOpenMode */ PIPE_TYPE_BYTE | PIPE_WAIT,
2575 /* nMaxInstances */ 1,
2576 /* nOutBufSize */ 1024,
2577 /* nInBufSize */ 1024,
2578 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
2579 /* lpSecurityAttrib */ NULL);
2580 ok(server != INVALID_HANDLE_VALUE, "cf failed\n");
2582 event = CreateEventA(NULL, TRUE, FALSE, NULL);
2583 ok(event != NULL, "CreateEventA failed\n");
2585 memset(&overlapped, 0, sizeof(overlapped));
2586 overlapped.hEvent = event;
2588 ret = ConnectNamedPipe(server, &overlapped);
2589 err = GetLastError();
2590 ok(ret == FALSE, "ConnectNamedPipe succeeded\n");
2591 ok(err == ERROR_IO_PENDING, "ConnectNamedPipe set error %i\n", err);
2593 wait = WaitForSingleObject(event, 0);
2594 ok(wait == WAIT_TIMEOUT, "WaitForSingleObject returned %x\n", wait);
2596 client = CreateFileA(PIPENAME, GENERIC_READ|GENERIC_WRITE, 0, NULL,
2597 OPEN_EXISTING, 0, NULL);
2598 ok(client != INVALID_HANDLE_VALUE, "cf failed\n");
2600 wait = WaitForSingleObject(event, 0);
2601 ok(wait == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", wait);
2603 /* Start a read that can't complete immediately. */
2604 completion_called = 0;
2605 ResetEvent(event);
2606 ret = ReadFileEx(server, read_buf, sizeof(read_buf), &overlapped, completion_routine);
2607 ok(ret == TRUE, "ReadFileEx failed, err=%i\n", GetLastError());
2608 ok(completion_called == 0, "completion routine called before ReadFileEx returned\n");
2610 ret = WriteFile(client, test_string, strlen(test_string), &num_bytes, NULL);
2611 ok(ret == TRUE, "WriteFile failed\n");
2612 ok(num_bytes == strlen(test_string), "only %i bytes written\n", num_bytes);
2614 ok(completion_called == 0, "completion routine called during WriteFile\n");
2616 wait = WaitForSingleObjectEx(event, 0, TRUE);
2617 ok(wait == WAIT_IO_COMPLETION || wait == WAIT_OBJECT_0, "WaitForSingleObjectEx returned %x\n", wait);
2619 ok(completion_called == 1, "completion not called after writing pipe\n");
2620 ok(completion_errorcode == 0, "completion called with error %x\n", completion_errorcode);
2621 ok(completion_num_bytes == strlen(test_string), "ReadFileEx returned only %d bytes\n", completion_num_bytes);
2622 ok(completion_lpoverlapped == &overlapped, "completion called with wrong overlapped pointer\n");
2623 ok(!memcmp(test_string, read_buf, strlen(test_string)), "ReadFileEx read wrong bytes\n");
2625 /* Make writes until the pipe is full and the write fails */
2626 memset(write_buf, 0xaa, sizeof(write_buf));
2627 for (i=0; i<256; i++)
2629 completion_called = 0;
2630 ResetEvent(event);
2631 ret = WriteFileEx(server, write_buf, sizeof(write_buf), &overlapped, completion_routine);
2632 err = GetLastError();
2634 ok(completion_called == 0, "completion routine called during WriteFileEx\n");
2636 wait = WaitForSingleObjectEx(event, 0, TRUE);
2638 if (wait == WAIT_TIMEOUT)
2639 /* write couldn't complete immediately, presumably the pipe is full */
2640 break;
2642 ok(wait == WAIT_IO_COMPLETION || wait == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", wait);
2644 ok(ret == TRUE, "WriteFileEx failed, err=%i\n", err);
2645 ok(completion_errorcode == 0, "completion called with error %x\n", completion_errorcode);
2646 ok(completion_lpoverlapped == &overlapped, "completion called with wrong overlapped pointer\n");
2649 ok(ret == TRUE, "WriteFileEx failed, err=%i\n", err);
2650 ok(completion_called == 0, "completion routine called but wait timed out\n");
2651 ok(completion_errorcode == 0, "completion called with error %x\n", completion_errorcode);
2652 ok(completion_lpoverlapped == &overlapped, "completion called with wrong overlapped pointer\n");
2654 /* free up some space in the pipe */
2655 for (i=0; i<256; i++)
2657 ret = ReadFile(client, read_buf, sizeof(read_buf), &num_bytes, NULL);
2658 ok(ret == TRUE, "ReadFile failed\n");
2660 ok(completion_called == 0, "completion routine called during ReadFile\n");
2662 wait = WaitForSingleObjectEx(event, 0, TRUE);
2663 ok(wait == WAIT_IO_COMPLETION || wait == WAIT_OBJECT_0 || wait == WAIT_TIMEOUT,
2664 "WaitForSingleObject returned %x\n", wait);
2665 if (wait != WAIT_TIMEOUT) break;
2668 ok(completion_called == 1, "completion routine not called\n");
2669 ok(completion_errorcode == 0, "completion called with error %x\n", completion_errorcode);
2670 ok(completion_lpoverlapped == &overlapped, "completion called with wrong overlapped pointer\n");
2672 num_bytes = 0xdeadbeef;
2673 SetLastError(0xdeadbeef);
2674 ret = ReadFile(INVALID_HANDLE_VALUE, read_buf, 0, &num_bytes, NULL);
2675 ok(!ret, "ReadFile should fail\n");
2676 ok(GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError());
2677 ok(num_bytes == 0, "expected 0, got %u\n", num_bytes);
2679 S(U(overlapped)).Offset = 0;
2680 S(U(overlapped)).OffsetHigh = 0;
2681 overlapped.Internal = -1;
2682 overlapped.InternalHigh = -1;
2683 overlapped.hEvent = event;
2684 num_bytes = 0xdeadbeef;
2685 SetLastError(0xdeadbeef);
2686 ret = ReadFile(server, read_buf, 0, &num_bytes, &overlapped);
2687 ok(!ret, "ReadFile should fail\n");
2688 ok(GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
2689 ok(num_bytes == 0, "bytes %u\n", num_bytes);
2690 ok((NTSTATUS)overlapped.Internal == STATUS_PENDING, "expected STATUS_PENDING, got %#lx\n", overlapped.Internal);
2691 ok(overlapped.InternalHigh == -1, "expected -1, got %lu\n", overlapped.InternalHigh);
2693 wait = WaitForSingleObject(event, 100);
2694 ok(wait == WAIT_TIMEOUT, "WaitForSingleObject returned %x\n", wait);
2696 num_bytes = 0xdeadbeef;
2697 ret = WriteFile(client, test_string, 1, &num_bytes, NULL);
2698 ok(ret, "WriteFile failed\n");
2699 ok(num_bytes == 1, "bytes %u\n", num_bytes);
2701 wait = WaitForSingleObject(event, 100);
2702 ok(wait == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", wait);
2704 ok(num_bytes == 1, "bytes %u\n", num_bytes);
2705 ok((NTSTATUS)overlapped.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", overlapped.Internal);
2706 ok(overlapped.InternalHigh == 0, "expected 0, got %lu\n", overlapped.InternalHigh);
2708 /* read the pending byte and clear the pipe */
2709 num_bytes = 0xdeadbeef;
2710 ret = ReadFile(server, read_buf, 1, &num_bytes, &overlapped);
2711 ok(ret, "ReadFile failed\n");
2712 ok(num_bytes == 1, "bytes %u\n", num_bytes);
2714 CloseHandle(client);
2715 CloseHandle(server);
2716 CloseHandle(event);
2719 #define test_peek_pipe(a,b,c,d) _test_peek_pipe(__LINE__,a,b,c,d)
2720 static void _test_peek_pipe(unsigned line, HANDLE pipe, DWORD expected_read, DWORD expected_avail, DWORD expected_message_length)
2722 DWORD bytes_read = 0xdeadbeed, avail = 0xdeadbeef, left = 0xdeadbeed;
2723 char buf[12000];
2724 FILE_PIPE_PEEK_BUFFER *peek_buf = (void*)buf;
2725 IO_STATUS_BLOCK io;
2726 NTSTATUS status;
2727 BOOL r;
2729 r = PeekNamedPipe(pipe, buf, sizeof(buf), &bytes_read, &avail, &left);
2730 ok_(__FILE__,line)(r, "PeekNamedPipe failed: %u\n", GetLastError());
2731 ok_(__FILE__,line)(bytes_read == expected_read, "bytes_read = %u, expected %u\n", bytes_read, expected_read);
2732 ok_(__FILE__,line)(avail == expected_avail, "avail = %u, expected %u\n", avail, expected_avail);
2733 ok_(__FILE__,line)(left == expected_message_length - expected_read, "left = %d, expected %d\n",
2734 left, expected_message_length - expected_read);
2736 status = NtFsControlFile(pipe, 0, NULL, NULL, &io, FSCTL_PIPE_PEEK, NULL, 0, buf, sizeof(buf));
2737 ok_(__FILE__,line)(!status || status == STATUS_PENDING, "NtFsControlFile(FSCTL_PIPE_PEEK) failed: %x\n", status);
2738 ok_(__FILE__,line)(io.Information == FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[expected_read]),
2739 "io.Information = %lu\n", io.Information);
2740 ok_(__FILE__,line)(peek_buf->ReadDataAvailable == expected_avail, "ReadDataAvailable = %u, expected %u\n",
2741 peek_buf->ReadDataAvailable, expected_avail);
2742 ok_(__FILE__,line)(peek_buf->MessageLength == expected_message_length, "MessageLength = %u, expected %u\n",
2743 peek_buf->MessageLength, expected_message_length);
2745 if (expected_read)
2747 r = PeekNamedPipe(pipe, buf, 1, &bytes_read, &avail, &left);
2748 ok_(__FILE__,line)(r, "PeekNamedPipe failed: %u\n", GetLastError());
2749 ok_(__FILE__,line)(bytes_read == 1, "bytes_read = %u, expected %u\n", bytes_read, expected_read);
2750 ok_(__FILE__,line)(avail == expected_avail, "avail = %u, expected %u\n", avail, expected_avail);
2751 ok_(__FILE__,line)(left == expected_message_length-1, "left = %d, expected %d\n", left, expected_message_length-1);
2755 #define overlapped_read_sync(a,b,c,d,e) _overlapped_read_sync(__LINE__,a,b,c,d,e)
2756 static void _overlapped_read_sync(unsigned line, HANDLE reader, void *buf, DWORD buf_size, DWORD expected_result, BOOL partial_read)
2758 DWORD read_bytes = 0xdeadbeef;
2759 OVERLAPPED overlapped;
2760 BOOL res;
2762 memset(&overlapped, 0, sizeof(overlapped));
2763 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
2764 res = ReadFile(reader, buf, buf_size, &read_bytes, &overlapped);
2765 if (partial_read)
2766 ok_(__FILE__,line)(!res && GetLastError() == ERROR_MORE_DATA, "ReadFile returned: %x (%u)\n", res, GetLastError());
2767 else
2768 ok_(__FILE__,line)(res, "ReadFile failed: %u\n", GetLastError());
2769 if(partial_read)
2770 ok_(__FILE__,line)(!read_bytes, "read_bytes %u expected 0\n", read_bytes);
2771 else
2772 ok_(__FILE__,line)(read_bytes == expected_result, "read_bytes %u expected %u\n", read_bytes, expected_result);
2774 read_bytes = 0xdeadbeef;
2775 res = GetOverlappedResult(reader, &overlapped, &read_bytes, FALSE);
2776 if (partial_read)
2777 ok_(__FILE__,line)(!res && GetLastError() == ERROR_MORE_DATA,
2778 "GetOverlappedResult returned: %x (%u)\n", res, GetLastError());
2779 else
2780 ok_(__FILE__,line)(res, "GetOverlappedResult failed: %u\n", GetLastError());
2781 ok_(__FILE__,line)(read_bytes == expected_result, "read_bytes %u expected %u\n", read_bytes, expected_result);
2782 CloseHandle(overlapped.hEvent);
2785 #define overlapped_read_async(a,b,c,d) _overlapped_read_async(__LINE__,a,b,c,d)
2786 static void _overlapped_read_async(unsigned line, HANDLE reader, void *buf, DWORD buf_size, OVERLAPPED *overlapped)
2788 DWORD read_bytes = 0xdeadbeef;
2789 BOOL res;
2791 memset(overlapped, 0, sizeof(*overlapped));
2792 overlapped->hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
2793 res = ReadFile(reader, buf, buf_size, &read_bytes, overlapped);
2794 ok_(__FILE__,line)(!res && GetLastError() == ERROR_IO_PENDING, "ReadFile returned %x(%u)\n", res, GetLastError());
2795 ok_(__FILE__,line)(!read_bytes, "read_bytes %u expected 0\n", read_bytes);
2797 _test_not_signaled(line, overlapped->hEvent);
2800 #define overlapped_write_sync(a,b,c) _overlapped_write_sync(__LINE__,a,b,c)
2801 static void _overlapped_write_sync(unsigned line, HANDLE writer, void *buf, DWORD size)
2803 DWORD written_bytes = 0xdeadbeef;
2804 OVERLAPPED overlapped;
2805 BOOL res;
2807 memset(&overlapped, 0, sizeof(overlapped));
2808 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
2809 res = WriteFile(writer, buf, size, &written_bytes, &overlapped);
2810 ok_(__FILE__,line)(res, "WriteFile returned %x(%u)\n", res, GetLastError());
2811 ok_(__FILE__,line)(written_bytes == size, "WriteFile returned written_bytes = %u\n", written_bytes);
2813 written_bytes = 0xdeadbeef;
2814 res = GetOverlappedResult(writer, &overlapped, &written_bytes, FALSE);
2815 ok_(__FILE__,line)(res, "GetOverlappedResult failed: %u\n", GetLastError());
2816 ok_(__FILE__,line)(written_bytes == size, "GetOverlappedResult returned written_bytes %u expected %u\n", written_bytes, size);
2818 CloseHandle(overlapped.hEvent);
2821 #define overlapped_write_async(a,b,c,d) _overlapped_write_async(__LINE__,a,b,c,d)
2822 static void _overlapped_write_async(unsigned line, HANDLE writer, void *buf, DWORD size, OVERLAPPED *overlapped)
2824 DWORD written_bytes = 0xdeadbeef;
2825 BOOL res;
2827 memset(overlapped, 0, sizeof(*overlapped));
2828 overlapped->hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
2829 res = WriteFile(writer, buf, size, &written_bytes, overlapped);
2830 ok_(__FILE__,line)(!res && GetLastError() == ERROR_IO_PENDING, "WriteFile returned %x(%u)\n", res, GetLastError());
2831 ok_(__FILE__,line)(!written_bytes, "written_bytes = %u\n", written_bytes);
2833 _test_not_signaled(line, overlapped->hEvent);
2836 #define test_flush_sync(a) _test_flush_sync(__LINE__,a)
2837 static void _test_flush_sync(unsigned line, HANDLE pipe)
2839 BOOL res;
2841 res = FlushFileBuffers(pipe);
2842 ok_(__FILE__,line)(res, "FlushFileBuffers failed: %u\n", GetLastError());
2845 static DWORD expected_flush_error;
2847 static DWORD CALLBACK flush_proc(HANDLE pipe)
2849 BOOL res;
2851 res = FlushFileBuffers(pipe);
2852 if (expected_flush_error == ERROR_SUCCESS)
2853 ok(res, "FlushFileBuffers failed: %u\n", GetLastError());
2854 else
2855 todo_wine ok(!res && GetLastError() == expected_flush_error, "FlushFileBuffers failed: %u\n", GetLastError());
2856 return 0;
2859 #define test_flush_async(a,b) _test_flush_async(__LINE__,a,b)
2860 static HANDLE _test_flush_async(unsigned line, HANDLE pipe, DWORD error)
2862 HANDLE thread;
2863 DWORD tid;
2865 expected_flush_error = error;
2866 thread = CreateThread(NULL, 0, flush_proc, pipe, 0, &tid);
2867 ok_(__FILE__,line)(thread != NULL, "CreateThread failed: %u\n", GetLastError());
2869 Sleep(50);
2870 _test_not_signaled(line, thread);
2871 return thread;
2874 #define test_flush_done(a) _test_flush_done(__LINE__,a)
2875 static void _test_flush_done(unsigned line, HANDLE thread)
2877 DWORD res = WaitForSingleObject(thread, 1000);
2878 ok_(__FILE__,line)(res == WAIT_OBJECT_0, "WaitForSingleObject returned %u (%u)\n", res, GetLastError());
2879 CloseHandle(thread);
2882 #define test_overlapped_result(a,b,c,d) _test_overlapped_result(__LINE__,a,b,c,d)
2883 static void _test_overlapped_result(unsigned line, HANDLE handle, OVERLAPPED *overlapped, DWORD expected_result, BOOL partial_read)
2885 DWORD result = 0xdeadbeef;
2886 BOOL res;
2888 _test_signaled(line, overlapped->hEvent);
2890 res = GetOverlappedResult(handle, overlapped, &result, FALSE);
2891 if (partial_read)
2892 ok_(__FILE__,line)(!res && GetLastError() == ERROR_MORE_DATA, "GetOverlappedResult returned: %x (%u)\n", res, GetLastError());
2893 else
2894 ok_(__FILE__,line)(res, "GetOverlappedResult failed: %u\n", GetLastError());
2895 ok_(__FILE__,line)(result == expected_result, "read_bytes = %u, expected %u\n", result, expected_result);
2896 CloseHandle(overlapped->hEvent);
2899 #define test_overlapped_failure(a,b,c) _test_overlapped_failure(__LINE__,a,b,c)
2900 static void _test_overlapped_failure(unsigned line, HANDLE handle, OVERLAPPED *overlapped, DWORD error)
2902 DWORD result;
2903 BOOL res;
2905 _test_signaled(line, overlapped->hEvent);
2907 res = GetOverlappedResult(handle, overlapped, &result, FALSE);
2908 ok_(__FILE__,line)(!res && GetLastError() == error, "GetOverlappedResult returned: %x (%u), expected error %u\n",
2909 res, GetLastError(), error);
2910 ok_(__FILE__,line)(!result, "result = %u\n", result);
2911 CloseHandle(overlapped->hEvent);
2914 #define cancel_overlapped(a,b) _cancel_overlapped(__LINE__,a,b)
2915 static void _cancel_overlapped(unsigned line, HANDLE handle, OVERLAPPED *overlapped)
2917 BOOL res;
2919 res = pCancelIoEx(handle, overlapped);
2920 ok_(__FILE__,line)(res, "CancelIoEx failed: %u\n", GetLastError());
2922 _test_overlapped_failure(line, handle, overlapped, ERROR_OPERATION_ABORTED);
2925 static void test_blocking_rw(HANDLE writer, HANDLE reader, DWORD buf_size, BOOL msg_mode, BOOL msg_read)
2927 OVERLAPPED read_overlapped, read_overlapped2, write_overlapped, write_overlapped2;
2928 char buf[10000], read_buf[10000];
2929 HANDLE flush_thread;
2931 memset(buf, 0xaa, sizeof(buf));
2933 /* test pending read with overlapped event */
2934 overlapped_read_async(reader, read_buf, 1000, &read_overlapped);
2935 test_flush_sync(writer);
2936 test_peek_pipe(reader, 0, 0, 0);
2938 /* write more data than needed for read */
2939 overlapped_write_sync(writer, buf, 4000);
2940 test_overlapped_result(reader, &read_overlapped, 1000, msg_read);
2941 test_peek_pipe(reader, 3000, 3000, msg_mode ? 3000 : 0);
2943 /* test pending write with overlapped event */
2944 overlapped_write_async(writer, buf, buf_size, &write_overlapped);
2945 test_peek_pipe(reader, 3000 + (msg_mode ? 0 : buf_size), 3000 + buf_size, msg_mode ? 3000 : 0);
2947 /* write one more byte */
2948 overlapped_write_async(writer, buf, 1, &write_overlapped2);
2949 flush_thread = test_flush_async(writer, ERROR_SUCCESS);
2950 test_not_signaled(write_overlapped.hEvent);
2951 test_peek_pipe(reader, 3000 + (msg_mode ? 0 : buf_size + 1), 3000 + buf_size + 1,
2952 msg_mode ? 3000 : 0);
2954 /* empty write will not block */
2955 overlapped_write_sync(writer, buf, 0);
2956 test_not_signaled(write_overlapped.hEvent);
2957 test_not_signaled(write_overlapped2.hEvent);
2958 test_peek_pipe(reader, 3000 + (msg_mode ? 0 : buf_size + 1), 3000 + buf_size + 1,
2959 msg_mode ? 3000 : 0);
2961 /* read remaining data from the first write */
2962 overlapped_read_sync(reader, read_buf, 3000, 3000, FALSE);
2963 test_overlapped_result(writer, &write_overlapped, buf_size, FALSE);
2964 test_not_signaled(write_overlapped2.hEvent);
2965 test_not_signaled(flush_thread);
2966 test_peek_pipe(reader, buf_size + (msg_mode ? 0 : 1), buf_size + 1, msg_mode ? buf_size : 0);
2968 /* read one byte so that the next write fits the buffer */
2969 overlapped_read_sync(reader, read_buf, 1, 1, msg_read);
2970 test_overlapped_result(writer, &write_overlapped2, 1, FALSE);
2971 test_peek_pipe(reader, buf_size + (msg_mode ? -1 : 0), buf_size, msg_mode ? buf_size - 1 : 0);
2973 /* read the whole buffer */
2974 overlapped_read_sync(reader, read_buf, buf_size, buf_size-msg_read, FALSE);
2975 test_peek_pipe(reader, msg_read ? 1 : 0, msg_read ? 1 : 0, msg_read ? 1 : 0);
2977 if(msg_read)
2979 overlapped_read_sync(reader, read_buf, 1000, 1, FALSE);
2980 test_peek_pipe(reader, 0, 0, 0);
2983 if(msg_mode)
2985 /* we still have an empty message in queue */
2986 overlapped_read_sync(reader, read_buf, 1000, 0, FALSE);
2987 test_peek_pipe(reader, 0, 0, 0);
2989 test_flush_done(flush_thread);
2991 /* pipe is empty, the next read will block */
2992 overlapped_read_async(reader, read_buf, 0, &read_overlapped);
2993 overlapped_read_async(reader, read_buf, 1000, &read_overlapped2);
2995 /* write one byte */
2996 overlapped_write_sync(writer, buf, 1);
2997 test_overlapped_result(reader, &read_overlapped, 0, msg_read);
2998 test_overlapped_result(reader, &read_overlapped2, 1, FALSE);
2999 test_peek_pipe(reader, 0, 0, 0);
3001 /* write a message larger than buffer */
3002 overlapped_write_async(writer, buf, buf_size+2000, &write_overlapped);
3003 test_peek_pipe(reader, buf_size + 2000, buf_size + 2000, msg_mode ? buf_size + 2000 : 0);
3005 /* read so that pending write is still larger than the buffer */
3006 overlapped_read_sync(reader, read_buf, 1999, 1999, msg_read);
3007 test_not_signaled(write_overlapped.hEvent);
3008 test_peek_pipe(reader, buf_size + 1, buf_size + 1, msg_mode ? buf_size + 1 : 0);
3010 /* read one more byte */
3011 overlapped_read_sync(reader, read_buf, 1, 1, msg_read);
3012 test_overlapped_result(writer, &write_overlapped, buf_size+2000, FALSE);
3013 test_peek_pipe(reader, buf_size, buf_size, msg_mode ? buf_size : 0);
3015 /* read remaining data */
3016 overlapped_read_sync(reader, read_buf, buf_size+1, buf_size, FALSE);
3017 test_peek_pipe(reader, 0, 0, 0);
3019 /* simple pass of empty message */
3020 overlapped_write_sync(writer, buf, 0);
3021 test_peek_pipe(reader, 0, 0, 0);
3022 if(msg_mode)
3023 overlapped_read_sync(reader, read_buf, 1, 0, FALSE);
3025 /* pipe is empty, the next read will block */
3026 test_flush_sync(writer);
3027 overlapped_read_async(reader, read_buf, 0, &read_overlapped);
3028 overlapped_read_async(reader, read_buf, 1, &read_overlapped2);
3030 /* 0 length write wakes one read in msg mode */
3031 overlapped_write_sync(writer, buf, 0);
3032 if(msg_mode)
3033 test_overlapped_result(reader, &read_overlapped, 0, FALSE);
3034 else
3035 test_not_signaled(read_overlapped.hEvent);
3036 test_not_signaled(read_overlapped2.hEvent);
3037 overlapped_write_sync(writer, buf, 1);
3038 test_overlapped_result(reader, &read_overlapped2, 1, FALSE);
3040 overlapped_write_sync(writer, buf, 20);
3041 test_peek_pipe(reader, 20, 20, msg_mode ? 20 : 0);
3042 overlapped_write_sync(writer, buf, 15);
3043 test_peek_pipe(reader, msg_mode ? 20 : 35, 35, msg_mode ? 20 : 0);
3044 overlapped_read_sync(reader, read_buf, 10, 10, msg_read);
3045 test_peek_pipe(reader, msg_mode ? 10 : 25, 25, msg_mode ? 10 : 0);
3046 overlapped_read_sync(reader, read_buf, 10, 10, FALSE);
3047 test_peek_pipe(reader, 15, 15, msg_mode ? 15 : 0);
3048 overlapped_read_sync(reader, read_buf, 15, 15, FALSE);
3050 if(!pCancelIoEx) {
3051 win_skip("CancelIoEx not available\n");
3052 return;
3055 /* add one more pending read, then cancel the first one */
3056 overlapped_read_async(reader, read_buf, 1, &read_overlapped);
3057 overlapped_read_async(reader, read_buf, 1, &read_overlapped2);
3058 cancel_overlapped(reader, &read_overlapped2);
3059 test_not_signaled(read_overlapped.hEvent);
3060 overlapped_write_sync(writer, buf, 1);
3061 test_overlapped_result(reader, &read_overlapped, 1, FALSE);
3063 /* make two async writes, cancel the first one and make sure that we read from the second one */
3064 overlapped_write_async(writer, buf, buf_size+2000, &write_overlapped);
3065 overlapped_write_async(writer, buf, 1, &write_overlapped2);
3066 test_peek_pipe(reader, buf_size + 2000 + (msg_mode ? 0 : 1),
3067 buf_size + 2001, msg_mode ? buf_size + 2000 : 0);
3068 cancel_overlapped(writer, &write_overlapped);
3069 test_peek_pipe(reader, 1, 1, msg_mode ? 1 : 0);
3070 overlapped_read_sync(reader, read_buf, 1000, 1, FALSE);
3071 test_overlapped_result(writer, &write_overlapped2, 1, FALSE);
3072 test_peek_pipe(reader, 0, 0, 0);
3074 /* same as above, but parially read written data before canceling */
3075 overlapped_write_async(writer, buf, buf_size+2000, &write_overlapped);
3076 overlapped_write_async(writer, buf, 1, &write_overlapped2);
3077 test_peek_pipe(reader, buf_size + 2000 + (msg_mode ? 0 : 1),
3078 buf_size + 2001, msg_mode ? buf_size + 2000 : 0);
3079 overlapped_read_sync(reader, read_buf, 10, 10, msg_read);
3080 test_not_signaled(write_overlapped.hEvent);
3081 cancel_overlapped(writer, &write_overlapped);
3082 test_peek_pipe(reader, 1, 1, msg_mode ? 1 : 0);
3083 overlapped_read_sync(reader, read_buf, 1000, 1, FALSE);
3084 test_overlapped_result(writer, &write_overlapped2, 1, FALSE);
3085 test_peek_pipe(reader, 0, 0, 0);
3087 /* empty queue by canceling write and make sure that flush is signaled */
3088 overlapped_write_async(writer, buf, buf_size+2000, &write_overlapped);
3089 flush_thread = test_flush_async(writer, ERROR_SUCCESS);
3090 test_not_signaled(flush_thread);
3091 cancel_overlapped(writer, &write_overlapped);
3092 test_peek_pipe(reader, 0, 0, 0);
3093 test_flush_done(flush_thread);
3096 #define overlapped_transact(a,b,c,d,e,f) _overlapped_transact(__LINE__,a,b,c,d,e,f)
3097 static void _overlapped_transact(unsigned line, HANDLE caller, void *write_buf, DWORD write_size,
3098 void *read_buf, DWORD read_size, OVERLAPPED *overlapped)
3100 BOOL res;
3102 memset(overlapped, 0, sizeof(*overlapped));
3103 overlapped->hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
3104 res = TransactNamedPipe(caller, write_buf, write_size, read_buf, read_size, NULL, overlapped);
3105 ok_(__FILE__,line)(!res && GetLastError() == ERROR_IO_PENDING,
3106 "TransactNamedPipe returned: %x(%u)\n", res, GetLastError());
3109 #define overlapped_transact_failure(a,b,c,d,e,f) _overlapped_transact_failure(__LINE__,a,b,c,d,e,f)
3110 static void _overlapped_transact_failure(unsigned line, HANDLE caller, void *write_buf, DWORD write_size,
3111 void *read_buf, DWORD read_size, DWORD expected_error)
3113 OVERLAPPED overlapped;
3114 BOOL res;
3116 memset(&overlapped, 0, sizeof(overlapped));
3117 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
3118 res = TransactNamedPipe(caller, write_buf, write_size, read_buf, read_size, NULL, &overlapped);
3119 ok_(__FILE__,line)(!res, "TransactNamedPipe succeeded\n");
3121 if (GetLastError() == ERROR_IO_PENDING) /* win8+ */
3123 _test_overlapped_failure(line, caller, &overlapped, expected_error);
3125 else
3127 ok_(__FILE__,line)(GetLastError() == expected_error,
3128 "TransactNamedPipe returned error %u, expected %u\n",
3129 GetLastError(), expected_error);
3130 CloseHandle(overlapped.hEvent);
3134 static void child_process_write_pipe(HANDLE pipe)
3136 OVERLAPPED overlapped;
3137 char buf[10000];
3139 memset(buf, 'x', sizeof(buf));
3140 overlapped_write_async(pipe, buf, sizeof(buf), &overlapped);
3142 /* sleep until parent process terminates this process */
3143 Sleep(INFINITE);
3146 static HANDLE create_writepipe_process(HANDLE pipe)
3148 STARTUPINFOA si = { sizeof(si) };
3149 PROCESS_INFORMATION info;
3150 char **argv, buf[MAX_PATH];
3151 BOOL res;
3153 winetest_get_mainargs(&argv);
3154 sprintf(buf, "\"%s\" pipe writepipe %lx", argv[0], (UINT_PTR)pipe);
3155 res = CreateProcessA(NULL, buf, NULL, NULL, TRUE, 0L, NULL, NULL, &si, &info);
3156 ok(res, "CreateProcess failed: %u\n", GetLastError());
3157 CloseHandle(info.hThread);
3159 return info.hProcess;
3162 static void create_overlapped_pipe(DWORD mode, HANDLE *client, HANDLE *server)
3164 SECURITY_ATTRIBUTES sec_attr = { sizeof(sec_attr), NULL, TRUE };
3165 DWORD read_mode = mode & (PIPE_READMODE_BYTE | PIPE_READMODE_MESSAGE);
3166 OVERLAPPED overlapped;
3167 BOOL res;
3169 *server = CreateNamedPipeA(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX,
3170 PIPE_WAIT | mode, 1, 5000, 6000, NMPWAIT_USE_DEFAULT_WAIT, NULL);
3171 ok(*server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %u\n", GetLastError());
3172 test_signaled(*server);
3174 memset(&overlapped, 0, sizeof(overlapped));
3175 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
3176 res = ConnectNamedPipe(*server, &overlapped);
3177 ok(!res && GetLastError() == ERROR_IO_PENDING, "WriteFile returned %x(%u)\n", res, GetLastError());
3178 test_not_signaled(*server);
3179 test_not_signaled(overlapped.hEvent);
3181 *client = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, &sec_attr, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
3182 ok(*client != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError());
3184 res = SetNamedPipeHandleState(*client, &read_mode, NULL, NULL);
3185 ok(res, "SetNamedPipeHandleState failed: %u\n", GetLastError());
3187 test_signaled(*client);
3188 test_not_signaled(*server);
3189 test_overlapped_result(*server, &overlapped, 0, FALSE);
3192 static void test_overlapped_transport(BOOL msg_mode, BOOL msg_read_mode)
3194 OVERLAPPED overlapped, overlapped2;
3195 HANDLE server, client, flush;
3196 DWORD read_bytes;
3197 HANDLE process;
3198 char buf[60000];
3199 BOOL res;
3201 DWORD create_flags =
3202 (msg_mode ? PIPE_TYPE_MESSAGE : PIPE_TYPE_BYTE) |
3203 (msg_read_mode ? PIPE_READMODE_MESSAGE : PIPE_READMODE_BYTE);
3205 create_overlapped_pipe(create_flags, &client, &server);
3207 trace("testing %s, %s server->client writes...\n",
3208 msg_mode ? "message mode" : "byte mode", msg_read_mode ? "message read" : "byte read");
3209 test_blocking_rw(server, client, 5000, msg_mode, msg_read_mode);
3210 trace("testing %s, %s client->server writes...\n",
3211 msg_mode ? "message mode" : "byte mode", msg_read_mode ? "message read" : "byte read");
3212 test_blocking_rw(client, server, 6000, msg_mode, msg_read_mode);
3214 CloseHandle(client);
3215 CloseHandle(server);
3217 /* close client with pending writes */
3218 create_overlapped_pipe(create_flags, &client, &server);
3219 overlapped_write_async(server, buf, 7000, &overlapped);
3220 flush = test_flush_async(server, ERROR_BROKEN_PIPE);
3221 CloseHandle(client);
3222 test_overlapped_failure(server, &overlapped, ERROR_BROKEN_PIPE);
3223 test_flush_done(flush);
3224 CloseHandle(server);
3226 /* close server with pending writes */
3227 create_overlapped_pipe(create_flags, &client, &server);
3228 overlapped_write_async(client, buf, 7000, &overlapped);
3229 flush = test_flush_async(client, ERROR_BROKEN_PIPE);
3230 CloseHandle(server);
3231 test_overlapped_failure(client, &overlapped, ERROR_BROKEN_PIPE);
3232 test_flush_done(flush);
3233 CloseHandle(client);
3235 /* disconnect with pending writes */
3236 create_overlapped_pipe(create_flags, &client, &server);
3237 overlapped_write_async(client, buf, 7000, &overlapped);
3238 overlapped_write_async(server, buf, 7000, &overlapped2);
3239 flush = test_flush_async(client, ERROR_PIPE_NOT_CONNECTED);
3240 res = DisconnectNamedPipe(server);
3241 ok(res, "DisconnectNamedPipe failed: %u\n", GetLastError());
3242 test_overlapped_failure(client, &overlapped, ERROR_PIPE_NOT_CONNECTED);
3243 test_overlapped_failure(client, &overlapped2, ERROR_PIPE_NOT_CONNECTED);
3244 test_flush_done(flush);
3245 CloseHandle(server);
3246 CloseHandle(client);
3248 /* terminate process with pending write */
3249 create_overlapped_pipe(create_flags, &client, &server);
3250 process = create_writepipe_process(client);
3251 /* successfully read part of write that is pending in child process */
3252 res = ReadFile(server, buf, 10, &read_bytes, NULL);
3253 if(!msg_read_mode)
3254 ok(res, "ReadFile failed: %u\n", GetLastError());
3255 else
3256 ok(!res && GetLastError() == ERROR_MORE_DATA, "ReadFile returned: %x %u\n", res, GetLastError());
3257 ok(read_bytes == 10, "read_bytes = %u\n", read_bytes);
3258 TerminateProcess(process, 0);
3259 winetest_wait_child_process(process);
3260 /* after terminating process, there is no pending write and pipe buffer is empty */
3261 overlapped_read_async(server, buf, 10, &overlapped);
3262 overlapped_write_sync(client, buf, 1);
3263 test_overlapped_result(server, &overlapped, 1, FALSE);
3264 CloseHandle(process);
3265 CloseHandle(server);
3266 CloseHandle(client);
3269 static void test_transact(HANDLE caller, HANDLE callee, DWORD write_buf_size, DWORD read_buf_size)
3271 OVERLAPPED overlapped, overlapped2, read_overlapped, write_overlapped;
3272 char buf[10000], read_buf[10000];
3274 memset(buf, 0xaa, sizeof(buf));
3276 /* simple transact call */
3277 overlapped_transact(caller, (BYTE*)"abc", 3, read_buf, 100, &overlapped);
3278 overlapped_write_sync(callee, (BYTE*)"test", 4);
3279 test_overlapped_result(caller, &overlapped, 4, FALSE);
3280 ok(!memcmp(read_buf, "test", 4), "unexpected read_buf\n");
3281 overlapped_read_sync(callee, read_buf, 1000, 3, FALSE);
3282 ok(!memcmp(read_buf, "abc", 3), "unexpected read_buf\n");
3284 /* transact fails if there is already data in read buffer */
3285 overlapped_write_sync(callee, buf, 1);
3286 overlapped_transact_failure(caller, buf, 2, read_buf, 1, ERROR_PIPE_BUSY);
3287 overlapped_read_sync(caller, read_buf, 1000, 1, FALSE);
3289 /* transact doesn't block on write */
3290 overlapped_write_async(caller, buf, write_buf_size+2000, &write_overlapped);
3291 overlapped_transact(caller, buf, 2, read_buf, 1, &overlapped);
3292 test_not_signaled(overlapped.hEvent);
3293 overlapped_write_sync(callee, buf, 1);
3294 test_overlapped_result(caller, &overlapped, 1, FALSE);
3295 overlapped_read_sync(callee, read_buf, sizeof(read_buf), write_buf_size+2000, FALSE);
3296 test_overlapped_result(caller, &write_overlapped, write_buf_size+2000, FALSE);
3297 overlapped_read_sync(callee, read_buf, sizeof(read_buf), 2, FALSE);
3299 /* transact with already pending read */
3300 overlapped_read_async(callee, read_buf, 10, &read_overlapped);
3301 overlapped_transact(caller, buf, 5, read_buf, 6, &overlapped);
3302 test_overlapped_result(callee, &read_overlapped, 5, FALSE);
3303 test_not_signaled(overlapped.hEvent);
3304 overlapped_write_sync(callee, buf, 10);
3305 test_overlapped_result(caller, &overlapped, 6, TRUE);
3306 overlapped_read_sync(caller, read_buf, sizeof(read_buf), 4, FALSE);
3308 /* 0-size messages */
3309 overlapped_transact(caller, buf, 5, read_buf, 0, &overlapped);
3310 overlapped_read_sync(callee, read_buf, sizeof(read_buf), 5, FALSE);
3311 overlapped_write_sync(callee, buf, 0);
3312 test_overlapped_result(caller, &overlapped, 0, FALSE);
3314 overlapped_transact(caller, buf, 0, read_buf, 0, &overlapped);
3315 overlapped_read_sync(callee, read_buf, sizeof(read_buf), 0, FALSE);
3316 test_not_signaled(overlapped.hEvent);
3317 overlapped_write_sync(callee, buf, 0);
3318 test_overlapped_result(caller, &overlapped, 0, FALSE);
3320 /* reply transact with another transact */
3321 overlapped_transact(caller, buf, 3, read_buf, 100, &overlapped);
3322 overlapped_read_sync(callee, read_buf, 1000, 3, FALSE);
3323 overlapped_transact(callee, buf, 4, read_buf, 100, &overlapped2);
3324 test_overlapped_result(caller, &overlapped, 4, FALSE);
3325 overlapped_write_sync(caller, buf, 1);
3326 test_overlapped_result(caller, &overlapped2, 1, FALSE);
3328 if (!pCancelIoEx) return;
3330 /* cancel keeps written data */
3331 overlapped_write_async(caller, buf, write_buf_size+2000, &write_overlapped);
3332 overlapped_transact(caller, buf, 2, read_buf, 1, &overlapped);
3333 test_not_signaled(overlapped.hEvent);
3334 cancel_overlapped(caller, &overlapped);
3335 overlapped_read_sync(callee, read_buf, sizeof(read_buf), write_buf_size+2000, FALSE);
3336 test_overlapped_result(caller, &write_overlapped, write_buf_size+2000, FALSE);
3337 overlapped_read_sync(callee, read_buf, sizeof(read_buf), 2, FALSE);
3340 static void test_TransactNamedPipe(void)
3342 HANDLE client, server;
3343 BYTE buf[10];
3345 create_overlapped_pipe(PIPE_TYPE_BYTE, &client, &server);
3346 overlapped_transact_failure(client, buf, 2, buf, 1, ERROR_BAD_PIPE);
3347 CloseHandle(client);
3348 CloseHandle(server);
3350 create_overlapped_pipe(PIPE_TYPE_MESSAGE | PIPE_READMODE_BYTE, &client, &server);
3351 overlapped_transact_failure(client, buf, 2, buf, 1, ERROR_BAD_PIPE);
3352 CloseHandle(client);
3353 CloseHandle(server);
3355 trace("testing server->client transaction...\n");
3356 create_overlapped_pipe(PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, &client, &server);
3357 test_transact(server, client, 5000, 6000);
3358 CloseHandle(client);
3359 CloseHandle(server);
3361 trace("testing client->server transaction...\n");
3362 create_overlapped_pipe(PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, &client, &server);
3363 test_transact(client, server, 6000, 5000);
3364 CloseHandle(client);
3365 CloseHandle(server);
3368 static HANDLE create_overlapped_server( OVERLAPPED *overlapped )
3370 HANDLE pipe;
3371 BOOL ret;
3373 pipe = CreateNamedPipeA(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX, PIPE_READMODE_BYTE | PIPE_WAIT,
3374 1, 5000, 6000, NMPWAIT_USE_DEFAULT_WAIT, NULL);
3375 ok(pipe != INVALID_HANDLE_VALUE, "got %u\n", GetLastError());
3376 ret = ConnectNamedPipe(pipe, overlapped);
3377 ok(!ret && GetLastError() == ERROR_IO_PENDING, "got %u\n", GetLastError());
3378 return pipe;
3381 static void child_process_check_pid(DWORD server_pid)
3383 DWORD current = GetProcessId(GetCurrentProcess());
3384 HANDLE pipe;
3385 ULONG pid;
3386 BOOL ret;
3388 pipe = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
3389 ok(pipe != INVALID_HANDLE_VALUE, "got %u\n", GetLastError());
3391 pid = 0;
3392 ret = pGetNamedPipeClientProcessId(pipe, &pid);
3393 ok(ret, "got %u\n", GetLastError());
3394 ok(pid == current, "got %04x\n", pid);
3396 pid = 0;
3397 ret = pGetNamedPipeServerProcessId(pipe, &pid);
3398 ok(ret, "got %u\n", GetLastError());
3399 ok(pid == server_pid, "got %04x expected %04x\n", pid, server_pid);
3400 CloseHandle(pipe);
3403 static HANDLE create_check_id_process(const char *verb, DWORD id)
3405 STARTUPINFOA si = {sizeof(si)};
3406 PROCESS_INFORMATION info;
3407 char **argv, buf[MAX_PATH];
3408 BOOL ret;
3410 winetest_get_mainargs(&argv);
3411 sprintf(buf, "\"%s\" pipe %s %x", argv[0], verb, id);
3412 ret = CreateProcessA(NULL, buf, NULL, NULL, TRUE, 0, NULL, NULL, &si, &info);
3413 ok(ret, "got %u\n", GetLastError());
3414 CloseHandle(info.hThread);
3415 return info.hProcess;
3418 static void test_namedpipe_process_id(void)
3420 HANDLE client, server, process;
3421 DWORD current = GetProcessId(GetCurrentProcess());
3422 OVERLAPPED overlapped;
3423 ULONG pid;
3424 BOOL ret;
3426 if (!pGetNamedPipeClientProcessId)
3428 win_skip("GetNamedPipeClientProcessId not available\n");
3429 return;
3432 create_overlapped_pipe(PIPE_TYPE_BYTE, &client, &server);
3434 SetLastError(0xdeadbeef);
3435 ret = pGetNamedPipeClientProcessId(server, NULL);
3436 ok(!ret, "success\n");
3437 todo_wine ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
3439 pid = 0;
3440 ret = pGetNamedPipeClientProcessId(server, &pid);
3441 ok(ret, "got %u\n", GetLastError());
3442 ok(pid == current, "got %04x expected %04x\n", pid, current);
3444 pid = 0;
3445 ret = pGetNamedPipeClientProcessId(client, &pid);
3446 ok(ret, "got %u\n", GetLastError());
3447 ok(pid == current, "got %04x expected %04x\n", pid, current);
3449 SetLastError(0xdeadbeef);
3450 ret = pGetNamedPipeServerProcessId(server, NULL);
3451 ok(!ret, "success\n");
3452 todo_wine ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
3454 pid = 0;
3455 ret = pGetNamedPipeServerProcessId(client, &pid);
3456 ok(ret, "got %u\n", GetLastError());
3457 ok(pid == current, "got %04x expected %04x\n", pid, current);
3459 pid = 0;
3460 ret = pGetNamedPipeServerProcessId(server, &pid);
3461 ok(ret, "got %u\n", GetLastError());
3462 ok(pid == current, "got %04x expected %04x\n", pid, current);
3464 /* closed client handle */
3465 CloseHandle(client);
3466 pid = 0;
3467 ret = pGetNamedPipeClientProcessId(server, &pid);
3468 ok(ret, "got %u\n", GetLastError());
3469 ok(pid == current, "got %04x expected %04x\n", pid, current);
3471 pid = 0;
3472 ret = pGetNamedPipeServerProcessId(server, &pid);
3473 ok(ret, "got %u\n", GetLastError());
3474 ok(pid == current, "got %04x expected %04x\n", pid, current);
3475 CloseHandle(server);
3477 /* disconnected server */
3478 create_overlapped_pipe(PIPE_TYPE_BYTE, &client, &server);
3479 DisconnectNamedPipe(server);
3481 SetLastError(0xdeadbeef);
3482 ret = pGetNamedPipeClientProcessId(server, &pid);
3483 todo_wine ok(!ret, "success\n");
3484 todo_wine ok(GetLastError() == ERROR_NOT_FOUND, "got %u\n", GetLastError());
3486 pid = 0;
3487 ret = pGetNamedPipeServerProcessId(server, &pid);
3488 ok(ret, "got %u\n", GetLastError());
3489 ok(pid == current, "got %04x expected %04x\n", pid, current);
3491 SetLastError(0xdeadbeef);
3492 ret = pGetNamedPipeClientProcessId(client, &pid);
3493 todo_wine ok(!ret, "success\n");
3494 todo_wine ok(GetLastError() == ERROR_PIPE_NOT_CONNECTED, "got %u\n", GetLastError());
3496 SetLastError(0xdeadbeef);
3497 ret = pGetNamedPipeServerProcessId(client, &pid);
3498 todo_wine ok(!ret, "success\n");
3499 todo_wine ok(GetLastError() == ERROR_PIPE_NOT_CONNECTED, "got %u\n", GetLastError());
3500 CloseHandle(client);
3501 CloseHandle(server);
3503 /* closed server handle */
3504 create_overlapped_pipe(PIPE_TYPE_BYTE, &client, &server);
3505 CloseHandle(server);
3507 pid = 0;
3508 ret = pGetNamedPipeClientProcessId(client, &pid);
3509 ok(ret, "got %u\n", GetLastError());
3510 ok(pid == current, "got %04x expected %04x\n", pid, current);
3512 pid = 0;
3513 ret = pGetNamedPipeServerProcessId(client, &pid);
3514 ok(ret, "got %u\n", GetLastError());
3515 ok(pid == current, "got %04x expected %04x\n", pid, current);
3516 CloseHandle(client);
3518 /* different process */
3519 memset(&overlapped, 0, sizeof(overlapped));
3520 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
3521 server = create_overlapped_server( &overlapped );
3522 ok(server != INVALID_HANDLE_VALUE, "got %u\n", GetLastError());
3524 process = create_check_id_process("checkpid", GetProcessId(GetCurrentProcess()));
3525 winetest_wait_child_process(process);
3527 CloseHandle(overlapped.hEvent);
3528 CloseHandle(process);
3529 CloseHandle(server);
3532 static void child_process_check_session_id(DWORD server_id)
3534 DWORD current;
3535 HANDLE pipe;
3536 ULONG id;
3537 BOOL ret;
3539 ProcessIdToSessionId(GetProcessId(GetCurrentProcess()), &current);
3541 pipe = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
3542 ok(pipe != INVALID_HANDLE_VALUE, "got %u\n", GetLastError());
3544 id = 0;
3545 ret = pGetNamedPipeClientSessionId(pipe, &id);
3546 ok(ret, "got %u\n", GetLastError());
3547 ok(id == current, "got %04x\n", id);
3549 id = 0;
3550 ret = pGetNamedPipeServerSessionId(pipe, &id);
3551 ok(ret, "got %u\n", GetLastError());
3552 ok(id == server_id, "got %04x expected %04x\n", id, server_id);
3553 CloseHandle(pipe);
3556 static void test_namedpipe_session_id(void)
3558 HANDLE client, server, process;
3559 OVERLAPPED overlapped;
3560 DWORD current;
3561 ULONG id;
3562 BOOL ret;
3564 if (!pGetNamedPipeClientSessionId)
3566 win_skip("GetNamedPipeClientSessionId not available\n");
3567 return;
3570 ProcessIdToSessionId(GetProcessId(GetCurrentProcess()), &current);
3572 create_overlapped_pipe(PIPE_TYPE_BYTE, &client, &server);
3574 SetLastError(0xdeadbeef);
3575 ret = pGetNamedPipeClientSessionId(server, NULL);
3576 ok(!ret, "success\n");
3577 todo_wine ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
3579 id = 0;
3580 ret = pGetNamedPipeClientSessionId(server, &id);
3581 ok(ret, "got %u\n", GetLastError());
3582 ok(id == current, "got %u expected %u\n", id, current);
3584 id = 0;
3585 ret = pGetNamedPipeClientSessionId(client, &id);
3586 ok(ret, "got %u\n", GetLastError());
3587 ok(id == current, "got %u expected %u\n", id, current);
3589 SetLastError(0xdeadbeef);
3590 ret = pGetNamedPipeServerSessionId(server, NULL);
3591 ok(!ret, "success\n");
3592 todo_wine ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %u\n", GetLastError());
3594 id = 0;
3595 ret = pGetNamedPipeServerSessionId(client, &id);
3596 ok(ret, "got %u\n", GetLastError());
3597 ok(id == current, "got %u expected %u\n", id, current);
3599 id = 0;
3600 ret = pGetNamedPipeServerSessionId(server, &id);
3601 ok(ret, "got %u\n", GetLastError());
3602 ok(id == current, "got %u expected %u\n", id, current);
3604 /* closed client handle */
3605 CloseHandle(client);
3607 id = 0;
3608 ret = pGetNamedPipeClientSessionId(server, &id);
3609 ok(ret, "got %u\n", GetLastError());
3610 ok(id == current, "got %04x expected %04x\n", id, current);
3612 id = 0;
3613 ret = pGetNamedPipeServerSessionId(server, &id);
3614 ok(ret, "got %u\n", GetLastError());
3615 ok(id == current, "got %04x expected %04x\n", id, current);
3616 CloseHandle(server);
3618 /* disconnected server */
3619 create_overlapped_pipe(PIPE_TYPE_BYTE, &client, &server);
3620 DisconnectNamedPipe(server);
3622 SetLastError(0xdeadbeef);
3623 ret = pGetNamedPipeClientSessionId(server, &id);
3624 todo_wine ok(!ret, "success\n");
3625 todo_wine ok(GetLastError() == ERROR_NOT_FOUND, "got %u\n", GetLastError());
3627 id = 0;
3628 ret = pGetNamedPipeServerSessionId(server, &id);
3629 ok(ret, "got %u\n", GetLastError());
3630 ok(id == current, "got %04x expected %04x\n", id, current);
3632 SetLastError(0xdeadbeef);
3633 ret = pGetNamedPipeClientSessionId(client, &id);
3634 todo_wine ok(!ret, "success\n");
3635 todo_wine ok(GetLastError() == ERROR_PIPE_NOT_CONNECTED, "got %u\n", GetLastError());
3637 SetLastError(0xdeadbeef);
3638 ret = pGetNamedPipeServerSessionId(client, &id);
3639 todo_wine ok(!ret, "success\n");
3640 todo_wine ok(GetLastError() == ERROR_PIPE_NOT_CONNECTED, "got %u\n", GetLastError());
3641 CloseHandle(client);
3642 CloseHandle(server);
3644 /* closed server handle */
3645 create_overlapped_pipe(PIPE_TYPE_BYTE, &client, &server);
3646 CloseHandle(server);
3648 id = 0;
3649 ret = pGetNamedPipeClientSessionId(client, &id);
3650 ok(ret, "got %u\n", GetLastError());
3651 ok(id == current, "got %04x expected %04x\n", id, current);
3653 id = 0;
3654 ret = pGetNamedPipeServerSessionId(client, &id);
3655 ok(ret, "got %u\n", GetLastError());
3656 ok(id == current, "got %04x expected %04x\n", id, current);
3657 CloseHandle(client);
3659 /* different process */
3660 memset(&overlapped, 0, sizeof(overlapped));
3661 overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
3662 server = create_overlapped_server( &overlapped );
3663 ok(server != INVALID_HANDLE_VALUE, "got %u\n", GetLastError());
3665 process = create_check_id_process("checksessionid", current);
3666 winetest_wait_child_process(process);
3668 CloseHandle(overlapped.hEvent);
3669 CloseHandle(process);
3670 CloseHandle(server);
3673 START_TEST(pipe)
3675 char **argv;
3676 int argc;
3677 HMODULE hmod;
3679 hmod = GetModuleHandleA("advapi32.dll");
3680 pDuplicateTokenEx = (void *) GetProcAddress(hmod, "DuplicateTokenEx");
3681 hmod = GetModuleHandleA("kernel32.dll");
3682 pQueueUserAPC = (void *) GetProcAddress(hmod, "QueueUserAPC");
3683 pCancelIoEx = (void *) GetProcAddress(hmod, "CancelIoEx");
3684 pGetNamedPipeClientProcessId = (void *) GetProcAddress(hmod, "GetNamedPipeClientProcessId");
3685 pGetNamedPipeServerProcessId = (void *) GetProcAddress(hmod, "GetNamedPipeServerProcessId");
3686 pGetNamedPipeClientSessionId = (void *) GetProcAddress(hmod, "GetNamedPipeClientSessionId");
3687 pGetNamedPipeServerSessionId = (void *) GetProcAddress(hmod, "GetNamedPipeServerSessionId");
3689 argc = winetest_get_mainargs(&argv);
3691 if (argc > 3)
3693 if (!strcmp(argv[2], "writepipe"))
3695 UINT_PTR handle;
3696 sscanf(argv[3], "%lx", &handle);
3697 child_process_write_pipe((HANDLE)handle);
3698 return;
3700 if (!strcmp(argv[2], "checkpid"))
3702 DWORD pid = GetProcessId(GetCurrentProcess());
3703 sscanf(argv[3], "%x", &pid);
3704 child_process_check_pid(pid);
3705 return;
3707 if (!strcmp(argv[2], "checksessionid"))
3709 DWORD id;
3710 ProcessIdToSessionId(GetProcessId(GetCurrentProcess()), &id);
3711 sscanf(argv[3], "%x", &id);
3712 child_process_check_session_id(id);
3713 return;
3717 if (test_DisconnectNamedPipe())
3718 return;
3719 test_CreateNamedPipe_instances_must_match();
3720 test_NamedPipe_2();
3721 test_CreateNamedPipe(PIPE_TYPE_BYTE);
3722 test_CreateNamedPipe(PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE);
3723 test_CreatePipe();
3724 test_ReadFile();
3725 test_CloseHandle();
3726 test_impersonation();
3727 test_overlapped();
3728 test_overlapped_error();
3729 test_NamedPipeHandleState();
3730 test_GetNamedPipeInfo();
3731 test_readfileex_pending();
3732 test_overlapped_transport(TRUE, FALSE);
3733 test_overlapped_transport(TRUE, TRUE);
3734 test_overlapped_transport(FALSE, FALSE);
3735 test_TransactNamedPipe();
3736 test_namedpipe_process_id();
3737 test_namedpipe_session_id();