1 /*
2  * Unit tests for named pipe functions in Wine
3  *
4  * Copyright (c) 2002 Dan Kegel
5  *
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.
10  *
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.
15  *
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
19  */
20 
21 #include <stdarg.h>
22 #include <stdio.h>
23 
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"
31 
32 #define PIPENAME "\\\\.\\PiPe\\tests_pipe.c"
33 #define PIPENAME_SPECIAL "\\\\.\\PiPe\\tests->pipe.c"
34 
35 #define NB_SERVER_LOOPS 8
36 
37 static HANDLE alarm_event;
38 static BOOL (WINAPI *pDuplicateTokenEx)(HANDLE,DWORD,LPSECURITY_ATTRIBUTES,
39                                         SECURITY_IMPERSONATION_LEVEL,TOKEN_TYPE,PHANDLE);
40 static DWORD (WINAPI *pQueueUserAPC)(PAPCFUNC pfnAPC, HANDLE hThread, ULONG_PTR dwData);
41 static BOOL (WINAPI *pCancelIoEx)(HANDLE handle, LPOVERLAPPED lpOverlapped);
42 
43 static BOOL user_apc_ran;
44 static void CALLBACK user_apc(ULONG_PTR param)
45 {
46     user_apc_ran = TRUE;
47 }
48 
49 
50 enum rpcThreadOp
51 {
52     RPC_READFILE
53 };
54 
55 struct rpcThreadArgs
56 {
57     ULONG_PTR returnValue;
58     DWORD lastError;
59     enum rpcThreadOp op;
60     ULONG_PTR args[5];
61 };
62 
63 static DWORD CALLBACK rpcThreadMain(LPVOID arg)
64 {
65     struct rpcThreadArgs *rpcargs = (struct rpcThreadArgs *)arg;
66     if (winetest_debug > 1) trace("rpcThreadMain starting\n");
67     SetLastError( rpcargs->lastError );
68 
69     switch (rpcargs->op)
70     {
71         case RPC_READFILE:
72             rpcargs->returnValue = (ULONG_PTR)ReadFile( (HANDLE)rpcargs->args[0],         /* hFile */
73                                                         (LPVOID)rpcargs->args[1],         /* buffer */
74                                                         (DWORD)rpcargs->args[2],          /* bytesToRead */
75                                                         (LPDWORD)rpcargs->args[3],        /* bytesRead */
76                                                         (LPOVERLAPPED)rpcargs->args[4] ); /* overlapped */
77             break;
78 
79         default:
80             SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
81             rpcargs->returnValue = 0;
82             break;
83     }
84 
85     rpcargs->lastError = GetLastError();
86     if (winetest_debug > 1) trace("rpcThreadMain returning\n");
87     return 0;
88 }
89 
90 /* Runs ReadFile(...) from a different thread */
91 static BOOL RpcReadFile(HANDLE hFile, LPVOID buffer, DWORD bytesToRead, LPDWORD bytesRead, LPOVERLAPPED overlapped)
92 {
93     struct rpcThreadArgs rpcargs;
94     HANDLE thread;
95     DWORD threadId, ret;
96 
97     rpcargs.returnValue = 0;
98     rpcargs.lastError = GetLastError();
99     rpcargs.op = RPC_READFILE;
100     rpcargs.args[0] = (ULONG_PTR)hFile;
101     rpcargs.args[1] = (ULONG_PTR)buffer;
102     rpcargs.args[2] = (ULONG_PTR)bytesToRead;
103     rpcargs.args[3] = (ULONG_PTR)bytesRead;
104     rpcargs.args[4] = (ULONG_PTR)overlapped;
105 
106     thread = CreateThread(NULL, 0, rpcThreadMain, (void *)&rpcargs, 0, &threadId);
107     ok(thread != NULL, "CreateThread failed. %d\n", GetLastError());
108     ret = WaitForSingleObject(thread, INFINITE);
109     ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed with %d.\n", GetLastError());
110     CloseHandle(thread);
111 
112     SetLastError(rpcargs.lastError);
113     return (BOOL)rpcargs.returnValue;
114 }
115 
116 #define test_not_signaled(h) _test_not_signaled(__LINE__,h)
117 static void _test_not_signaled(unsigned line, HANDLE handle)
118 {
119     DWORD res = WaitForSingleObject(handle, 0);
120     ok_(__FILE__,line)(res == WAIT_TIMEOUT, "WaitForSingleObject returned %u (%u)\n", res, GetLastError());
121 }
122 
123 #define test_signaled(h) _test_signaled(__LINE__,h)
124 static void _test_signaled(unsigned line, HANDLE handle)
125 {
126     DWORD res = WaitForSingleObject(handle, 0);
127     ok_(__FILE__,line)(res == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", res);
128 }
129 
130 #define test_pipe_info(a,b,c,d,e) _test_pipe_info(__LINE__,a,b,c,d,e)
131 static void _test_pipe_info(unsigned line, HANDLE pipe, DWORD ex_flags, DWORD ex_out_buf_size, DWORD ex_in_buf_size, DWORD ex_max_instances)
132 {
133     DWORD flags = 0xdeadbeef, out_buf_size = 0xdeadbeef, in_buf_size = 0xdeadbeef, max_instances = 0xdeadbeef;
134     BOOL res;
135 
136     res = GetNamedPipeInfo(pipe, &flags, &out_buf_size, &in_buf_size, &max_instances);
137     ok_(__FILE__,line)(res, "GetNamedPipeInfo failed: %x\n", res);
138     ok_(__FILE__,line)(flags == ex_flags, "flags = %x, expected %x\n", flags, ex_flags);
139     ok_(__FILE__,line)(out_buf_size == ex_out_buf_size, "out_buf_size = %x, expected %u\n", out_buf_size, ex_out_buf_size);
140     ok_(__FILE__,line)(in_buf_size == ex_in_buf_size, "in_buf_size = %x, expected %u\n", in_buf_size, ex_in_buf_size);
141     ok_(__FILE__,line)(max_instances == ex_max_instances, "max_instances = %x, expected %u\n", max_instances, ex_max_instances);
142 }
143 
144 static void test_CreateNamedPipe(int pipemode)
145 {
146     HANDLE hnp;
147     HANDLE hFile;
148     static const char obuf[] = "Bit Bucket";
149     static const char obuf2[] = "More bits";
150     char ibuf[32], *pbuf;
151     DWORD written;
152     DWORD readden;
153     DWORD avail;
154     DWORD left;
155     DWORD lpmode;
156     BOOL ret;
157 
158     if (pipemode == PIPE_TYPE_BYTE)
159         trace("test_CreateNamedPipe starting in byte mode\n");
160     else
161         trace("test_CreateNamedPipe starting in message mode\n");
162 
163     /* Wait for nonexistent pipe */
164     ret = WaitNamedPipeA(PIPENAME, 2000);
165     ok(ret == 0, "WaitNamedPipe returned %d for nonexistent pipe\n", ret);
166     ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
167 
168     /* Bad parameter checks */
169     hnp = CreateNamedPipeA("not a named pipe", PIPE_ACCESS_DUPLEX, pipemode | PIPE_WAIT,
170         /* nMaxInstances */ 1,
171         /* nOutBufSize */ 1024,
172         /* nInBufSize */ 1024,
173         /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
174         /* lpSecurityAttrib */ NULL);
175     ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_NAME,
176         "CreateNamedPipe should fail if name doesn't start with \\\\.\\pipe\n");
177 
178     if (pipemode == PIPE_TYPE_BYTE)
179     {
180         /* Bad parameter checks */
181         hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_MESSAGE,
182             /* nMaxInstances */ 1,
183             /* nOutBufSize */ 1024,
184             /* nInBufSize */ 1024,
185             /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
186             /* lpSecurityAttrib */ NULL);
187         ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_PARAMETER,
188             "CreateNamedPipe should fail with PIPE_TYPE_BYTE | PIPE_READMODE_MESSAGE\n");
189     }
190 
191     hnp = CreateNamedPipeA(NULL,
192         PIPE_ACCESS_DUPLEX, pipemode | PIPE_WAIT,
193         1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL);
194     ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
195         "CreateNamedPipe should fail if name is NULL\n");
196 
197     hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
198     ok(hFile == INVALID_HANDLE_VALUE
199         && GetLastError() == ERROR_FILE_NOT_FOUND,
200         "connecting to nonexistent named pipe should fail with ERROR_FILE_NOT_FOUND\n");
201 
202     /* Functional checks */
203 
204     hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, pipemode | PIPE_WAIT,
205         /* nMaxInstances */ 1,
206         /* nOutBufSize */ 1024,
207         /* nInBufSize */ 1024,
208         /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
209         /* lpSecurityAttrib */ NULL);
210     ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
211     test_signaled(hnp);
212 
213     ret = PeekNamedPipe(hnp, NULL, 0, NULL, &readden, NULL);
214     todo_wine
215     ok(!ret && GetLastError() == ERROR_BAD_PIPE, "PeekNamedPipe returned %x (%u)\n",
216        ret, GetLastError());
217 
218     ret = WaitNamedPipeA(PIPENAME, 2000);
219     ok(ret, "WaitNamedPipe failed (%d)\n", GetLastError());
220 
221     hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
222     ok(hFile != INVALID_HANDLE_VALUE, "CreateFile failed (%d)\n", GetLastError());
223 
224     ok(!WaitNamedPipeA(PIPENAME, 100), "WaitNamedPipe succeeded\n");
225 
226     ok(GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %u\n", GetLastError());
227 
228     /* Test ConnectNamedPipe() in both directions */
229     ok(!ConnectNamedPipe(hnp, NULL), "ConnectNamedPipe(server) succeeded\n");
230     ok(GetLastError() == ERROR_PIPE_CONNECTED, "expected ERROR_PIPE_CONNECTED, got %u\n", GetLastError());
231     ok(!ConnectNamedPipe(hFile, NULL), "ConnectNamedPipe(client) succeeded\n");
232     ok(GetLastError() == ERROR_INVALID_FUNCTION, "expected ERROR_INVALID_FUNCTION, got %u\n", GetLastError());
233 
234     /* don't try to do i/o if one side couldn't be opened, as it hangs */
235     if (hFile != INVALID_HANDLE_VALUE) {
236         HANDLE hFile2;
237 
238         /* Make sure we can read and write a few bytes in both directions */
239         memset(ibuf, 0, sizeof(ibuf));
240         ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile\n");
241         ok(written == sizeof(obuf), "write file len\n");
242         ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
243         ok(readden == sizeof(obuf), "read got %d bytes\n", readden);
244         ok(memcmp(obuf, ibuf, written) == 0, "content check\n");
245 
246         memset(ibuf, 0, sizeof(ibuf));
247         ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), "WriteFile\n");
248         ok(written == sizeof(obuf2), "write file len\n");
249         ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
250         ok(readden == sizeof(obuf2), "read got %d bytes\n", readden);
251         ok(memcmp(obuf2, ibuf, written) == 0, "content check\n");
252 
253         /* Now the same again, but with an additional call to PeekNamedPipe */
254         memset(ibuf, 0, sizeof(ibuf));
255         ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile\n");
256         ok(written == sizeof(obuf), "write file len 1\n");
257         ok(PeekNamedPipe(hFile, NULL, 0, NULL, &avail, &left), "Peek\n");
258         ok(avail == sizeof(obuf), "peek 1 got %d bytes\n", avail);
259         if (pipemode == PIPE_TYPE_BYTE)
260             ok(left == 0, "peek 1 got %d bytes left\n", left);
261         else
262             ok(left == sizeof(obuf), "peek 1 got %d bytes left\n", left);
263         ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
264         ok(readden == sizeof(obuf), "read 1 got %d bytes\n", readden);
265         ok(memcmp(obuf, ibuf, written) == 0, "content 1 check\n");
266 
267         memset(ibuf, 0, sizeof(ibuf));
268         ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), "WriteFile\n");
269         ok(written == sizeof(obuf2), "write file len 2\n");
270         ok(PeekNamedPipe(hnp, NULL, 0, NULL, &avail, &left), "Peek\n");
271         ok(avail == sizeof(obuf2), "peek 2 got %d bytes\n", avail);
272         if (pipemode == PIPE_TYPE_BYTE)
273             ok(left == 0, "peek 2 got %d bytes left\n", left);
274         else
275             ok(left == sizeof(obuf2), "peek 2 got %d bytes left\n", left);
276         ok(PeekNamedPipe(hnp, (LPVOID)1, 0, NULL, &avail, &left), "Peek\n");
277         ok(avail == sizeof(obuf2), "peek 2 got %d bytes\n", avail);
278         if (pipemode == PIPE_TYPE_BYTE)
279             ok(left == 0, "peek 2 got %d bytes left\n", left);
280         else
281             ok(left == sizeof(obuf2), "peek 2 got %d bytes left\n", left);
282         ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
283         ok(readden == sizeof(obuf2), "read 2 got %d bytes\n", readden);
284         ok(memcmp(obuf2, ibuf, written) == 0, "content 2 check\n");
285 
286         /* Test how ReadFile behaves when the buffer is not big enough for the whole message */
287         memset(ibuf, 0, sizeof(ibuf));
288         ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), "WriteFile\n");
289         ok(written == sizeof(obuf2), "write file len\n");
290         ok(PeekNamedPipe(hFile, ibuf, 4, &readden, &avail, &left), "Peek\n");
291         ok(readden == 4, "peek got %d bytes\n", readden);
292         ok(avail == sizeof(obuf2), "peek got %d bytes available\n", avail);
293         if (pipemode == PIPE_TYPE_BYTE)
294             ok(left == -4, "peek got %d bytes left\n", left);
295         else
296             ok(left == sizeof(obuf2)-4, "peek got %d bytes left\n", left);
297         ok(ReadFile(hFile, ibuf, 4, &readden, NULL), "ReadFile\n");
298         ok(readden == 4, "read got %d bytes\n", readden);
299         ok(ReadFile(hFile, ibuf + 4, sizeof(ibuf) - 4, &readden, NULL), "ReadFile\n");
300         ok(readden == sizeof(obuf2) - 4, "read got %d bytes\n", readden);
301         ok(memcmp(obuf2, ibuf, written) == 0, "content check\n");
302 
303         memset(ibuf, 0, sizeof(ibuf));
304         ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile\n");
305         ok(written == sizeof(obuf), "write file len\n");
306         ok(PeekNamedPipe(hnp, ibuf, 4, &readden, &avail, &left), "Peek\n");
307         ok(readden == 4, "peek got %d bytes\n", readden);
308         ok(avail == sizeof(obuf), "peek got %d bytes available\n", avail);
309         if (pipemode == PIPE_TYPE_BYTE)
310         {
311             ok(left == -4, "peek got %d bytes left\n", left);
312             ok(ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile\n");
313         }
314         else
315         {
316             ok(left == sizeof(obuf)-4, "peek got %d bytes left\n", left);
317             SetLastError(0xdeadbeef);
318             ok(!ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile\n");
319             ok(GetLastError() == ERROR_MORE_DATA, "wrong error\n");
320         }
321         ok(readden == 4, "read got %d bytes\n", readden);
322         ok(ReadFile(hnp, ibuf + 4, sizeof(ibuf) - 4, &readden, NULL), "ReadFile\n");
323         ok(readden == sizeof(obuf) - 4, "read got %d bytes\n", readden);
324         ok(memcmp(obuf, ibuf, written) == 0, "content check\n");
325 
326         /* Similar to above, but use a read buffer size small enough to read in three parts */
327         memset(ibuf, 0, sizeof(ibuf));
328         ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), "WriteFile\n");
329         ok(written == sizeof(obuf2), "write file len\n");
330         if (pipemode == PIPE_TYPE_BYTE)
331         {
332             ok(ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile\n");
333             ok(readden == 4, "read got %d bytes\n", readden);
334             ok(ReadFile(hnp, ibuf + 4, 4, &readden, NULL), "ReadFile\n");
335         }
336         else
337         {
338             SetLastError(0xdeadbeef);
339             ok(!ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile\n");
340             ok(GetLastError() == ERROR_MORE_DATA, "wrong error\n");
341             ok(readden == 4, "read got %d bytes\n", readden);
342             SetLastError(0xdeadbeef);
343             ok(!ReadFile(hnp, ibuf + 4, 4, &readden, NULL), "ReadFile\n");
344             ok(GetLastError() == ERROR_MORE_DATA, "wrong error\n");
345         }
346         ok(readden == 4, "read got %d bytes\n", readden);
347         ok(ReadFile(hnp, ibuf + 8, sizeof(ibuf) - 8, &readden, NULL), "ReadFile\n");
348         ok(readden == sizeof(obuf2) - 8, "read got %d bytes\n", readden);
349         ok(memcmp(obuf2, ibuf, written) == 0, "content check\n");
350 
351         /* Test reading of multiple writes */
352         memset(ibuf, 0, sizeof(ibuf));
353         ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile3a\n");
354         ok(written == sizeof(obuf), "write file len 3a\n");
355         ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), " WriteFile3b\n");
356         ok(written == sizeof(obuf2), "write file len 3b\n");
357         ok(PeekNamedPipe(hFile, ibuf, 4, &readden, &avail, &left), "Peek3\n");
358         ok(readden == 4, "peek3 got %d bytes\n", readden);
359         if (pipemode == PIPE_TYPE_BYTE)
360             ok(left == -4, "peek3 got %d bytes left\n", left);
361         else
362             ok(left == sizeof(obuf)-4, "peek3 got %d bytes left\n", left);
363         ok(avail == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes available\n", avail);
364         ok(PeekNamedPipe(hFile, ibuf, sizeof(ibuf), &readden, &avail, &left), "Peek3\n");
365         if (pipemode == PIPE_TYPE_BYTE) {
366             ok(readden == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes\n", readden);
367             ok(left == (DWORD) -(sizeof(obuf) + sizeof(obuf2)), "peek3 got %d bytes left\n", left);
368         }
369         else
370         {
371             ok(readden == sizeof(obuf), "peek3 got %d bytes\n", readden);
372             ok(left == 0, "peek3 got %d bytes left\n", left);
373         }
374         ok(avail == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes available\n", avail);
375         pbuf = ibuf;
376         ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "pipe content 3a check\n");
377         if (pipemode == PIPE_TYPE_BYTE && readden >= sizeof(obuf)+sizeof(obuf2)) {
378             pbuf += sizeof(obuf);
379             ok(memcmp(obuf2, pbuf, sizeof(obuf2)) == 0, "pipe content 3b check\n");
380         }
381         ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
382         ok(readden == sizeof(obuf) + sizeof(obuf2), "read 3 got %d bytes\n", readden);
383         pbuf = ibuf;
384         ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 3a check\n");
385         pbuf += sizeof(obuf);
386         ok(memcmp(obuf2, pbuf, sizeof(obuf2)) == 0, "content 3b check\n");
387 
388         /* Multiple writes in the reverse direction */
389         memset(ibuf, 0, sizeof(ibuf));
390         ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile4a\n");
391         ok(written == sizeof(obuf), "write file len 4a\n");
392         ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), " WriteFile4b\n");
393         ok(written == sizeof(obuf2), "write file len 4b\n");
394         ok(PeekNamedPipe(hnp, ibuf, 4, &readden, &avail, &left), "Peek3\n");
395         ok(readden == 4, "peek3 got %d bytes\n", readden);
396         if (pipemode == PIPE_TYPE_BYTE)
397             ok(left == -4, "peek3 got %d bytes left\n", left);
398         else
399             ok(left == sizeof(obuf)-4, "peek3 got %d bytes left\n", left);
400         ok(avail == sizeof(obuf) + sizeof(obuf2), "peek3 got %d bytes available\n", avail);
401         ok(PeekNamedPipe(hnp, ibuf, sizeof(ibuf), &readden, &avail, &left), "Peek4\n");
402         if (pipemode == PIPE_TYPE_BYTE) {
403             ok(readden == sizeof(obuf) + sizeof(obuf2), "peek4 got %d bytes\n", readden);
404             ok(left == (DWORD) -(sizeof(obuf) + sizeof(obuf2)), "peek4 got %d bytes left\n", left);
405         }
406         else
407         {
408             ok(readden == sizeof(obuf), "peek4 got %d bytes\n", readden);
409             ok(left == 0, "peek4 got %d bytes left\n", left);
410         }
411         ok(avail == sizeof(obuf) + sizeof(obuf2), "peek4 got %d bytes available\n", avail);
412         pbuf = ibuf;
413         ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "pipe content 4a check\n");
414         if (pipemode == PIPE_TYPE_BYTE && readden >= sizeof(obuf)+sizeof(obuf2)) {
415             pbuf += sizeof(obuf);
416             ok(memcmp(obuf2, pbuf, sizeof(obuf2)) == 0, "pipe content 4b check\n");
417         }
418         ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
419         if (pipemode == PIPE_TYPE_BYTE) {
420             ok(readden == sizeof(obuf) + sizeof(obuf2), "read 4 got %d bytes\n", readden);
421         }
422         else {
423             ok(readden == sizeof(obuf), "read 4 got %d bytes\n", readden);
424         }
425         pbuf = ibuf;
426         ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 4a check\n");
427         if (pipemode == PIPE_TYPE_BYTE) {
428             pbuf += sizeof(obuf);
429             ok(memcmp(obuf2, pbuf, sizeof(obuf2)) == 0, "content 4b check\n");
430         }
431 
432         /* Test reading of multiple writes after a mode change
433           (CreateFile always creates a byte mode pipe) */
434         lpmode = PIPE_READMODE_MESSAGE;
435         if (pipemode == PIPE_TYPE_BYTE) {
436             /* trying to change the client end of a byte pipe to message mode should fail */
437             ok(!SetNamedPipeHandleState(hFile, &lpmode, NULL, NULL), "Change mode\n");
438         }
439         else {
440             ok(SetNamedPipeHandleState(hFile, &lpmode, NULL, NULL), "Change mode\n");
441 
442             memset(ibuf, 0, sizeof(ibuf));
443             ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile5a\n");
444             ok(written == sizeof(obuf), "write file len 3a\n");
445             ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), " WriteFile5b\n");
446             ok(written == sizeof(obuf2), "write file len 3b\n");
447             ok(PeekNamedPipe(hFile, ibuf, sizeof(ibuf), &readden, &avail, &left), "Peek5\n");
448             ok(readden == sizeof(obuf), "peek5 got %d bytes\n", readden);
449             ok(avail == sizeof(obuf) + sizeof(obuf2), "peek5 got %d bytes available\n", avail);
450             ok(left == 0, "peek5 got %d bytes left\n", left);
451             pbuf = ibuf;
452             ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 5a check\n");
453             ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
454             ok(readden == sizeof(obuf), "read 5 got %d bytes\n", readden);
455             pbuf = ibuf;
456             ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 5a check\n");
457             if (readden <= sizeof(obuf))
458                 ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
459 
460             /* Multiple writes in the reverse direction */
461             /* the write of obuf2 from write4 should still be in the buffer */
462             ok(PeekNamedPipe(hnp, ibuf, sizeof(ibuf), &readden, &avail, NULL), "Peek6a\n");
463             ok(readden == sizeof(obuf2), "peek6a got %d bytes\n", readden);
464             ok(avail == sizeof(obuf2), "peek6a got %d bytes available\n", avail);
465             if (avail > 0) {
466                 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
467                 ok(readden == sizeof(obuf2), "read 6a got %d bytes\n", readden);
468                 pbuf = ibuf;
469                 ok(memcmp(obuf2, pbuf, sizeof(obuf2)) == 0, "content 6a check\n");
470             }
471             memset(ibuf, 0, sizeof(ibuf));
472             ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile6a\n");
473             ok(written == sizeof(obuf), "write file len 6a\n");
474             ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), " WriteFile6b\n");
475             ok(written == sizeof(obuf2), "write file len 6b\n");
476             ok(PeekNamedPipe(hnp, ibuf, sizeof(ibuf), &readden, &avail, NULL), "Peek6\n");
477             ok(readden == sizeof(obuf), "peek6 got %d bytes\n", readden);
478 
479             ok(avail == sizeof(obuf) + sizeof(obuf2), "peek6b got %d bytes available\n", avail);
480             pbuf = ibuf;
481             ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 6a check\n");
482             ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
483             ok(readden == sizeof(obuf), "read 6b got %d bytes\n", readden);
484             pbuf = ibuf;
485             ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 6a check\n");
486             if (readden <= sizeof(obuf))
487                 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
488 
489             /* Test how ReadFile behaves when the buffer is not big enough for the whole message */
490             memset(ibuf, 0, sizeof(ibuf));
491             ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), "WriteFile 7\n");
492             ok(written == sizeof(obuf2), "write file len 7\n");
493             SetLastError(0xdeadbeef);
494             ok(!ReadFile(hFile, ibuf, 4, &readden, NULL), "ReadFile 7\n");
495             ok(GetLastError() == ERROR_MORE_DATA, "wrong error 7\n");
496             ok(readden == 4, "read got %d bytes 7\n", readden);
497             ok(ReadFile(hFile, ibuf + 4, sizeof(ibuf) - 4, &readden, NULL), "ReadFile 7\n");
498             ok(readden == sizeof(obuf2) - 4, "read got %d bytes 7\n", readden);
499             ok(memcmp(obuf2, ibuf, written) == 0, "content check 7\n");
500 
501             memset(ibuf, 0, sizeof(ibuf));
502             ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile 8\n");
503             ok(written == sizeof(obuf), "write file len 8\n");
504             SetLastError(0xdeadbeef);
505             ok(!ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile 8\n");
506             ok(GetLastError() == ERROR_MORE_DATA, "wrong error 8\n");
507             ok(readden == 4, "read got %d bytes 8\n", readden);
508             ok(ReadFile(hnp, ibuf + 4, sizeof(ibuf) - 4, &readden, NULL), "ReadFile 8\n");
509             ok(readden == sizeof(obuf) - 4, "read got %d bytes 8\n", readden);
510             ok(memcmp(obuf, ibuf, written) == 0, "content check 8\n");
511 
512             /* The following test shows that when doing a partial read of a message, the rest
513              * is still in the pipe, and can be received from a second thread. This shows
514              * especially that the content is _not_ stored in thread-local-storage until it is
515              * completely transmitted. The same method works even across multiple processes. */
516             memset(ibuf, 0, sizeof(ibuf));
517             ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile 9\n");
518             ok(written == sizeof(obuf), "write file len 9\n");
519             ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), "WriteFile 9\n");
520             ok(written == sizeof(obuf2), "write file len 9\n");
521             SetLastError(0xdeadbeef);
522             ok(!ReadFile(hFile, ibuf, 4, &readden, NULL), "ReadFile 9\n");
523             ok(GetLastError() == ERROR_MORE_DATA, "wrong error 9\n");
524             ok(readden == 4, "read got %d bytes 9\n", readden);
525             SetLastError(0xdeadbeef);
526             ret = RpcReadFile(hFile, ibuf + 4, 4, &readden, NULL);
527             ok(!ret, "RpcReadFile 9\n");
528             ok(GetLastError() == ERROR_MORE_DATA, "wrong error 9\n");
529             ok(readden == 4, "read got %d bytes 9\n", readden);
530             ret = RpcReadFile(hFile, ibuf + 8, sizeof(ibuf), &readden, NULL);
531             ok(ret, "RpcReadFile 9\n");
532             ok(readden == sizeof(obuf) - 8, "read got %d bytes 9\n", readden);
533             ok(memcmp(obuf, ibuf, sizeof(obuf)) == 0, "content check 9\n");
534             if (readden <= sizeof(obuf) - 8) /* blocks forever if second part was already received */
535             {
536                 memset(ibuf, 0, sizeof(ibuf));
537                 SetLastError(0xdeadbeef);
538                 ret = RpcReadFile(hFile, ibuf, 4, &readden, NULL);
539                 ok(!ret, "RpcReadFile 9\n");
540                 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 9\n");
541                 ok(readden == 4, "read got %d bytes 9\n", readden);
542                 SetLastError(0xdeadbeef);
543                 ok(!ReadFile(hFile, ibuf + 4, 4, &readden, NULL), "ReadFile 9\n");
544                 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 9\n");
545                 ok(readden == 4, "read got %d bytes 9\n", readden);
546                 ret = RpcReadFile(hFile, ibuf + 8, sizeof(ibuf), &readden, NULL);
547                 ok(ret, "RpcReadFile 9\n");
548                 ok(readden == sizeof(obuf2) - 8, "read got %d bytes 9\n", readden);
549                 ok(memcmp(obuf2, ibuf, sizeof(obuf2)) == 0, "content check 9\n");
550             }
551 
552             /* Now the reverse direction */
553             memset(ibuf, 0, sizeof(ibuf));
554             ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), "WriteFile 10\n");
555             ok(written == sizeof(obuf2), "write file len 10\n");
556             ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile 10\n");
557             ok(written == sizeof(obuf), "write file len 10\n");
558             SetLastError(0xdeadbeef);
559             ok(!ReadFile(hnp, ibuf, 4, &readden, NULL), "ReadFile 10\n");
560             ok(GetLastError() == ERROR_MORE_DATA, "wrong error 10\n");
561             ok(readden == 4, "read got %d bytes 10\n", readden);
562             SetLastError(0xdeadbeef);
563             ret = RpcReadFile(hnp, ibuf + 4, 4, &readden, NULL);
564             ok(!ret, "RpcReadFile 10\n");
565             ok(GetLastError() == ERROR_MORE_DATA, "wrong error 10\n");
566             ok(readden == 4, "read got %d bytes 10\n", readden);
567             ret = RpcReadFile(hnp, ibuf + 8, sizeof(ibuf), &readden, NULL);
568             ok(ret, "RpcReadFile 10\n");
569             ok(readden == sizeof(obuf2) - 8, "read got %d bytes 10\n", readden);
570             ok(memcmp(obuf2, ibuf, sizeof(obuf2)) == 0, "content check 10\n");
571             if (readden <= sizeof(obuf2) - 8) /* blocks forever if second part was already received */
572             {
573                 memset(ibuf, 0, sizeof(ibuf));
574                 SetLastError(0xdeadbeef);
575                 ret = RpcReadFile(hnp, ibuf, 4, &readden, NULL);
576                 ok(!ret, "RpcReadFile 10\n");
577                 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 10\n");
578                 ok(readden == 4, "read got %d bytes 10\n", readden);
579                 SetLastError(0xdeadbeef);
580                 ok(!ReadFile(hnp, ibuf + 4, 4, &readden, NULL), "ReadFile 10\n");
581                 ok(GetLastError() == ERROR_MORE_DATA, "wrong error 10\n");
582                 ok(readden == 4, "read got %d bytes 10\n", readden);
583                 ret = RpcReadFile(hnp, ibuf + 8, sizeof(ibuf), &readden, NULL);
584                 ok(ret, "RpcReadFile 10\n");
585                 ok(readden == sizeof(obuf) - 8, "read got %d bytes 10\n", readden);
586                 ok(memcmp(obuf, ibuf, sizeof(obuf)) == 0, "content check 10\n");
587             }
588 
589         }
590 
591         /* Picky conformance tests */
592 
593         /* Verify that you can't connect to pipe again
594          * until server calls DisconnectNamedPipe+ConnectNamedPipe
595          * or creates a new pipe
596          * case 1: other client not yet closed
597          */
598         hFile2 = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
599         ok(hFile2 == INVALID_HANDLE_VALUE,
600             "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n");
601         ok(GetLastError() == ERROR_PIPE_BUSY,
602             "connecting to named pipe before other client closes should fail with ERROR_PIPE_BUSY\n");
603 
604         ok(CloseHandle(hFile), "CloseHandle\n");
605 
606         /* case 2: other client already closed */
607         hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
608         ok(hFile == INVALID_HANDLE_VALUE,
609             "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n");
610         ok(GetLastError() == ERROR_PIPE_BUSY,
611             "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail with ERROR_PIPE_BUSY\n");
612 
613         ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n");
614 
615         /* case 3: server has called DisconnectNamedPipe but not ConnectNamed Pipe */
616         hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
617         ok(hFile == INVALID_HANDLE_VALUE,
618             "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n");
619         ok(GetLastError() == ERROR_PIPE_BUSY,
620             "connecting to named pipe after other client closes but before ConnectNamedPipe should fail with ERROR_PIPE_BUSY\n");
621 
622         /* to be complete, we'd call ConnectNamedPipe here and loop,
623          * but by default that's blocking, so we'd either have
624          * to turn on the uncommon nonblocking mode, or
625          * use another thread.
626          */
627     }
628 
629     ok(CloseHandle(hnp), "CloseHandle\n");
630 
631     hnp = CreateNamedPipeA(PIPENAME_SPECIAL, PIPE_ACCESS_DUPLEX, pipemode | PIPE_WAIT,
632         /* nMaxInstances */ 1,
633         /* nOutBufSize */ 1024,
634         /* nInBufSize */ 1024,
635         /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
636         /* lpSecurityAttrib */ NULL);
637     ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe with special characters failed\n");
638     ok(CloseHandle(hnp), "CloseHandle\n");
639 
640     if (winetest_debug > 1) trace("test_CreateNamedPipe returning\n");
641 }
642 
643 static void test_CreateNamedPipe_instances_must_match(void)
644 {
645     HANDLE hnp, hnp2;
646 
647     /* Check no mismatch */
648     hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
649         /* nMaxInstances */ 2,
650         /* nOutBufSize */ 1024,
651         /* nInBufSize */ 1024,
652         /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
653         /* lpSecurityAttrib */ NULL);
654     ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
655 
656     hnp2 = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
657         /* nMaxInstances */ 2,
658         /* nOutBufSize */ 1024,
659         /* nInBufSize */ 1024,
660         /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
661         /* lpSecurityAttrib */ NULL);
662     ok(hnp2 != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
663 
664     ok(CloseHandle(hnp), "CloseHandle\n");
665     ok(CloseHandle(hnp2), "CloseHandle\n");
666 
667     /* Check nMaxInstances */
668     hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
669         /* nMaxInstances */ 1,
670         /* nOutBufSize */ 1024,
671         /* nInBufSize */ 1024,
672         /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
673         /* lpSecurityAttrib */ NULL);
674     ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
675 
676     hnp2 = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
677         /* nMaxInstances */ 1,
678         /* nOutBufSize */ 1024,
679         /* nInBufSize */ 1024,
680         /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
681         /* lpSecurityAttrib */ NULL);
682     ok(hnp2 == INVALID_HANDLE_VALUE
683         && GetLastError() == ERROR_PIPE_BUSY, "nMaxInstances not obeyed\n");
684 
685     ok(CloseHandle(hnp), "CloseHandle\n");
686 
687     /* Check PIPE_ACCESS_* */
688     hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
689         /* nMaxInstances */ 2,
690         /* nOutBufSize */ 1024,
691         /* nInBufSize */ 1024,
692         /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
693         /* lpSecurityAttrib */ NULL);
694     ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
695 
696     hnp2 = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE | PIPE_WAIT,
697         /* nMaxInstances */ 2,
698         /* nOutBufSize */ 1024,
699         /* nInBufSize */ 1024,
700         /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
701         /* lpSecurityAttrib */ NULL);
702     ok(hnp2 == INVALID_HANDLE_VALUE
703         && GetLastError() == ERROR_ACCESS_DENIED, "PIPE_ACCESS_* mismatch allowed\n");
704 
705     ok(CloseHandle(hnp), "CloseHandle\n");
706 
707     /* check everything else */
708     hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
709         /* nMaxInstances */ 4,
710         /* nOutBufSize */ 1024,
711         /* nInBufSize */ 1024,
712         /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
713         /* lpSecurityAttrib */ NULL);
714     ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
715 
716     hnp2 = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE,
717         /* nMaxInstances */ 3,
718         /* nOutBufSize */ 102,
719         /* nInBufSize */ 24,
720         /* nDefaultWait */ 1234,
721         /* lpSecurityAttrib */ NULL);
722     ok(hnp2 != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
723 
724     ok(CloseHandle(hnp), "CloseHandle\n");
725     ok(CloseHandle(hnp2), "CloseHandle\n");
726 }
727 
728 static void test_ReadFile(void)
729 {
730     HANDLE server, client;
731     OVERLAPPED overlapped;
732     DWORD size;
733     BOOL res;
734 
735     static char buf[512];
736 
737     server = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX,
738                               PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
739                               1, 1024, 1024, NMPWAIT_WAIT_FOREVER, NULL);
740     ok(server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %u\n", GetLastError());
741 
742     client = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL,
743                          OPEN_EXISTING, 0, 0);
744     ok(client != INVALID_HANDLE_VALUE, "CreateFile failed with %u\n", GetLastError());
745 
746     ok(WriteFile(client, buf, sizeof(buf), &size, NULL), "WriteFile\n");
747 
748     res = ReadFile(server, buf, 1, &size, NULL);
749     ok(!res && GetLastError() == ERROR_MORE_DATA, "ReadFile returned %x(%u)\n", res, GetLastError());
750     ok(size == 1, "size = %u\n", size);
751 
752     /* pass both overlapped and ret read */
753     memset(&overlapped, 0, sizeof(overlapped));
754     res = ReadFile(server, buf, 1, &size, &overlapped);
755     ok(!res && GetLastError() == ERROR_MORE_DATA, "ReadFile returned %x(%u)\n", res, GetLastError());
756     ok(size == 0, "size = %u\n", size);
757     ok((NTSTATUS)overlapped.Internal == STATUS_BUFFER_OVERFLOW, "Internal = %lx\n", overlapped.Internal);
758     ok(overlapped.InternalHigh == 1, "InternalHigh = %lx\n", overlapped.InternalHigh);
759 
760     DisconnectNamedPipe(server);
761 
762     memset(&overlapped, 0, sizeof(overlapped));
763     overlapped.InternalHigh = 0xdeadbeef;
764     res = ReadFile(server, buf, 1, &size, &overlapped);
765     ok(!res && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "ReadFile returned %x(%u)\n", res, GetLastError());
766     ok(size == 0, "size = %u\n", size);
767     ok(overlapped.Internal == STATUS_PENDING, "Internal = %lx\n", overlapped.Internal);
768     ok(overlapped.InternalHigh == 0xdeadbeef, "InternalHigh = %lx\n", overlapped.InternalHigh);
769 
770     memset(&overlapped, 0, sizeof(overlapped));
771     overlapped.InternalHigh = 0xdeadbeef;
772     res = WriteFile(server, buf, 1, &size, &overlapped);
773     ok(!res && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "ReadFile returned %x(%u)\n", res, GetLastError());
774     ok(size == 0, "size = %u\n", size);
775     ok(overlapped.Internal == STATUS_PENDING, "Internal = %lx\n", overlapped.Internal);
776     ok(overlapped.InternalHigh == 0xdeadbeef, "InternalHigh = %lx\n", overlapped.InternalHigh);
777 
778     CloseHandle(server);
779     CloseHandle(client);
780 }
781 
782 /** implementation of alarm() */
783 static DWORD CALLBACK alarmThreadMain(LPVOID arg)
784 {
785     DWORD_PTR timeout = (DWORD_PTR) arg;
786     if (winetest_debug > 1) trace("alarmThreadMain\n");
787     if (WaitForSingleObject( alarm_event, timeout ) == WAIT_TIMEOUT)
788     {
789         ok(FALSE, "alarm\n");
790         ExitProcess(1);
791     }
792     return 1;
793 }
794 
795 static HANDLE hnp = INVALID_HANDLE_VALUE;
796 
797 /** Trivial byte echo server - disconnects after each session */
798 static DWORD CALLBACK serverThreadMain1(LPVOID arg)
799 {
800     int i;
801 
802     if (winetest_debug > 1) trace("serverThreadMain1 start\n");
803     /* Set up a simple echo server */
804     hnp = CreateNamedPipeA(PIPENAME "serverThreadMain1", PIPE_ACCESS_DUPLEX,
805         PIPE_TYPE_BYTE | PIPE_WAIT,
806         /* nMaxInstances */ 1,
807         /* nOutBufSize */ 1024,
808         /* nInBufSize */ 1024,
809         /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
810         /* lpSecurityAttrib */ NULL);
811 
812     ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
813     for (i = 0; i < NB_SERVER_LOOPS; i++) {
814         char buf[512];
815         DWORD written;
816         DWORD readden;
817         BOOL success;
818 
819         /* Wait for client to connect */
820         if (winetest_debug > 1) trace("Server calling ConnectNamedPipe...\n");
821         ok(ConnectNamedPipe(hnp, NULL)
822             || GetLastError() == ERROR_PIPE_CONNECTED, "ConnectNamedPipe\n");
823         if (winetest_debug > 1) trace("ConnectNamedPipe returned.\n");
824 
825         /* Echo bytes once */
826         memset(buf, 0, sizeof(buf));
827 
828         if (winetest_debug > 1) trace("Server reading...\n");
829         success = ReadFile(hnp, buf, sizeof(buf), &readden, NULL);
830         if (winetest_debug > 1) trace("Server done reading.\n");
831         ok(success, "ReadFile\n");
832         ok(readden, "short read\n");
833 
834         if (winetest_debug > 1) trace("Server writing...\n");
835         ok(WriteFile(hnp, buf, readden, &written, NULL), "WriteFile\n");
836         if (winetest_debug > 1) trace("Server done writing.\n");
837         ok(written == readden, "write file len\n");
838 
839         /* finish this connection, wait for next one */
840         ok(FlushFileBuffers(hnp), "FlushFileBuffers\n");
841         if (winetest_debug > 1) trace("Server done flushing.\n");
842         ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n");
843         if (winetest_debug > 1) trace("Server done disconnecting.\n");
844     }
845     return 0;
846 }
847 
848 /** Trivial byte echo server - closes after each connection */
849 static DWORD CALLBACK serverThreadMain2(LPVOID arg)
850 {
851     int i;
852     HANDLE hnpNext = 0;
853 
854     trace("serverThreadMain2\n");
855     /* Set up a simple echo server */
856     hnp = CreateNamedPipeA(PIPENAME "serverThreadMain2", PIPE_ACCESS_DUPLEX,
857         PIPE_TYPE_BYTE | PIPE_WAIT,
858         /* nMaxInstances */ 2,
859         /* nOutBufSize */ 1024,
860         /* nInBufSize */ 1024,
861         /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
862         /* lpSecurityAttrib */ NULL);
863     ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
864 
865     for (i = 0; i < NB_SERVER_LOOPS; i++) {
866         char buf[512];
867         DWORD written;
868         DWORD readden;
869         DWORD ret;
870         BOOL success;
871 
872 
873         user_apc_ran = FALSE;
874         if (i == 0 && pQueueUserAPC) {
875             if (winetest_debug > 1) trace("Queueing an user APC\n"); /* verify the pipe is non alerable */
876             ret = pQueueUserAPC(&user_apc, GetCurrentThread(), 0);
877             ok(ret, "QueueUserAPC failed: %d\n", GetLastError());
878         }
879 
880         /* Wait for client to connect */
881         if (winetest_debug > 1) trace("Server calling ConnectNamedPipe...\n");
882         ok(ConnectNamedPipe(hnp, NULL)
883             || GetLastError() == ERROR_PIPE_CONNECTED, "ConnectNamedPipe\n");
884         if (winetest_debug > 1) trace("ConnectNamedPipe returned.\n");
885 
886         /* Echo bytes once */
887         memset(buf, 0, sizeof(buf));
888 
889         if (winetest_debug > 1) trace("Server reading...\n");
890         success = ReadFile(hnp, buf, sizeof(buf), &readden, NULL);
891         if (winetest_debug > 1) trace("Server done reading.\n");
892         ok(success, "ReadFile\n");
893 
894         if (winetest_debug > 1) trace("Server writing...\n");
895         ok(WriteFile(hnp, buf, readden, &written, NULL), "WriteFile\n");
896         if (winetest_debug > 1) trace("Server done writing.\n");
897         ok(written == readden, "write file len\n");
898 
899         /* finish this connection, wait for next one */
900         ok(FlushFileBuffers(hnp), "FlushFileBuffers\n");
901         ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n");
902 
903         ok(user_apc_ran == FALSE, "UserAPC ran, pipe using alertable io mode\n");
904 
905         if (i == 0 && pQueueUserAPC)
906             SleepEx(0, TRUE); /* get rid of apc */
907 
908         /* Set up next echo server */
909         hnpNext =
910             CreateNamedPipeA(PIPENAME "serverThreadMain2", PIPE_ACCESS_DUPLEX,
911             PIPE_TYPE_BYTE | PIPE_WAIT,
912             /* nMaxInstances */ 2,
913             /* nOutBufSize */ 1024,
914             /* nInBufSize */ 1024,
915             /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
916             /* lpSecurityAttrib */ NULL);
917 
918         ok(hnpNext != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
919 
920         ok(CloseHandle(hnp), "CloseHandle\n");
921         hnp = hnpNext;
922     }
923     return 0;
924 }
925 
926 /** Trivial byte echo server - uses overlapped named pipe calls */
927 static DWORD CALLBACK serverThreadMain3(LPVOID arg)
928 {
929     int i;
930     HANDLE hEvent;
931 
932     if (winetest_debug > 1) trace("serverThreadMain3\n");
933     /* Set up a simple echo server */
934     hnp = CreateNamedPipeA(PIPENAME "serverThreadMain3", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
935         PIPE_TYPE_BYTE | PIPE_WAIT,
936         /* nMaxInstances */ 1,
937         /* nOutBufSize */ 1024,
938         /* nInBufSize */ 1024,
939         /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
940         /* lpSecurityAttrib */ NULL);
941     ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
942 
943     hEvent = CreateEventW(NULL,  /* security attribute */
944         TRUE,                   /* manual reset event */
945         FALSE,                  /* initial state */
946         NULL);                  /* name */
947     ok(hEvent != NULL, "CreateEvent\n");
948 
949     for (i = 0; i < NB_SERVER_LOOPS; i++) {
950         char buf[512];
951         DWORD written;
952         DWORD readden;
953         DWORD dummy;
954         BOOL success;
955         OVERLAPPED oOverlap;
956         int letWFSOEwait = (i & 2);
957         int letGORwait = (i & 1);
958         DWORD err;
959 
960         memset(&oOverlap, 0, sizeof(oOverlap));
961         oOverlap.hEvent = hEvent;
962 
963         /* Wait for client to connect */
964         if (i == 0) {
965             if (winetest_debug > 1) trace("Server calling non-overlapped ConnectNamedPipe on overlapped pipe...\n");
966             success = ConnectNamedPipe(hnp, NULL);
967             err = GetLastError();
968             ok(success || (err == ERROR_PIPE_CONNECTED), "ConnectNamedPipe failed: %d\n", err);
969             if (winetest_debug > 1) trace("ConnectNamedPipe operation complete.\n");
970         } else {
971             if (winetest_debug > 1) trace("Server calling overlapped ConnectNamedPipe...\n");
972             success = ConnectNamedPipe(hnp, &oOverlap);
973             err = GetLastError();
974             ok(!success && (err == ERROR_IO_PENDING || err == ERROR_PIPE_CONNECTED), "overlapped ConnectNamedPipe\n");
975             if (winetest_debug > 1) trace("overlapped ConnectNamedPipe returned.\n");
976             if (!success && (err == ERROR_IO_PENDING)) {
977                 if (letWFSOEwait)
978                 {
979                     DWORD ret;
980                     do {
981                         ret = WaitForSingleObjectEx(hEvent, INFINITE, TRUE);
982                     } while (ret == WAIT_IO_COMPLETION);
983                     ok(ret == 0, "wait ConnectNamedPipe returned %x\n", ret);
984                 }
985                 success = GetOverlappedResult(hnp, &oOverlap, &dummy, letGORwait);
986                 if (!letGORwait && !letWFSOEwait && !success) {
987                     ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult\n");
988                     success = GetOverlappedResult(hnp, &oOverlap, &dummy, TRUE);
989                 }
990             }
991             ok(success || (err == ERROR_PIPE_CONNECTED), "GetOverlappedResult ConnectNamedPipe\n");
992             if (winetest_debug > 1) trace("overlapped ConnectNamedPipe operation complete.\n");
993         }
994 
995         /* Echo bytes once */
996         memset(buf, 0, sizeof(buf));
997 
998         if (winetest_debug > 1) trace("Server reading...\n");
999         success = ReadFile(hnp, buf, sizeof(buf), &readden, &oOverlap);
1000         if (winetest_debug > 1) trace("Server ReadFile returned...\n");
1001         err = GetLastError();
1002         ok(success || err == ERROR_IO_PENDING, "overlapped ReadFile\n");
1003         if (winetest_debug > 1) trace("overlapped ReadFile returned.\n");
1004         if (!success && (err == ERROR_IO_PENDING)) {
1005             if (letWFSOEwait)
1006             {
1007                 DWORD ret;
1008                 do {
1009                     ret = WaitForSingleObjectEx(hEvent, INFINITE, TRUE);
1010                 } while (ret == WAIT_IO_COMPLETION);
1011                 ok(ret == 0, "wait ReadFile returned %x\n", ret);
1012             }
1013             success = GetOverlappedResult(hnp, &oOverlap, &readden, letGORwait);
1014             if (!letGORwait && !letWFSOEwait && !success) {
1015                 ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult\n");
1016                 success = GetOverlappedResult(hnp, &oOverlap, &readden, TRUE);
1017             }
1018         }
1019         if (winetest_debug > 1) trace("Server done reading.\n");
1020         ok(success, "overlapped ReadFile\n");
1021 
1022         if (winetest_debug > 1) trace("Server writing...\n");
1023         success = WriteFile(hnp, buf, readden, &written, &oOverlap);
1024         if (winetest_debug > 1) trace("Server WriteFile returned...\n");
1025         err = GetLastError();
1026         ok(success || err == ERROR_IO_PENDING, "overlapped WriteFile\n");
1027         if (winetest_debug > 1) trace("overlapped WriteFile returned.\n");
1028         if (!success && (err == ERROR_IO_PENDING)) {
1029             if (letWFSOEwait)
1030             {
1031                 DWORD ret;
1032                 do {
1033                     ret = WaitForSingleObjectEx(hEvent, INFINITE, TRUE);
1034                 } while (ret == WAIT_IO_COMPLETION);
1035                 ok(ret == 0, "wait WriteFile returned %x\n", ret);
1036             }
1037             success = GetOverlappedResult(hnp, &oOverlap, &written, letGORwait);
1038             if (!letGORwait && !letWFSOEwait && !success) {
1039                 ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult\n");
1040                 success = GetOverlappedResult(hnp, &oOverlap, &written, TRUE);
1041             }
1042         }
1043         if (winetest_debug > 1) trace("Server done writing.\n");
1044         ok(success, "overlapped WriteFile\n");
1045         ok(written == readden, "write file len\n");
1046 
1047         /* finish this connection, wait for next one */
1048         ok(FlushFileBuffers(hnp), "FlushFileBuffers\n");
1049         ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n");
1050     }
1051     return 0;
1052 }
1053 
1054 /** Trivial byte echo server - uses i/o completion ports */
1055 static DWORD CALLBACK serverThreadMain4(LPVOID arg)
1056 {
1057     int i;
1058     HANDLE hcompletion;
1059     BOOL ret;
1060 
1061     if (winetest_debug > 1) trace("serverThreadMain4\n");
1062     /* Set up a simple echo server */
1063     hnp = CreateNamedPipeA(PIPENAME "serverThreadMain4", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
1064         PIPE_TYPE_BYTE | PIPE_WAIT,
1065         /* nMaxInstances */ 1,
1066         /* nOutBufSize */ 1024,
1067         /* nInBufSize */ 1024,
1068         /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
1069         /* lpSecurityAttrib */ NULL);
1070     ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
1071 
1072     hcompletion = CreateIoCompletionPort(hnp, NULL, 12345, 1);
1073     ok(hcompletion != NULL, "CreateIoCompletionPort failed, error=%i\n", GetLastError());
1074 
1075     for (i = 0; i < NB_SERVER_LOOPS; i++) {
1076         char buf[512];
1077         DWORD written;
1078         DWORD readden;
1079         DWORD dummy;
1080         BOOL success;
1081         OVERLAPPED oConnect;
1082         OVERLAPPED oRead;
1083         OVERLAPPED oWrite;
1084         OVERLAPPED *oResult;
1085         DWORD err;
1086         ULONG_PTR compkey;
1087 
1088         memset(&oConnect, 0, sizeof(oConnect));
1089         memset(&oRead, 0, sizeof(oRead));
1090         memset(&oWrite, 0, sizeof(oWrite));
1091 
1092         /* Wait for client to connect */
1093         if (winetest_debug > 1) trace("Server calling overlapped ConnectNamedPipe...\n");
1094         success = ConnectNamedPipe(hnp, &oConnect);
1095         err = GetLastError();
1096         ok(!success && (err == ERROR_IO_PENDING || err == ERROR_PIPE_CONNECTED),
1097            "overlapped ConnectNamedPipe got %u err %u\n", success, err );
1098         if (!success && err == ERROR_IO_PENDING) {
1099             if (winetest_debug > 1) trace("ConnectNamedPipe GetQueuedCompletionStatus\n");
1100             success = GetQueuedCompletionStatus(hcompletion, &dummy, &compkey, &oResult, 0);
1101             if (!success)
1102             {
1103                 ok( GetLastError() == WAIT_TIMEOUT,
1104                     "ConnectNamedPipe GetQueuedCompletionStatus wrong error %u\n", GetLastError());
1105                 success = GetQueuedCompletionStatus(hcompletion, &dummy, &compkey, &oResult, 10000);
1106             }
1107             ok(success, "ConnectNamedPipe GetQueuedCompletionStatus failed, errno=%i\n", GetLastError());
1108             if (success)
1109             {
1110                 ok(compkey == 12345, "got completion key %i instead of 12345\n", (int)compkey);
1111                 ok(oResult == &oConnect, "got overlapped pointer %p instead of %p\n", oResult, &oConnect);
1112             }
1113         }
1114         if (winetest_debug > 1) trace("overlapped ConnectNamedPipe operation complete.\n");
1115 
1116         /* Echo bytes once */
1117         memset(buf, 0, sizeof(buf));
1118 
1119         if (winetest_debug > 1) trace("Server reading...\n");
1120         success = ReadFile(hnp, buf, sizeof(buf), &readden, &oRead);
1121         if (winetest_debug > 1) trace("Server ReadFile returned...\n");
1122         err = GetLastError();
1123         ok(success || err == ERROR_IO_PENDING, "overlapped ReadFile, err=%i\n", err);
1124         success = GetQueuedCompletionStatus(hcompletion, &readden, &compkey,
1125             &oResult, 10000);
1126         ok(success, "ReadFile GetQueuedCompletionStatus failed, errno=%i\n", GetLastError());
1127         if (success)
1128         {
1129             ok(compkey == 12345, "got completion key %i instead of 12345\n", (int)compkey);
1130             ok(oResult == &oRead, "got overlapped pointer %p instead of %p\n", oResult, &oRead);
1131         }
1132         if (winetest_debug > 1) trace("Server done reading.\n");
1133 
1134         if (winetest_debug > 1) trace("Server writing...\n");
1135         success = WriteFile(hnp, buf, readden, &written, &oWrite);
1136         if (winetest_debug > 1) trace("Server WriteFile returned...\n");
1137         err = GetLastError();
1138         ok(success || err == ERROR_IO_PENDING, "overlapped WriteFile failed, err=%u\n", err);
1139         success = GetQueuedCompletionStatus(hcompletion, &written, &compkey,
1140             &oResult, 10000);
1141         ok(success, "WriteFile GetQueuedCompletionStatus failed, errno=%i\n", GetLastError());
1142         if (success)
1143         {
1144             ok(compkey == 12345, "got completion key %i instead of 12345\n", (int)compkey);
1145             ok(oResult == &oWrite, "got overlapped pointer %p instead of %p\n", oResult, &oWrite);
1146             ok(written == readden, "write file len\n");
1147         }
1148         if (winetest_debug > 1) trace("Server done writing.\n");
1149 
1150         /* Client will finish this connection, the following ops will trigger broken pipe errors. */
1151 
1152         /* Wait for the pipe to break. */
1153         while (PeekNamedPipe(hnp, NULL, 0, NULL, &written, &written));
1154 
1155         if (winetest_debug > 1) trace("Server writing on disconnected pipe...\n");
1156         SetLastError(ERROR_SUCCESS);
1157         success = WriteFile(hnp, buf, readden, &written, &oWrite);
1158         err = GetLastError();
1159         todo_wine_if (!success && err == ERROR_PIPE_NOT_CONNECTED) ok(!success && err == ERROR_NO_DATA,
1160             "overlapped WriteFile on disconnected pipe returned %u, err=%i\n", success, err);
1161 
1162         /* No completion status is queued on immediate error. */
1163         SetLastError(ERROR_SUCCESS);
1164         oResult = (OVERLAPPED *)0xdeadbeef;
1165         success = GetQueuedCompletionStatus(hcompletion, &written, &compkey,
1166             &oResult, 0);
1167         err = GetLastError();
1168         ok(!success && err == WAIT_TIMEOUT && !oResult,
1169            "WriteFile GetQueuedCompletionStatus returned %u, err=%i, oResult %p\n",
1170            success, err, oResult);
1171 
1172         if (winetest_debug > 1) trace("Server reading from disconnected pipe...\n");
1173         SetLastError(ERROR_SUCCESS);
1174         success = ReadFile(hnp, buf, sizeof(buf), &readden, &oRead);
1175         if (winetest_debug > 1) trace("Server ReadFile from disconnected pipe returned...\n");
1176         err = GetLastError();
1177         ok(!success && err == ERROR_BROKEN_PIPE,
1178             "overlapped ReadFile on disconnected pipe returned %u, err=%i\n", success, err);
1179 
1180         SetLastError(ERROR_SUCCESS);
1181         oResult = (OVERLAPPED *)0xdeadbeef;
1182         success = GetQueuedCompletionStatus(hcompletion, &readden, &compkey,
1183             &oResult, 0);
1184         err = GetLastError();
1185         ok(!success && err == WAIT_TIMEOUT && !oResult,
1186            "ReadFile GetQueuedCompletionStatus returned %u, err=%i, oResult %p\n",
1187            success, err, oResult);
1188 
1189         /* finish this connection, wait for next one */
1190         ok(FlushFileBuffers(hnp), "FlushFileBuffers\n");
1191         success = DisconnectNamedPipe(hnp);
1192         ok(success, "DisconnectNamedPipe failed, err %u\n", GetLastError());
1193     }
1194 
1195     ret = CloseHandle(hnp);
1196     ok(ret, "CloseHandle named pipe failed, err=%i\n", GetLastError());
1197     ret = CloseHandle(hcompletion);
1198     ok(ret, "CloseHandle completion failed, err=%i\n", GetLastError());
1199 
1200     return 0;
1201 }
1202 
1203 static int completion_called;
1204 static DWORD completion_errorcode;
1205 static DWORD completion_num_bytes;
1206 static LPOVERLAPPED completion_lpoverlapped;
1207 
1208 static VOID WINAPI completion_routine(DWORD errorcode, DWORD num_bytes, LPOVERLAPPED lpoverlapped)
1209 {
1210     completion_called++;
1211     completion_errorcode = errorcode;
1212     completion_num_bytes = num_bytes;
1213     completion_lpoverlapped = lpoverlapped;
1214     SetEvent(lpoverlapped->hEvent);
1215 }
1216 
1217 /** Trivial byte echo server - uses ReadFileEx/WriteFileEx */
1218 static DWORD CALLBACK serverThreadMain5(LPVOID arg)
1219 {
1220     int i;
1221     HANDLE hEvent;
1222 
1223     if (winetest_debug > 1) trace("serverThreadMain5\n");
1224     /* Set up a simple echo server */
1225     hnp = CreateNamedPipeA(PIPENAME "serverThreadMain5", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
1226         PIPE_TYPE_BYTE | PIPE_WAIT,
1227         /* nMaxInstances */ 1,
1228         /* nOutBufSize */ 1024,
1229         /* nInBufSize */ 1024,
1230         /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
1231         /* lpSecurityAttrib */ NULL);
1232     ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
1233 
1234     hEvent = CreateEventW(NULL,  /* security attribute */
1235         TRUE,                   /* manual reset event */
1236         FALSE,                  /* initial state */
1237         NULL);                  /* name */
1238     ok(hEvent != NULL, "CreateEvent\n");
1239 
1240     for (i = 0; i < NB_SERVER_LOOPS; i++) {
1241         char buf[512];
1242         DWORD readden;
1243         BOOL success;
1244         OVERLAPPED oOverlap;
1245         DWORD err;
1246 
1247         memset(&oOverlap, 0, sizeof(oOverlap));
1248         oOverlap.hEvent = hEvent;
1249 
1250         /* Wait for client to connect */
1251         if (winetest_debug > 1) trace("Server calling ConnectNamedPipe...\n");
1252         success = ConnectNamedPipe(hnp, NULL);
1253         err = GetLastError();
1254         ok(success || (err == ERROR_PIPE_CONNECTED), "ConnectNamedPipe failed: %d\n", err);
1255         if (winetest_debug > 1) trace("ConnectNamedPipe operation complete.\n");
1256 
1257         /* Echo bytes once */
1258         memset(buf, 0, sizeof(buf));
1259 
1260         if (winetest_debug > 1) trace("Server reading...\n");
1261         completion_called = 0;
1262         ResetEvent(hEvent);
1263         success = ReadFileEx(hnp, buf, sizeof(buf), &oOverlap, completion_routine);
1264         if (winetest_debug > 1) trace("Server ReadFileEx returned...\n");
1265         ok(success, "ReadFileEx failed, err=%i\n", GetLastError());
1266         ok(completion_called == 0, "completion routine called before ReadFileEx return\n");
1267         if (winetest_debug > 1) trace("ReadFileEx returned.\n");
1268         if (success) {
1269             DWORD ret;
1270             do {
1271                 ret = WaitForSingleObjectEx(hEvent, INFINITE, TRUE);
1272             } while (ret == WAIT_IO_COMPLETION);
1273             ok(ret == 0, "wait ReadFileEx returned %x\n", ret);
1274         }
1275         ok(completion_called == 1, "completion routine called %i times\n", completion_called);
1276         ok(completion_errorcode == ERROR_SUCCESS, "completion routine got error %d\n", completion_errorcode);
1277         ok(completion_num_bytes != 0, "read 0 bytes\n");
1278         ok(completion_lpoverlapped == &oOverlap, "got wrong overlapped pointer %p\n", completion_lpoverlapped);
1279         readden = completion_num_bytes;
1280         if (winetest_debug > 1) trace("Server done reading.\n");
1281 
1282         if (winetest_debug > 1) trace("Server writing...\n");
1283         completion_called = 0;
1284         ResetEvent(hEvent);
1285         success = WriteFileEx(hnp, buf, readden, &oOverlap, completion_routine);
1286         if (winetest_debug > 1) trace("Server WriteFileEx returned...\n");
1287         ok(success, "WriteFileEx failed, err=%i\n", GetLastError());
1288         ok(completion_called == 0, "completion routine called before ReadFileEx return\n");
1289         if (winetest_debug > 1) trace("overlapped WriteFile returned.\n");
1290         if (success) {
1291             DWORD ret;
1292             do {
1293                 ret = WaitForSingleObjectEx(hEvent, INFINITE, TRUE);
1294             } while (ret == WAIT_IO_COMPLETION);
1295             ok(ret == 0, "wait WriteFileEx returned %x\n", ret);
1296         }
1297         if (winetest_debug > 1) trace("Server done writing.\n");
1298         ok(completion_called == 1, "completion routine called %i times\n", completion_called);
1299         ok(completion_errorcode == ERROR_SUCCESS, "completion routine got error %d\n", completion_errorcode);
1300         ok(completion_num_bytes == readden, "read %i bytes wrote %i\n", readden, completion_num_bytes);
1301         ok(completion_lpoverlapped == &oOverlap, "got wrong overlapped pointer %p\n", completion_lpoverlapped);
1302 
1303         /* finish this connection, wait for next one */
1304         ok(FlushFileBuffers(hnp), "FlushFileBuffers\n");
1305         ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n");
1306     }
1307     return 0;
1308 }
1309 
1310 static void exercizeServer(const char *pipename, HANDLE serverThread)
1311 {
1312     int i;
1313 
1314     if (winetest_debug > 1) trace("exercizeServer starting\n");
1315     for (i = 0; i < NB_SERVER_LOOPS; i++) {
1316         HANDLE hFile=INVALID_HANDLE_VALUE;
1317         static const char obuf[] = "Bit Bucket";
1318         char ibuf[32];
1319         DWORD written;
1320         DWORD readden;
1321         int loop;
1322 
1323         for (loop = 0; loop < 3; loop++) {
1324 	    DWORD err;
1325             if (winetest_debug > 1) trace("Client connecting...\n");
1326             /* Connect to the server */
1327             hFile = CreateFileA(pipename, GENERIC_READ | GENERIC_WRITE, 0,
1328                 NULL, OPEN_EXISTING, 0, 0);
1329             if (hFile != INVALID_HANDLE_VALUE)
1330                 break;
1331 	    err = GetLastError();
1332 	    if (loop == 0)
1333 	        ok(err == ERROR_PIPE_BUSY || err == ERROR_FILE_NOT_FOUND, "connecting to pipe\n");
1334 	    else
1335 	        ok(err == ERROR_PIPE_BUSY, "connecting to pipe\n");
1336             if (winetest_debug > 1) trace("connect failed, retrying\n");
1337             Sleep(200);
1338         }
1339         ok(hFile != INVALID_HANDLE_VALUE, "client opening named pipe\n");
1340 
1341         /* Make sure it can echo */
1342         memset(ibuf, 0, sizeof(ibuf));
1343         if (winetest_debug > 1) trace("Client writing...\n");
1344         ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile to client end of pipe\n");
1345         ok(written == sizeof(obuf), "write file len\n");
1346         if (winetest_debug > 1) trace("Client reading...\n");
1347         ok(ReadFile(hFile, ibuf, sizeof(obuf), &readden, NULL), "ReadFile from client end of pipe\n");
1348         ok(readden == sizeof(obuf), "read file len\n");
1349         ok(memcmp(obuf, ibuf, written) == 0, "content check\n");
1350 
1351         if (winetest_debug > 1) trace("Client closing...\n");
1352         ok(CloseHandle(hFile), "CloseHandle\n");
1353     }
1354 
1355     ok(WaitForSingleObject(serverThread,INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject\n");
1356     CloseHandle(hnp);
1357     if (winetest_debug > 1) trace("exercizeServer returning\n");
1358 }
1359 
1360 static void test_NamedPipe_2(void)
1361 {
1362     HANDLE serverThread;
1363     DWORD serverThreadId;
1364     HANDLE alarmThread;
1365     DWORD alarmThreadId;
1366 
1367     trace("test_NamedPipe_2 starting\n");
1368     /* Set up a twenty second timeout */
1369     alarm_event = CreateEventW( NULL, TRUE, FALSE, NULL );
1370     SetLastError(0xdeadbeef);
1371     alarmThread = CreateThread(NULL, 0, alarmThreadMain, (void *) 20000, 0, &alarmThreadId);
1372     ok(alarmThread != NULL, "CreateThread failed: %d\n", GetLastError());
1373 
1374     /* The servers we're about to exercise do try to clean up carefully,
1375      * but to reduce the chance of a test failure due to a pipe handle
1376      * leak in the test code, we'll use a different pipe name for each server.
1377      */
1378 
1379     /* Try server #1 */
1380     SetLastError(0xdeadbeef);
1381     serverThread = CreateThread(NULL, 0, serverThreadMain1, (void *)8, 0, &serverThreadId);
1382     ok(serverThread != NULL, "CreateThread failed: %d\n", GetLastError());
1383     exercizeServer(PIPENAME "serverThreadMain1", serverThread);
1384 
1385     /* Try server #2 */
1386     SetLastError(0xdeadbeef);
1387     serverThread = CreateThread(NULL, 0, serverThreadMain2, 0, 0, &serverThreadId);
1388     ok(serverThread != NULL, "CreateThread failed: %d\n", GetLastError());
1389     exercizeServer(PIPENAME "serverThreadMain2", serverThread);
1390 
1391     /* Try server #3 */
1392     SetLastError(0xdeadbeef);
1393     serverThread = CreateThread(NULL, 0, serverThreadMain3, 0, 0, &serverThreadId);
1394     ok(serverThread != NULL, "CreateThread failed: %d\n", GetLastError());
1395     exercizeServer(PIPENAME "serverThreadMain3", serverThread);
1396 
1397     /* Try server #4 */
1398     SetLastError(0xdeadbeef);
1399     serverThread = CreateThread(NULL, 0, serverThreadMain4, 0, 0, &serverThreadId);
1400     ok(serverThread != NULL, "CreateThread failed: %d\n", GetLastError());
1401     exercizeServer(PIPENAME "serverThreadMain4", serverThread);
1402 
1403     /* Try server #5 */
1404     SetLastError(0xdeadbeef);
1405     serverThread = CreateThread(NULL, 0, serverThreadMain5, 0, 0, &serverThreadId);
1406     ok(serverThread != NULL, "CreateThread failed: %d\n", GetLastError());
1407     exercizeServer(PIPENAME "serverThreadMain5", serverThread);
1408 
1409     ok(SetEvent( alarm_event ), "SetEvent\n");
1410     CloseHandle( alarm_event );
1411     if (winetest_debug > 1) trace("test_NamedPipe_2 returning\n");
1412 }
1413 
1414 static int test_DisconnectNamedPipe(void)
1415 {
1416     HANDLE hnp;
1417     HANDLE hFile;
1418     static const char obuf[] = "Bit Bucket";
1419     char ibuf[32];
1420     DWORD written;
1421     DWORD readden;
1422     DWORD ret;
1423 
1424     SetLastError(0xdeadbeef);
1425     hnp = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
1426         /* nMaxInstances */ 1,
1427         /* nOutBufSize */ 1024,
1428         /* nInBufSize */ 1024,
1429         /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
1430         /* lpSecurityAttrib */ NULL);
1431     if ((hnp == INVALID_HANDLE_VALUE /* Win98 */ || !hnp /* Win95 */)
1432         && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) {
1433 
1434         win_skip("Named pipes are not implemented\n");
1435         return 1;
1436     }
1437 
1438     ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL) == 0
1439         && GetLastError() == ERROR_PIPE_LISTENING, "WriteFile to not-yet-connected pipe\n");
1440     ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL) == 0
1441         && GetLastError() == ERROR_PIPE_LISTENING, "ReadFile from not-yet-connected pipe\n");
1442 
1443     hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
1444     ok(hFile != INVALID_HANDLE_VALUE, "CreateFile failed\n");
1445 
1446     /* don't try to do i/o if one side couldn't be opened, as it hangs */
1447     if (hFile != INVALID_HANDLE_VALUE) {
1448 
1449         /* see what happens if server calls DisconnectNamedPipe
1450          * when there are bytes in the pipe
1451          */
1452 
1453         ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile\n");
1454         ok(written == sizeof(obuf), "write file len\n");
1455         ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe while messages waiting\n");
1456         ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL) == 0
1457             && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "WriteFile to disconnected pipe\n");
1458         ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL) == 0
1459             && GetLastError() == ERROR_PIPE_NOT_CONNECTED,
1460             "ReadFile from disconnected pipe with bytes waiting\n");
1461 
1462         ok(!DisconnectNamedPipe(hnp) && GetLastError() == ERROR_PIPE_NOT_CONNECTED,
1463            "DisconnectNamedPipe worked twice\n");
1464         ret = WaitForSingleObject(hFile, 0);
1465         ok(ret == WAIT_TIMEOUT, "WaitForSingleObject returned %X\n", ret);
1466 
1467         ret = PeekNamedPipe(hFile, NULL, 0, NULL, &readden, NULL);
1468         todo_wine
1469         ok(!ret && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "PeekNamedPipe returned %x (%u)\n",
1470            ret, GetLastError());
1471         ret = PeekNamedPipe(hnp, NULL, 0, NULL, &readden, NULL);
1472         todo_wine
1473         ok(!ret && GetLastError() == ERROR_BAD_PIPE, "PeekNamedPipe returned %x (%u)\n",
1474            ret, GetLastError());
1475         ok(CloseHandle(hFile), "CloseHandle\n");
1476     }
1477 
1478     ok(CloseHandle(hnp), "CloseHandle\n");
1479 
1480     return 0;
1481 }
1482 static void test_CreatePipe(void)
1483 {
1484     SECURITY_ATTRIBUTES pipe_attr;
1485     HANDLE piperead, pipewrite;
1486     DWORD written;
1487     DWORD read;
1488     DWORD i, size;
1489     BYTE *buffer;
1490     char readbuf[32];
1491 
1492     user_apc_ran = FALSE;
1493     if (pQueueUserAPC)
1494         ok(pQueueUserAPC(user_apc, GetCurrentThread(), 0), "couldn't create user apc\n");
1495 
1496     pipe_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
1497     pipe_attr.bInheritHandle = TRUE;
1498     pipe_attr.lpSecurityDescriptor = NULL;
1499     ok(CreatePipe(&piperead, &pipewrite, &pipe_attr, 0) != 0, "CreatePipe failed\n");
1500     test_pipe_info(piperead, FILE_PIPE_SERVER_END, 4096, 4096, 1);
1501     test_pipe_info(pipewrite, 0, 4096, 4096, 1);
1502 
1503     ok(WriteFile(pipewrite,PIPENAME,sizeof(PIPENAME), &written, NULL), "Write to anonymous pipe failed\n");
1504     ok(written == sizeof(PIPENAME), "Write to anonymous pipe wrote %d bytes\n", written);
1505     ok(ReadFile(piperead,readbuf,sizeof(readbuf),&read, NULL), "Read from non empty pipe failed\n");
1506     ok(read == sizeof(PIPENAME), "Read from  anonymous pipe got %d bytes\n", read);
1507     ok(CloseHandle(pipewrite), "CloseHandle for the write pipe failed\n");
1508     ok(CloseHandle(piperead), "CloseHandle for the read pipe failed\n");
1509 
1510     /* Now write another chunk*/
1511     ok(CreatePipe(&piperead, &pipewrite, &pipe_attr, 0) != 0, "CreatePipe failed\n");
1512     ok(WriteFile(pipewrite,PIPENAME,sizeof(PIPENAME), &written, NULL), "Write to anonymous pipe failed\n");
1513     ok(written == sizeof(PIPENAME), "Write to anonymous pipe wrote %d bytes\n", written);
1514     /* and close the write end, read should still succeed*/
1515     ok(CloseHandle(pipewrite), "CloseHandle for the Write Pipe failed\n");
1516     ok(ReadFile(piperead,readbuf,sizeof(readbuf),&read, NULL), "Read from broken pipe with pending data failed\n");
1517     ok(read == sizeof(PIPENAME), "Read from anonymous pipe got %d bytes\n", read);
1518     /* But now we need to get informed that the pipe is closed */
1519     ok(ReadFile(piperead,readbuf,sizeof(readbuf),&read, NULL) == 0, "Broken pipe not detected\n");
1520     ok(CloseHandle(piperead), "CloseHandle for the read pipe failed\n");
1521 
1522     /* Try bigger chunks */
1523     size = 32768;
1524     buffer = HeapAlloc( GetProcessHeap(), 0, size );
1525     for (i = 0; i < size; i++) buffer[i] = i;
1526     ok(CreatePipe(&piperead, &pipewrite, &pipe_attr, (size + 24)) != 0, "CreatePipe failed\n");
1527     ok(WriteFile(pipewrite, buffer, size, &written, NULL), "Write to anonymous pipe failed\n");
1528     ok(written == size, "Write to anonymous pipe wrote %d bytes\n", written);
1529     /* and close the write end, read should still succeed*/
1530     ok(CloseHandle(pipewrite), "CloseHandle for the Write Pipe failed\n");
1531     memset( buffer, 0, size );
1532     ok(ReadFile(piperead, buffer, size, &read, NULL), "Read from broken pipe with pending data failed\n");
1533     ok(read == size, "Read from anonymous pipe got %d bytes\n", read);
1534     for (i = 0; i < size; i++) ok( buffer[i] == (BYTE)i, "invalid data %x at %x\n", buffer[i], i );
1535     /* But now we need to get informed that the pipe is closed */
1536     ok(ReadFile(piperead,readbuf,sizeof(readbuf),&read, NULL) == 0, "Broken pipe not detected\n");
1537     ok(CloseHandle(piperead), "CloseHandle for the read pipe failed\n");
1538     HeapFree(GetProcessHeap(), 0, buffer);
1539 
1540     ok(user_apc_ran == FALSE, "user apc ran, pipe using alertable io mode\n");
1541     SleepEx(0, TRUE); /* get rid of apc */
1542 
1543     ok(CreatePipe(&piperead, &pipewrite, &pipe_attr, 1) != 0, "CreatePipe failed\n");
1544     test_pipe_info(piperead, FILE_PIPE_SERVER_END, 1, 1, 1);
1545     test_pipe_info(pipewrite, 0, 1, 1, 1);
1546     ok(CloseHandle(pipewrite), "CloseHandle for the Write Pipe failed\n");
1547     ok(CloseHandle(piperead), "CloseHandle for the read pipe failed\n");
1548 }
1549 
1550 static void test_CloseHandle(void)
1551 {
1552     static const char testdata[] = "Hello World";
1553     DWORD state, numbytes;
1554     HANDLE hpipe, hfile;
1555     char buffer[32];
1556     BOOL ret;
1557 
1558     hpipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX,
1559                              PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
1560                              1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL);
1561     ok(hpipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %u\n", GetLastError());
1562 
1563     hfile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
1564     ok(hfile != INVALID_HANDLE_VALUE, "CreateFile failed with %u\n", GetLastError());
1565 
1566     numbytes = 0xdeadbeef;
1567     ret = WriteFile(hpipe, testdata, sizeof(testdata), &numbytes, NULL);
1568     ok(ret, "WriteFile failed with %u\n", GetLastError());
1569     ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes);
1570 
1571     numbytes = 0xdeadbeef;
1572     ret = PeekNamedPipe(hfile, NULL, 0, NULL, &numbytes, NULL);
1573     ok(ret, "PeekNamedPipe failed with %u\n", GetLastError());
1574     ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes);
1575 
1576     ret = CloseHandle(hpipe);
1577     ok(ret, "CloseHandle failed with %u\n", GetLastError());
1578 
1579     numbytes = 0xdeadbeef;
1580     memset(buffer, 0, sizeof(buffer));
1581     ret = ReadFile(hfile, buffer, 0, &numbytes, NULL);
1582     ok(ret, "ReadFile failed with %u\n", GetLastError());
1583     ok(numbytes == 0, "expected 0, got %u\n", numbytes);
1584 
1585     numbytes = 0xdeadbeef;
1586     ret = PeekNamedPipe(hfile, NULL, 0, NULL, &numbytes, NULL);
1587     ok(ret, "PeekNamedPipe failed with %u\n", GetLastError());
1588     ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes);
1589 
1590     numbytes = 0xdeadbeef;
1591     memset(buffer, 0, sizeof(buffer));
1592     ret = ReadFile(hfile, buffer, sizeof(buffer), &numbytes, NULL);
1593     ok(ret, "ReadFile failed with %u\n", GetLastError());
1594     ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes);
1595 
1596     ret = GetNamedPipeHandleStateA(hfile, &state, NULL, NULL, NULL, NULL, 0);
1597     ok(ret, "GetNamedPipeHandleState failed with %u\n", GetLastError());
1598     state = PIPE_READMODE_MESSAGE | PIPE_WAIT;
1599     ret = SetNamedPipeHandleState(hfile, &state, NULL, NULL);
1600     ok(ret, "SetNamedPipeHandleState failed with %u\n", GetLastError());
1601 
1602     SetLastError(0xdeadbeef);
1603     ret = ReadFile(hfile, buffer, 0, &numbytes, NULL);
1604     ok(!ret, "ReadFile unexpectedly succeeded\n");
1605     ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1606 
1607     numbytes = 0xdeadbeef;
1608     ret = PeekNamedPipe(hfile, NULL, 0, NULL, &numbytes, NULL);
1609     ok(!ret && GetLastError() == ERROR_BROKEN_PIPE, "PeekNamedPipe returned %x (%u)\n",
1610        ret, GetLastError());
1611     ok(numbytes == 0xdeadbeef, "numbytes = %u\n", numbytes);
1612 
1613     SetLastError(0xdeadbeef);
1614     ret = WriteFile(hfile, testdata, sizeof(testdata), &numbytes, NULL);
1615     ok(!ret, "WriteFile unexpectedly succeeded\n");
1616     todo_wine ok(GetLastError() == ERROR_NO_DATA, "expected ERROR_NO_DATA, got %u\n", GetLastError());
1617 
1618     CloseHandle(hfile);
1619 
1620     hpipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX,
1621                              PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
1622                              1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL);
1623     ok(hpipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %u\n", GetLastError());
1624 
1625     hfile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
1626     ok(hfile != INVALID_HANDLE_VALUE, "CreateFile failed with %u\n", GetLastError());
1627 
1628     numbytes = 0xdeadbeef;
1629     ret = WriteFile(hpipe, testdata, 0, &numbytes, NULL);
1630     ok(ret, "WriteFile failed with %u\n", GetLastError());
1631     ok(numbytes == 0, "expected 0, got %u\n", numbytes);
1632 
1633     ret = CloseHandle(hpipe);
1634     ok(ret, "CloseHandle failed with %u\n", GetLastError());
1635 
1636     numbytes = 0xdeadbeef;
1637     memset(buffer, 0, sizeof(buffer));
1638     ret = ReadFile(hfile, buffer, sizeof(buffer), &numbytes, NULL);
1639     ok(ret, "ReadFile failed with %u\n", GetLastError());
1640     ok(numbytes == 0, "expected 0, got %u\n", numbytes);
1641 
1642     SetLastError(0xdeadbeef);
1643     ret = ReadFile(hfile, buffer, 0, &numbytes, NULL);
1644     ok(!ret, "ReadFile unexpectedly succeeded\n");
1645     ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1646 
1647     ret = GetNamedPipeHandleStateA(hfile, &state, NULL, NULL, NULL, NULL, 0);
1648     ok(ret, "GetNamedPipeHandleState failed with %u\n", GetLastError());
1649     state = PIPE_READMODE_MESSAGE | PIPE_WAIT;
1650     ret = SetNamedPipeHandleState(hfile, &state, NULL, NULL);
1651     ok(ret, "SetNamedPipeHandleState failed with %u\n", GetLastError());
1652 
1653     SetLastError(0xdeadbeef);
1654     ret = ReadFile(hfile, buffer, 0, &numbytes, NULL);
1655     ok(!ret, "ReadFile unexpectedly succeeded\n");
1656     ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1657 
1658     SetLastError(0xdeadbeef);
1659     ret = WriteFile(hfile, testdata, sizeof(testdata), &numbytes, NULL);
1660     ok(!ret, "WriteFile unexpectedly succeeded\n");
1661     todo_wine ok(GetLastError() == ERROR_NO_DATA, "expected ERROR_NO_DATA, got %u\n", GetLastError());
1662 
1663     CloseHandle(hfile);
1664 
1665     /* repeat test with hpipe <-> hfile swapped */
1666 
1667     hpipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX,
1668                              PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
1669                              1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL);
1670     ok(hpipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %u\n", GetLastError());
1671 
1672     hfile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
1673     ok(hfile != INVALID_HANDLE_VALUE, "CreateFile failed with %u\n", GetLastError());
1674 
1675     numbytes = 0xdeadbeef;
1676     ret = WriteFile(hfile, testdata, sizeof(testdata), &numbytes, NULL);
1677     ok(ret, "WriteFile failed with %u\n", GetLastError());
1678     ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes);
1679 
1680     numbytes = 0xdeadbeef;
1681     ret = PeekNamedPipe(hpipe, NULL, 0, NULL, &numbytes, NULL);
1682     ok(ret, "PeekNamedPipe failed with %u\n", GetLastError());
1683     ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes);
1684 
1685     ret = CloseHandle(hfile);
1686     ok(ret, "CloseHandle failed with %u\n", GetLastError());
1687 
1688     numbytes = 0xdeadbeef;
1689     memset(buffer, 0, sizeof(buffer));
1690     ret = ReadFile(hpipe, buffer, 0, &numbytes, NULL);
1691     ok(ret || GetLastError() == ERROR_MORE_DATA /* >= Win 8 */,
1692                  "ReadFile failed with %u\n", GetLastError());
1693     ok(numbytes == 0, "expected 0, got %u\n", numbytes);
1694 
1695     numbytes = 0xdeadbeef;
1696     ret = PeekNamedPipe(hpipe, NULL, 0, NULL, &numbytes, NULL);
1697     ok(ret, "PeekNamedPipe failed with %u\n", GetLastError());
1698     ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes);
1699 
1700     numbytes = 0xdeadbeef;
1701     memset(buffer, 0, sizeof(buffer));
1702     ret = ReadFile(hpipe, buffer, sizeof(buffer), &numbytes, NULL);
1703     ok(ret, "ReadFile failed with %u\n", GetLastError());
1704     ok(numbytes == sizeof(testdata), "expected sizeof(testdata), got %u\n", numbytes);
1705 
1706     ret = GetNamedPipeHandleStateA(hpipe, &state, NULL, NULL, NULL, NULL, 0);
1707     ok(ret, "GetNamedPipeHandleState failed with %u\n", GetLastError());
1708     state = PIPE_READMODE_MESSAGE | PIPE_WAIT;
1709     ret = SetNamedPipeHandleState(hpipe, &state, NULL, NULL);
1710     ok(ret, "SetNamedPipeHandleState failed with %u\n", GetLastError());
1711 
1712     SetLastError(0xdeadbeef);
1713     ret = ReadFile(hpipe, buffer, 0, &numbytes, NULL);
1714     ok(!ret, "ReadFile unexpectedly succeeded\n");
1715     ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1716 
1717     numbytes = 0xdeadbeef;
1718     ret = PeekNamedPipe(hpipe, NULL, 0, NULL, &numbytes, NULL);
1719     ok(!ret && GetLastError() == ERROR_BROKEN_PIPE, "PeekNamedPipe returned %x (%u)\n",
1720        ret, GetLastError());
1721     ok(numbytes == 0xdeadbeef, "numbytes = %u\n", numbytes);
1722 
1723     SetLastError(0xdeadbeef);
1724     ret = WriteFile(hpipe, testdata, sizeof(testdata), &numbytes, NULL);
1725     ok(!ret, "WriteFile unexpectedly succeeded\n");
1726     todo_wine ok(GetLastError() == ERROR_NO_DATA, "expected ERROR_NO_DATA, got %u\n", GetLastError());
1727 
1728     CloseHandle(hpipe);
1729 
1730     hpipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX,
1731                              PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
1732                              1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL);
1733     ok(hpipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %u\n", GetLastError());
1734 
1735     hfile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
1736     ok(hfile != INVALID_HANDLE_VALUE, "CreateFile failed with %u\n", GetLastError());
1737 
1738     numbytes = 0xdeadbeef;
1739     ret = WriteFile(hfile, testdata, 0, &numbytes, NULL);
1740     ok(ret, "WriteFile failed with %u\n", GetLastError());
1741     ok(numbytes == 0, "expected 0, got %u\n", numbytes);
1742 
1743     ret = CloseHandle(hfile);
1744     ok(ret, "CloseHandle failed with %u\n", GetLastError());
1745 
1746     numbytes = 0xdeadbeef;
1747     memset(buffer, 0, sizeof(buffer));
1748     ret = ReadFile(hpipe, buffer, sizeof(buffer), &numbytes, NULL);
1749     ok(ret, "ReadFile failed with %u\n", GetLastError());
1750     ok(numbytes == 0, "expected 0, got %u\n", numbytes);
1751 
1752     SetLastError(0xdeadbeef);
1753     ret = ReadFile(hpipe, buffer, 0, &numbytes, NULL);
1754     ok(!ret, "ReadFile unexpectedly succeeded\n");
1755     ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1756 
1757     ret = GetNamedPipeHandleStateA(hpipe, &state, NULL, NULL, NULL, NULL, 0);
1758     ok(ret, "GetNamedPipeHandleState failed with %u\n", GetLastError());
1759     state = PIPE_READMODE_MESSAGE | PIPE_WAIT;
1760     ret = SetNamedPipeHandleState(hpipe, &state, NULL, NULL);
1761     ok(ret, "SetNamedPipeHandleState failed with %u\n", GetLastError());
1762 
1763     SetLastError(0xdeadbeef);
1764     ret = ReadFile(hpipe, buffer, 0, &numbytes, NULL);
1765     ok(!ret, "ReadFile unexpectedly succeeded\n");
1766     ok(GetLastError() == ERROR_BROKEN_PIPE, "expected ERROR_BROKEN_PIPE, got %u\n", GetLastError());
1767 
1768     SetLastError(0xdeadbeef);
1769     ret = WriteFile(hpipe, testdata, sizeof(testdata), &numbytes, NULL);
1770     ok(!ret, "WriteFile unexpectedly succeeded\n");
1771     todo_wine ok(GetLastError() == ERROR_NO_DATA, "expected ERROR_NO_DATA, got %u\n", GetLastError());
1772 
1773     CloseHandle(hpipe);
1774 }
1775 
1776 struct named_pipe_client_params
1777 {
1778     DWORD security_flags;
1779     HANDLE token;
1780     BOOL revert;
1781 };
1782 
1783 #define PIPE_NAME "\\\\.\\pipe\\named_pipe_test"
1784 
1785 static DWORD CALLBACK named_pipe_client_func(LPVOID p)
1786 {
1787     struct named_pipe_client_params *params = p;
1788     HANDLE pipe;
1789     BOOL ret;
1790     const char message[] = "Test";
1791     DWORD bytes_read, bytes_written;
1792     char dummy;
1793     TOKEN_PRIVILEGES *Privileges = NULL;
1794 
1795     if (params->token)
1796     {
1797         if (params->revert)
1798         {
1799             /* modify the token so we can tell if the pipe impersonation
1800              * token reverts to the process token */
1801             ret = AdjustTokenPrivileges(params->token, TRUE, NULL, 0, NULL, NULL);
1802             ok(ret, "AdjustTokenPrivileges failed with error %d\n", GetLastError());
1803         }
1804         ret = SetThreadToken(NULL, params->token);
1805         ok(ret, "SetThreadToken failed with error %d\n", GetLastError());
1806     }
1807     else
1808     {
1809         DWORD Size = 0;
1810         HANDLE process_token;
1811 
1812         ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES, &process_token);
1813         ok(ret, "OpenProcessToken failed with error %d\n", GetLastError());
1814 
1815         ret = GetTokenInformation(process_token, TokenPrivileges, NULL, 0, &Size);
1816         ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetTokenInformation(TokenPrivileges) failed with %d\n", GetLastError());
1817         Privileges = HeapAlloc(GetProcessHeap(), 0, Size);
1818         ret = GetTokenInformation(process_token, TokenPrivileges, Privileges, Size, &Size);
1819         ok(ret, "GetTokenInformation(TokenPrivileges) failed with %d\n", GetLastError());
1820 
1821         ret = AdjustTokenPrivileges(process_token, TRUE, NULL, 0, NULL, NULL);
1822         ok(ret, "AdjustTokenPrivileges failed with error %d\n", GetLastError());
1823 
1824         CloseHandle(process_token);
1825     }
1826 
1827     pipe = CreateFileA(PIPE_NAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, params->security_flags, NULL);
1828     ok(pipe != INVALID_HANDLE_VALUE, "CreateFile for pipe failed with error %d\n", GetLastError());
1829 
1830     ret = WriteFile(pipe, message, sizeof(message), &bytes_written, NULL);
1831     ok(ret, "WriteFile failed with error %d\n", GetLastError());
1832 
1833     ret = ReadFile(pipe, &dummy, sizeof(dummy), &bytes_read, NULL);
1834     ok(ret, "ReadFile failed with error %d\n", GetLastError());
1835 
1836     if (params->token)
1837     {
1838         if (params->revert)
1839         {
1840             ret = RevertToSelf();
1841             ok(ret, "RevertToSelf failed with error %d\n", GetLastError());
1842         }
1843         else
1844         {
1845             ret = AdjustTokenPrivileges(params->token, TRUE, NULL, 0, NULL, NULL);
1846             ok(ret, "AdjustTokenPrivileges failed with error %d\n", GetLastError());
1847         }
1848     }
1849     else
1850     {
1851         HANDLE process_token;
1852 
1853         ret = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &process_token);
1854         ok(ret, "OpenProcessToken failed with error %d\n", GetLastError());
1855 
1856         ret = AdjustTokenPrivileges(process_token, FALSE, Privileges, 0, NULL, NULL);
1857         ok(ret, "AdjustTokenPrivileges failed with error %d\n", GetLastError());
1858 
1859         HeapFree(GetProcessHeap(), 0, Privileges);
1860 
1861         CloseHandle(process_token);
1862     }
1863 
1864     ret = WriteFile(pipe, message, sizeof(message), &bytes_written, NULL);
1865     ok(ret, "WriteFile failed with error %d\n", GetLastError());
1866 
1867     ret = ReadFile(pipe, &dummy, sizeof(dummy), &bytes_read, NULL);
1868     ok(ret, "ReadFile failed with error %d\n", GetLastError());
1869 
1870     CloseHandle(pipe);
1871 
1872     return 0;
1873 }
1874 
1875 static HANDLE make_impersonation_token(DWORD Access, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
1876 {
1877     HANDLE ProcessToken;
1878     HANDLE Token = NULL;
1879     BOOL ret;
1880 
1881     ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &ProcessToken);
1882     ok(ret, "OpenProcessToken failed with error %d\n", GetLastError());
1883 
1884     ret = pDuplicateTokenEx(ProcessToken, Access, NULL, ImpersonationLevel, TokenImpersonation, &Token);
1885     ok(ret, "DuplicateToken failed with error %d\n", GetLastError());
1886 
1887     CloseHandle(ProcessToken);
1888 
1889     return Token;
1890 }
1891 
1892 static void test_ImpersonateNamedPipeClient(HANDLE hClientToken, DWORD security_flags, BOOL revert, void (*test_func)(int, HANDLE))
1893 {
1894     HANDLE hPipeServer;
1895     BOOL ret;
1896     DWORD dwTid;
1897     HANDLE hThread;
1898     char buffer[256];
1899     DWORD dwBytesRead;
1900     DWORD error;
1901     struct named_pipe_client_params params;
1902     char dummy = 0;
1903     DWORD dwBytesWritten;
1904     HANDLE hToken = NULL;
1905     SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
1906     DWORD size;
1907 
1908     hPipeServer = CreateNamedPipeA(PIPE_NAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 100, 100, NMPWAIT_USE_DEFAULT_WAIT, NULL);
1909     ok(hPipeServer != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with error %d\n", GetLastError());
1910 
1911     params.security_flags = security_flags;
1912     params.token = hClientToken;
1913     params.revert = revert;
1914     hThread = CreateThread(NULL, 0, named_pipe_client_func, &params, 0, &dwTid);
1915     ok(hThread != NULL, "CreateThread failed with error %d\n", GetLastError());
1916 
1917     SetLastError(0xdeadbeef);
1918     ret = ImpersonateNamedPipeClient(hPipeServer);
1919     error = GetLastError();
1920     ok(ret /* win2k3 */ || (error == ERROR_CANNOT_IMPERSONATE),
1921        "ImpersonateNamedPipeClient should have failed with ERROR_CANNOT_IMPERSONATE instead of %d\n", GetLastError());
1922 
1923     ret = ConnectNamedPipe(hPipeServer, NULL);
1924     ok(ret || (GetLastError() == ERROR_PIPE_CONNECTED), "ConnectNamedPipe failed with error %d\n", GetLastError());
1925 
1926     ret = ReadFile(hPipeServer, buffer, sizeof(buffer), &dwBytesRead, NULL);
1927     ok(ret, "ReadFile failed with error %d\n", GetLastError());
1928 
1929     ret = ImpersonateNamedPipeClient(hPipeServer);
1930     ok(ret, "ImpersonateNamedPipeClient failed with error %d\n", GetLastError());
1931 
1932     ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken);
1933     ok(ret, "OpenThreadToken failed with error %d\n", GetLastError());
1934 
1935     (*test_func)(0, hToken);
1936 
1937     ImpersonationLevel = 0xdeadbeef; /* to avoid false positives */
1938     ret = GetTokenInformation(hToken, TokenImpersonationLevel, &ImpersonationLevel, sizeof(ImpersonationLevel), &size);
1939     ok(ret, "GetTokenInformation(TokenImpersonationLevel) failed with error %d\n", GetLastError());
1940     ok(ImpersonationLevel == SecurityImpersonation, "ImpersonationLevel should have been SecurityImpersonation(%d) instead of %d\n", SecurityImpersonation, ImpersonationLevel);
1941 
1942     CloseHandle(hToken);
1943 
1944     RevertToSelf();
1945 
1946     ret = WriteFile(hPipeServer, &dummy, sizeof(dummy), &dwBytesWritten, NULL);
1947     ok(ret, "WriteFile failed with error %d\n", GetLastError());
1948 
1949     ret = ReadFile(hPipeServer, buffer, sizeof(buffer), &dwBytesRead, NULL);
1950     ok(ret, "ReadFile failed with error %d\n", GetLastError());
1951 
1952     ret = ImpersonateNamedPipeClient(hPipeServer);
1953     ok(ret, "ImpersonateNamedPipeClient failed with error %d\n", GetLastError());
1954 
1955     ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken);
1956     ok(ret, "OpenThreadToken failed with error %d\n", GetLastError());
1957 
1958     (*test_func)(1, hToken);
1959 
1960     CloseHandle(hToken);
1961 
1962     RevertToSelf();
1963 
1964     ret = WriteFile(hPipeServer, &dummy, sizeof(dummy), &dwBytesWritten, NULL);
1965     ok(ret, "WriteFile failed with error %d\n", GetLastError());
1966 
1967     WaitForSingleObject(hThread, INFINITE);
1968 
1969     ret = ImpersonateNamedPipeClient(hPipeServer);
1970     ok(ret, "ImpersonateNamedPipeClient failed with error %d\n", GetLastError());
1971 
1972     RevertToSelf();
1973 
1974     CloseHandle(hThread);
1975     CloseHandle(hPipeServer);
1976 }
1977 
1978 static BOOL are_all_privileges_disabled(HANDLE hToken)
1979 {
1980     BOOL ret;
1981     TOKEN_PRIVILEGES *Privileges = NULL;
1982     DWORD Size = 0;
1983     BOOL all_privs_disabled = TRUE;
1984     DWORD i;
1985 
1986     ret = GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &Size);
1987     if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1988     {
1989         Privileges = HeapAlloc(GetProcessHeap(), 0, Size);
1990         ret = GetTokenInformation(hToken, TokenPrivileges, Privileges, Size, &Size);
1991         if (!ret)
1992         {
1993             HeapFree(GetProcessHeap(), 0, Privileges);
1994             return FALSE;
1995         }
1996     }
1997     else
1998         return FALSE;
1999 
2000     for (i = 0; i < Privileges->PrivilegeCount; i++)
2001     {
2002         if (Privileges->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED)
2003         {
2004             all_privs_disabled = FALSE;
2005             break;
2006         }
2007     }
2008 
2009     HeapFree(GetProcessHeap(), 0, Privileges);
2010 
2011     return all_privs_disabled;
2012 }
2013 
2014 static DWORD get_privilege_count(HANDLE hToken)
2015 {
2016     TOKEN_STATISTICS Statistics;
2017     DWORD Size = sizeof(Statistics);
2018     BOOL ret;
2019 
2020     ret = GetTokenInformation(hToken, TokenStatistics, &Statistics, Size, &Size);
2021     ok(ret, "GetTokenInformation(TokenStatistics)\n");
2022     if (!ret) return -1;
2023 
2024     return Statistics.PrivilegeCount;
2025 }
2026 
2027 static void test_no_sqos_no_token(int call_index, HANDLE hToken)
2028 {
2029     DWORD priv_count;
2030 
2031     switch (call_index)
2032     {
2033     case 0:
2034         priv_count = get_privilege_count(hToken);
2035         todo_wine
2036         ok(priv_count == 0, "privilege count should have been 0 instead of %d\n", priv_count);
2037         break;
2038     case 1:
2039         priv_count = get_privilege_count(hToken);
2040         ok(priv_count > 0, "privilege count should now be > 0 instead of 0\n");
2041         ok(!are_all_privileges_disabled(hToken), "impersonated token should not have been modified\n");
2042         break;
2043     default:
2044         ok(0, "shouldn't happen\n");
2045     }
2046 }
2047 
2048 static void test_no_sqos(int call_index, HANDLE hToken)
2049 {
2050     switch (call_index)
2051     {
2052     case 0:
2053         ok(!are_all_privileges_disabled(hToken), "token should be a copy of the process one\n");
2054         break;
2055     case 1:
2056         todo_wine
2057         ok(are_all_privileges_disabled(hToken), "impersonated token should have been modified\n");
2058         break;
2059     default:
2060         ok(0, "shouldn't happen\n");
2061     }
2062 }
2063 
2064 static void test_static_context(int call_index, HANDLE hToken)
2065 {
2066     switch (call_index)
2067     {
2068     case 0:
2069         ok(!are_all_privileges_disabled(hToken), "token should be a copy of the process one\n");
2070         break;
2071     case 1:
2072         ok(!are_all_privileges_disabled(hToken), "impersonated token should not have been modified\n");
2073         break;
2074     default:
2075         ok(0, "shouldn't happen\n");
2076     }
2077 }
2078 
2079 static void test_dynamic_context(int call_index, HANDLE hToken)
2080 {
2081     switch (call_index)
2082     {
2083     case 0:
2084         ok(!are_all_privileges_disabled(hToken), "token should be a copy of the process one\n");
2085         break;
2086     case 1:
2087         todo_wine
2088         ok(are_all_privileges_disabled(hToken), "impersonated token should have been modified\n");
2089         break;
2090     default:
2091         ok(0, "shouldn't happen\n");
2092     }
2093 }
2094 
2095 static void test_dynamic_context_no_token(int call_index, HANDLE hToken)
2096 {
2097     switch (call_index)
2098     {
2099     case 0:
2100         ok(are_all_privileges_disabled(hToken), "token should be a copy of the process one\n");
2101         break;
2102     case 1:
2103         ok(!are_all_privileges_disabled(hToken), "process token modification should have been detected and impersonation token updated\n");
2104         break;
2105     default:
2106         ok(0, "shouldn't happen\n");
2107     }
2108 }
2109 
2110 static void test_no_sqos_revert(int call_index, HANDLE hToken)
2111 {
2112     DWORD priv_count;
2113     switch (call_index)
2114     {
2115     case 0:
2116         priv_count = get_privilege_count(hToken);
2117         todo_wine
2118         ok(priv_count == 0, "privilege count should have been 0 instead of %d\n", priv_count);
2119         break;
2120     case 1:
2121         priv_count = get_privilege_count(hToken);
2122         ok(priv_count > 0, "privilege count should now be > 0 instead of 0\n");
2123         ok(!are_all_privileges_disabled(hToken), "impersonated token should not have been modified\n");
2124         break;
2125     default:
2126         ok(0, "shouldn't happen\n");
2127     }
2128 }
2129 
2130 static void test_static_context_revert(int call_index, HANDLE hToken)
2131 {
2132     switch (call_index)
2133     {
2134     case 0:
2135         todo_wine
2136         ok(are_all_privileges_disabled(hToken), "privileges should have been disabled\n");
2137         break;
2138     case 1:
2139         todo_wine
2140         ok(are_all_privileges_disabled(hToken), "impersonated token should not have been modified\n");
2141         break;
2142     default:
2143         ok(0, "shouldn't happen\n");
2144     }
2145 }
2146 
2147 static void test_dynamic_context_revert(int call_index, HANDLE hToken)
2148 {
2149     switch (call_index)
2150     {
2151     case 0:
2152         todo_wine
2153         ok(are_all_privileges_disabled(hToken), "privileges should have been disabled\n");
2154         break;
2155     case 1:
2156         ok(!are_all_privileges_disabled(hToken), "impersonated token should now be process token\n");
2157         break;
2158     default:
2159         ok(0, "shouldn't happen\n");
2160     }
2161 }
2162 
2163 static void test_impersonation(void)
2164 {
2165     HANDLE hClientToken;
2166     HANDLE hProcessToken;
2167     BOOL ret;
2168 
2169     if( !pDuplicateTokenEx ) {
2170         skip("DuplicateTokenEx not found\n");
2171         return;
2172     }
2173 
2174     ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hProcessToken);
2175     if (!ret)
2176     {
2177         skip("couldn't open process token, skipping impersonation tests\n");
2178         return;
2179     }
2180 
2181     if (!get_privilege_count(hProcessToken) || are_all_privileges_disabled(hProcessToken))
2182     {
2183         skip("token didn't have any privileges or they were all disabled. token not suitable for impersonation tests\n");
2184         CloseHandle(hProcessToken);
2185         return;
2186     }
2187     CloseHandle(hProcessToken);
2188 
2189     test_ImpersonateNamedPipeClient(NULL, 0, FALSE, test_no_sqos_no_token);
2190     hClientToken = make_impersonation_token(TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, SecurityImpersonation);
2191     test_ImpersonateNamedPipeClient(hClientToken, 0, FALSE, test_no_sqos);
2192     CloseHandle(hClientToken);
2193     hClientToken = make_impersonation_token(TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, SecurityImpersonation);
2194     test_ImpersonateNamedPipeClient(hClientToken,
2195         SECURITY_SQOS_PRESENT | SECURITY_IMPERSONATION, FALSE,
2196         test_static_context);
2197     CloseHandle(hClientToken);
2198     hClientToken = make_impersonation_token(TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, SecurityImpersonation);
2199     test_ImpersonateNamedPipeClient(hClientToken,
2200         SECURITY_SQOS_PRESENT | SECURITY_CONTEXT_TRACKING | SECURITY_IMPERSONATION,
2201         FALSE, test_dynamic_context);
2202     CloseHandle(hClientToken);
2203     test_ImpersonateNamedPipeClient(NULL,
2204         SECURITY_SQOS_PRESENT | SECURITY_CONTEXT_TRACKING | SECURITY_IMPERSONATION,
2205         FALSE, test_dynamic_context_no_token);
2206 
2207     hClientToken = make_impersonation_token(TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, SecurityImpersonation);
2208     test_ImpersonateNamedPipeClient(hClientToken, 0, TRUE, test_no_sqos_revert);
2209     CloseHandle(hClientToken);
2210     hClientToken = make_impersonation_token(TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, SecurityImpersonation);
2211     test_ImpersonateNamedPipeClient(hClientToken,
2212         SECURITY_SQOS_PRESENT | SECURITY_IMPERSONATION, TRUE,
2213         test_static_context_revert);
2214     CloseHandle(hClientToken);
2215     hClientToken = make_impersonation_token(TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, SecurityImpersonation);
2216     test_ImpersonateNamedPipeClient(hClientToken,
2217         SECURITY_SQOS_PRESENT | SECURITY_CONTEXT_TRACKING | SECURITY_IMPERSONATION,
2218         TRUE, test_dynamic_context_revert);
2219     CloseHandle(hClientToken);
2220 }
2221 
2222 struct overlapped_server_args
2223 {
2224     HANDLE pipe_created;
2225 };
2226 
2227 static DWORD CALLBACK overlapped_server(LPVOID arg)
2228 {
2229     OVERLAPPED ol;
2230     HANDLE pipe;
2231     int ret, err;
2232     struct overlapped_server_args *a = arg;
2233     DWORD num;
2234     char buf[100];
2235 
2236     pipe = CreateNamedPipeA("\\\\.\\pipe\\my pipe", FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, 1, 0, 0, 100000, NULL);
2237     ok(pipe != NULL, "pipe NULL\n");
2238 
2239     ol.hEvent = CreateEventA(0, 1, 0, 0);
2240     ok(ol.hEvent != NULL, "event NULL\n");
2241     ret = ConnectNamedPipe(pipe, &ol);
2242     err = GetLastError();
2243     ok(ret == 0, "ret %d\n", ret);
2244     ok(err == ERROR_IO_PENDING, "gle %d\n", err);
2245     SetEvent(a->pipe_created);
2246 
2247     ret = WaitForSingleObjectEx(ol.hEvent, INFINITE, 1);
2248     ok(ret == WAIT_OBJECT_0, "ret %x\n", ret);
2249 
2250     ret = GetOverlappedResult(pipe, &ol, &num, 1);
2251     ok(ret == 1, "ret %d\n", ret);
2252 
2253     /* This should block */
2254     ret = ReadFile(pipe, buf, sizeof(buf), &num, NULL);
2255     ok(ret == 1, "ret %d\n", ret);
2256 
2257     DisconnectNamedPipe(pipe);
2258 
2259     ret = ConnectNamedPipe(pipe, &ol);
2260     err = GetLastError();
2261     ok(ret == 0, "ret %d\n", ret);
2262     ok(err == ERROR_IO_PENDING, "gle %d\n", err);
2263     CancelIo(pipe);
2264     ret = WaitForSingleObjectEx(ol.hEvent, INFINITE, 1);
2265     ok(ret == WAIT_OBJECT_0, "ret %x\n", ret);
2266 
2267     ret = GetOverlappedResult(pipe, &ol, &num, 1);
2268     err = GetLastError();
2269     ok(ret == 0, "ret %d\n", ret);
2270     ok(err == ERROR_OPERATION_ABORTED, "gle %d\n", err);
2271 
2272     CloseHandle(ol.hEvent);
2273     CloseHandle(pipe);
2274     return 1;
2275 }
2276 
2277 static void test_overlapped(void)
2278 {
2279     DWORD tid, num;
2280     HANDLE thread, pipe;
2281     BOOL ret;
2282     struct overlapped_server_args args;
2283 
2284     args.pipe_created = CreateEventA(0, 1, 0, 0);
2285     thread = CreateThread(NULL, 0, overlapped_server, &args, 0, &tid);
2286 
2287     WaitForSingleObject(args.pipe_created, INFINITE);
2288     pipe = CreateFileA("\\\\.\\pipe\\my pipe", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
2289     ok(pipe != INVALID_HANDLE_VALUE, "cf failed\n");
2290 
2291     /* Sleep to try to get the ReadFile in the server to occur before the following WriteFile */
2292     Sleep(1);
2293 
2294     ret = WriteFile(pipe, "x", 1, &num, NULL);
2295     ok(ret, "WriteFile failed with error %d\n", GetLastError());
2296 
2297     WaitForSingleObject(thread, INFINITE);
2298     CloseHandle(pipe);
2299     CloseHandle(args.pipe_created);
2300     CloseHandle(thread);
2301 }
2302 
2303 static void test_overlapped_error(void)
2304 {
2305     HANDLE pipe, file, event;
2306     DWORD err, numbytes;
2307     OVERLAPPED overlapped;
2308     BOOL ret;
2309 
2310     event = CreateEventA(NULL, TRUE, FALSE, NULL);
2311     ok(event != NULL, "CreateEventA failed with %u\n", GetLastError());
2312 
2313     pipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
2314                             PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
2315                             1, 1024, 1024, NMPWAIT_WAIT_FOREVER, NULL);
2316     ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %u\n", GetLastError());
2317 
2318     memset(&overlapped, 0, sizeof(overlapped));
2319     overlapped.hEvent = event;
2320     ret = ConnectNamedPipe(pipe, &overlapped);
2321     err = GetLastError();
2322     ok(ret == FALSE, "ConnectNamedPipe succeeded\n");
2323     ok(err == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %u\n", err);
2324 
2325     file = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL,
2326                        OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
2327     ok(file != INVALID_HANDLE_VALUE, "CreateFile failed with %u\n", GetLastError());
2328 
2329     numbytes = 0xdeadbeef;
2330     ret = GetOverlappedResult(pipe, &overlapped, &numbytes, TRUE);
2331     ok(ret == TRUE, "GetOverlappedResult failed\n");
2332     ok(numbytes == 0, "expected 0, got %u\n", numbytes);
2333     ok(overlapped.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08lx\n", overlapped.Internal);
2334 
2335     CloseHandle(file);
2336     CloseHandle(pipe);
2337 
2338     pipe = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
2339                             PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
2340                             1, 1024, 1024, NMPWAIT_WAIT_FOREVER, NULL);
2341     ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe failed with %u\n", GetLastError());
2342 
2343     file = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL,
2344                        OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
2345     ok(file != INVALID_HANDLE_VALUE, "CreateFile failed with %u\n", GetLastError());
2346 
2347     memset(&overlapped, 0, sizeof(overlapped));
2348     overlapped.hEvent = event;
2349     ret = ConnectNamedPipe(pipe, &overlapped);
2350     err = GetLastError();
2351     ok(ret == FALSE, "ConnectNamedPipe succeeded\n");
2352     ok(err == ERROR_PIPE_CONNECTED, "expected ERROR_PIPE_CONNECTED, got %u\n", err);
2353     ok(overlapped.Internal == STATUS_PENDING, "expected STATUS_PENDING, got %08lx\n", overlapped.Internal);
2354 
2355     CloseHandle(file);
2356     CloseHandle(pipe);
2357 
2358     CloseHandle(event);
2359 }
2360 
2361 static void test_NamedPipeHandleState(void)
2362 {
2363     HANDLE server, client;
2364     BOOL ret;
2365     DWORD state, instances, maxCollectionCount, collectDataTimeout;
2366     char userName[MAX_PATH];
2367 
2368     server = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX,
2369         /* dwOpenMode */ PIPE_TYPE_BYTE | PIPE_WAIT,
2370         /* nMaxInstances */ 1,
2371         /* nOutBufSize */ 1024,
2372         /* nInBufSize */ 1024,
2373         /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
2374         /* lpSecurityAttrib */ NULL);
2375     ok(server != INVALID_HANDLE_VALUE, "cf failed\n");
2376     ret = GetNamedPipeHandleStateA(server, NULL, NULL, NULL, NULL, NULL, 0);
2377     ok(ret, "GetNamedPipeHandleState failed: %d\n", GetLastError());
2378     ret = GetNamedPipeHandleStateA(server, &state, &instances, NULL, NULL, NULL,
2379         0);
2380     ok(ret, "GetNamedPipeHandleState failed: %d\n", GetLastError());
2381     if (ret)
2382     {
2383         ok(state == 0, "unexpected state %08x\n", state);
2384         ok(instances == 1, "expected 1 instances, got %d\n", instances);
2385     }
2386     /* Some parameters have no meaning, and therefore can't be retrieved,
2387      * on a local pipe.
2388      */
2389     SetLastError(0xdeadbeef);
2390     ret = GetNamedPipeHandleStateA(server, &state, &instances,
2391         &maxCollectionCount, &collectDataTimeout, userName,
2392         sizeof(userName) / sizeof(userName[0]));
2393     todo_wine
2394     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
2395        "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2396     /* A byte-mode pipe server can't be changed to message mode. */
2397     state = PIPE_READMODE_MESSAGE;
2398     SetLastError(0xdeadbeef);
2399     ret = SetNamedPipeHandleState(server, &state, NULL, NULL);
2400     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
2401        "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2402 
2403     client = CreateFileA(PIPENAME, GENERIC_READ|GENERIC_WRITE, 0, NULL,
2404         OPEN_EXISTING, 0, NULL);
2405     ok(client != INVALID_HANDLE_VALUE, "cf failed\n");
2406 
2407     state = PIPE_READMODE_BYTE;
2408     ret = SetNamedPipeHandleState(client, &state, NULL, NULL);
2409     ok(ret, "SetNamedPipeHandleState failed: %d\n", GetLastError());
2410     /* A byte-mode pipe client can't be changed to message mode, either. */
2411     state = PIPE_READMODE_MESSAGE;
2412     SetLastError(0xdeadbeef);
2413     ret = SetNamedPipeHandleState(server, &state, NULL, NULL);
2414     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
2415        "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2416 
2417     CloseHandle(client);
2418     CloseHandle(server);
2419 
2420     server = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX,
2421         /* dwOpenMode */ PIPE_TYPE_MESSAGE | PIPE_WAIT,
2422         /* nMaxInstances */ 1,
2423         /* nOutBufSize */ 1024,
2424         /* nInBufSize */ 1024,
2425         /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
2426         /* lpSecurityAttrib */ NULL);
2427     ok(server != INVALID_HANDLE_VALUE, "cf failed\n");
2428     ret = GetNamedPipeHandleStateA(server, NULL, NULL, NULL, NULL, NULL, 0);
2429     ok(ret, "GetNamedPipeHandleState failed: %d\n", GetLastError());
2430     ret = GetNamedPipeHandleStateA(server, &state, &instances, NULL, NULL, NULL,
2431         0);
2432     ok(ret, "GetNamedPipeHandleState failed: %d\n", GetLastError());
2433     if (ret)
2434     {
2435         ok(state == 0, "unexpected state %08x\n", state);
2436         ok(instances == 1, "expected 1 instances, got %d\n", instances);
2437     }
2438     /* In contrast to byte-mode pipes, a message-mode pipe server can be
2439      * changed to byte mode.
2440      */
2441     state = PIPE_READMODE_BYTE;
2442     ret = SetNamedPipeHandleState(server, &state, NULL, NULL);
2443     ok(ret, "SetNamedPipeHandleState failed: %d\n", GetLastError());
2444 
2445     client = CreateFileA(PIPENAME, GENERIC_READ|GENERIC_WRITE, 0, NULL,
2446         OPEN_EXISTING, 0, NULL);
2447     ok(client != INVALID_HANDLE_VALUE, "cf failed\n");
2448 
2449     state = PIPE_READMODE_MESSAGE;
2450     ret = SetNamedPipeHandleState(client, &state, NULL, NULL);
2451     ok(ret, "SetNamedPipeHandleState failed: %d\n", GetLastError());
2452     /* A message-mode pipe client can also be changed to byte mode.
2453      */
2454     state = PIPE_READMODE_BYTE;
2455     ret = SetNamedPipeHandleState(client, &state, NULL, NULL);
2456     ok(ret, "SetNamedPipeHandleState failed: %d\n", GetLastError());
2457 
2458     CloseHandle(client);
2459     CloseHandle(server);
2460 }
2461 
2462 static void test_GetNamedPipeInfo(void)
2463 {
2464     HANDLE server;
2465 
2466     server = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX,
2467         /* dwOpenMode */ PIPE_TYPE_BYTE | PIPE_WAIT,
2468         /* nMaxInstances */ 1,
2469         /* nOutBufSize */ 1024,
2470         /* nInBufSize */ 1024,
2471         /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
2472         /* lpSecurityAttrib */ NULL);
2473     ok(server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
2474 
2475     test_pipe_info(server, PIPE_SERVER_END | PIPE_TYPE_BYTE, 1024, 1024, 1);
2476 
2477     CloseHandle(server);
2478 
2479     server = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX,
2480         /* dwOpenMode */ PIPE_TYPE_MESSAGE | PIPE_NOWAIT,
2481         /* nMaxInstances */ 3,
2482         /* nOutBufSize */ 1024,
2483         /* nInBufSize */ 1024,
2484         /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
2485         /* lpSecurityAttrib */ NULL);
2486     ok(server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
2487 
2488     test_pipe_info(server, PIPE_SERVER_END | PIPE_TYPE_MESSAGE, 1024, 1024, 3);
2489 
2490     CloseHandle(server);
2491 
2492     server = CreateNamedPipeA(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX,
2493         /* dwOpenMode */ PIPE_TYPE_MESSAGE | PIPE_WAIT,
2494         /* nMaxInstances */ 1,
2495         /* nOutBufSize */ 0,
2496         /* nInBufSize */ 0,
2497         /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
2498         /* lpSecurityAttrib */ NULL);
2499     ok(server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
2500 
2501     test_pipe_info(server, PIPE_SERVER_END | PIPE_TYPE_MESSAGE, 0, 0, 1);
2502 
2503     CloseHandle(server);
2504 
2505     server = CreateNamedPipeA(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX,
2506         /* dwOpenMode */ PIPE_TYPE_MESSAGE | PIPE_WAIT,
2507         /* nMaxInstances */ 1,
2508         /* nOutBufSize */ 0xf000,
2509         /* nInBufSize */ 0xf000,
2510         /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
2511         /* lpSecurityAttrib */ NULL);
2512     ok(server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
2513 
2514     test_pipe_info(server, PIPE_SERVER_END | PIPE_TYPE_MESSAGE, 0xf000, 0xf000, 1);
2515 
2516     CloseHandle(server);
2517 }
2518 
2519 static void test_readfileex_pending(void)
2520 {
2521     HANDLE server, client, event;
2522     BOOL ret;
2523     DWORD err, wait, num_bytes;
2524     OVERLAPPED overlapped;
2525     char read_buf[1024];
2526     char write_buf[1024];
2527     const char test_string[] = "test";
2528     int i;
2529 
2530     server = CreateNamedPipeA(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX,
2531         /* dwOpenMode */ PIPE_TYPE_BYTE | PIPE_WAIT,
2532         /* nMaxInstances */ 1,
2533         /* nOutBufSize */ 1024,
2534         /* nInBufSize */ 1024,
2535         /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
2536         /* lpSecurityAttrib */ NULL);
2537     ok(server != INVALID_HANDLE_VALUE, "cf failed\n");
2538 
2539     event = CreateEventA(NULL, TRUE, FALSE, NULL);
2540     ok(event != NULL, "CreateEventA failed\n");
2541 
2542     memset(&overlapped, 0, sizeof(overlapped));
2543     overlapped.hEvent = event;
2544 
2545     ret = ConnectNamedPipe(server, &overlapped);
2546     err = GetLastError();
2547     ok(ret == FALSE, "ConnectNamedPipe succeeded\n");
2548     ok(err == ERROR_IO_PENDING, "ConnectNamedPipe set error %i\n", err);
2549 
2550     wait = WaitForSingleObject(event, 0);
2551     ok(wait == WAIT_TIMEOUT, "WaitForSingleObject returned %x\n", wait);
2552 
2553     client = CreateFileA(PIPENAME, GENERIC_READ|GENERIC_WRITE, 0, NULL,
2554         OPEN_EXISTING, 0, NULL);
2555     ok(client != INVALID_HANDLE_VALUE, "cf failed\n");
2556 
2557     wait = WaitForSingleObject(event, 0);
2558     ok(wait == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", wait);
2559 
2560     /* Start a read that can't complete immediately. */
2561     completion_called = 0;
2562     ResetEvent(event);
2563     ret = ReadFileEx(server, read_buf, sizeof(read_buf), &overlapped, completion_routine);
2564     ok(ret == TRUE, "ReadFileEx failed, err=%i\n", GetLastError());
2565     ok(completion_called == 0, "completion routine called before ReadFileEx returned\n");
2566 
2567     ret = WriteFile(client, test_string, strlen(test_string), &num_bytes, NULL);
2568     ok(ret == TRUE, "WriteFile failed\n");
2569     ok(num_bytes == strlen(test_string), "only %i bytes written\n", num_bytes);
2570 
2571     ok(completion_called == 0, "completion routine called during WriteFile\n");
2572 
2573     wait = WaitForSingleObjectEx(event, 0, TRUE);
2574     ok(wait == WAIT_IO_COMPLETION || wait == WAIT_OBJECT_0, "WaitForSingleObjectEx returned %x\n", wait);
2575 
2576     ok(completion_called == 1, "completion not called after writing pipe\n");
2577     ok(completion_errorcode == 0, "completion called with error %x\n", completion_errorcode);
2578     ok(completion_num_bytes == strlen(test_string), "ReadFileEx returned only %d bytes\n", completion_num_bytes);
2579     ok(completion_lpoverlapped == &overlapped, "completion called with wrong overlapped pointer\n");
2580     ok(!memcmp(test_string, read_buf, strlen(test_string)), "ReadFileEx read wrong bytes\n");
2581 
2582     /* Make writes until the pipe is full and the write fails */
2583     memset(write_buf, 0xaa, sizeof(write_buf));
2584     for (i=0; i<256; i++)
2585     {
2586         completion_called = 0;
2587         ResetEvent(event);
2588         ret = WriteFileEx(server, write_buf, sizeof(write_buf), &overlapped, completion_routine);
2589         err = GetLastError();
2590 
2591         ok(completion_called == 0, "completion routine called during WriteFileEx\n");
2592 
2593         wait = WaitForSingleObjectEx(event, 0, TRUE);
2594 
2595         if (wait == WAIT_TIMEOUT)
2596             /* write couldn't complete immediately, presumably the pipe is full */
2597             break;
2598 
2599         ok(wait == WAIT_IO_COMPLETION || wait == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", wait);
2600 
2601         ok(ret == TRUE, "WriteFileEx failed, err=%i\n", err);
2602         ok(completion_errorcode == 0, "completion called with error %x\n", completion_errorcode);
2603         ok(completion_lpoverlapped == &overlapped, "completion called with wrong overlapped pointer\n");
2604     }
2605 
2606     ok(ret == TRUE, "WriteFileEx failed, err=%i\n", err);
2607     ok(completion_called == 0, "completion routine called but wait timed out\n");
2608     ok(completion_errorcode == 0, "completion called with error %x\n", completion_errorcode);
2609     ok(completion_lpoverlapped == &overlapped, "completion called with wrong overlapped pointer\n");
2610 
2611     /* free up some space in the pipe */
2612     for (i=0; i<256; i++)
2613     {
2614         ret = ReadFile(client, read_buf, sizeof(read_buf), &num_bytes, NULL);
2615         ok(ret == TRUE, "ReadFile failed\n");
2616 
2617         ok(completion_called == 0, "completion routine called during ReadFile\n");
2618 
2619         wait = WaitForSingleObjectEx(event, 0, TRUE);
2620         ok(wait == WAIT_IO_COMPLETION || wait == WAIT_OBJECT_0 || wait == WAIT_TIMEOUT,
2621            "WaitForSingleObject returned %x\n", wait);
2622         if (wait != WAIT_TIMEOUT) break;
2623     }
2624 
2625     ok(completion_called == 1, "completion routine not called\n");
2626     ok(completion_errorcode == 0, "completion called with error %x\n", completion_errorcode);
2627     ok(completion_lpoverlapped == &overlapped, "completion called with wrong overlapped pointer\n");
2628 
2629     num_bytes = 0xdeadbeef;
2630     SetLastError(0xdeadbeef);
2631     ret = ReadFile(INVALID_HANDLE_VALUE, read_buf, 0, &num_bytes, NULL);
2632     ok(!ret, "ReadFile should fail\n");
2633     ok(GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError());
2634     ok(num_bytes == 0, "expected 0, got %u\n", num_bytes);
2635 
2636     S(U(overlapped)).Offset = 0;
2637     S(U(overlapped)).OffsetHigh = 0;
2638     overlapped.Internal = -1;
2639     overlapped.InternalHigh = -1;
2640     overlapped.hEvent = event;
2641     num_bytes = 0xdeadbeef;
2642     SetLastError(0xdeadbeef);
2643     ret = ReadFile(server, read_buf, 0, &num_bytes, &overlapped);
2644     ok(!ret, "ReadFile should fail\n");
2645     ok(GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %d\n", GetLastError());
2646     ok(num_bytes == 0, "bytes %u\n", num_bytes);
2647     ok((NTSTATUS)overlapped.Internal == STATUS_PENDING, "expected STATUS_PENDING, got %#lx\n", overlapped.Internal);
2648     ok(overlapped.InternalHigh == -1, "expected -1, got %lu\n", overlapped.InternalHigh);
2649 
2650     wait = WaitForSingleObject(event, 100);
2651     ok(wait == WAIT_TIMEOUT, "WaitForSingleObject returned %x\n", wait);
2652 
2653     num_bytes = 0xdeadbeef;
2654     ret = WriteFile(client, test_string, 1, &num_bytes, NULL);
2655     ok(ret, "WriteFile failed\n");
2656     ok(num_bytes == 1, "bytes %u\n", num_bytes);
2657 
2658     wait = WaitForSingleObject(event, 100);
2659     ok(wait == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", wait);
2660 
2661     ok(num_bytes == 1, "bytes %u\n", num_bytes);
2662     ok((NTSTATUS)overlapped.Internal == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %#lx\n", overlapped.Internal);
2663     ok(overlapped.InternalHigh == 0, "expected 0, got %lu\n", overlapped.InternalHigh);
2664 
2665     /* read the pending byte and clear the pipe */
2666     num_bytes = 0xdeadbeef;
2667     ret = ReadFile(server, read_buf, 1, &num_bytes, &overlapped);
2668     ok(ret, "ReadFile failed\n");
2669     ok(num_bytes == 1, "bytes %u\n", num_bytes);
2670 
2671     CloseHandle(client);
2672     CloseHandle(server);
2673     CloseHandle(event);
2674 }
2675 
2676 #define test_peek_pipe(a,b,c,d) _test_peek_pipe(__LINE__,a,b,c,d)
2677 static void _test_peek_pipe(unsigned line, HANDLE pipe, DWORD expected_read, DWORD expected_avail, DWORD expected_message_length)
2678 {
2679     DWORD bytes_read = 0xdeadbeed, avail = 0xdeadbeef, left = 0xdeadbeed;
2680     char buf[4000];
2681     FILE_PIPE_PEEK_BUFFER *peek_buf = (void*)buf;
2682     IO_STATUS_BLOCK io;
2683     NTSTATUS status;
2684     BOOL r;
2685 
2686     r = PeekNamedPipe(pipe, buf, sizeof(buf), &bytes_read, &avail, &left);
2687     ok_(__FILE__,line)(r, "PeekNamedPipe failed: %u\n", GetLastError());
2688     ok_(__FILE__,line)(bytes_read == expected_read, "bytes_read = %u, expected %u\n", bytes_read, expected_read);
2689     ok_(__FILE__,line)(avail == expected_avail, "avail = %u, expected %u\n", avail, expected_avail);
2690     ok_(__FILE__,line)(left == expected_message_length - expected_read, "left = %d, expected %d\n",
2691                        left, expected_message_length - expected_read);
2692 
2693     status = NtFsControlFile(pipe, 0, NULL, NULL, &io, FSCTL_PIPE_PEEK, NULL, 0, buf, sizeof(buf));
2694     ok_(__FILE__,line)(!status || status == STATUS_PENDING, "NtFsControlFile(FSCTL_PIPE_PEEK) failed: %x\n", status);
2695     ok_(__FILE__,line)(io.Information == FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[expected_read]),
2696                        "io.Information = %lu\n", io.Information);
2697     ok_(__FILE__,line)(peek_buf->ReadDataAvailable == expected_avail, "ReadDataAvailable = %u, expected %u\n",
2698                        peek_buf->ReadDataAvailable, expected_avail);
2699     ok_(__FILE__,line)(peek_buf->MessageLength == expected_message_length, "MessageLength = %u, expected %u\n",
2700                        peek_buf->MessageLength, expected_message_length);
2701 
2702     if (expected_read)
2703     {
2704         r = PeekNamedPipe(pipe, buf, 1, &bytes_read, &avail, &left);
2705         ok_(__FILE__,line)(r, "PeekNamedPipe failed: %u\n", GetLastError());
2706         ok_(__FILE__,line)(bytes_read == 1, "bytes_read = %u, expected %u\n", bytes_read, expected_read);
2707         ok_(__FILE__,line)(avail == expected_avail, "avail = %u, expected %u\n", avail, expected_avail);
2708         ok_(__FILE__,line)(left == expected_message_length-1, "left = %d, expected %d\n", left, expected_message_length-1);
2709     }
2710 }
2711 
2712 #define overlapped_read_sync(a,b,c,d,e) _overlapped_read_sync(__LINE__,a,b,c,d,e)
2713 static void _overlapped_read_sync(unsigned line, HANDLE reader, void *buf, DWORD buf_size, DWORD expected_result, BOOL partial_read)
2714 {
2715     DWORD read_bytes = 0xdeadbeef;
2716     OVERLAPPED overlapped;
2717     BOOL res;
2718 
2719     memset(&overlapped, 0, sizeof(overlapped));
2720     overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
2721     res = ReadFile(reader, buf, buf_size, &read_bytes, &overlapped);
2722     if (partial_read)
2723         ok_(__FILE__,line)(!res && GetLastError() == ERROR_MORE_DATA, "ReadFile returned: %x (%u)\n", res, GetLastError());
2724     else
2725         ok_(__FILE__,line)(res, "ReadFile failed: %u\n", GetLastError());
2726     if(partial_read)
2727         ok_(__FILE__,line)(!read_bytes, "read_bytes %u expected 0\n", read_bytes);
2728     else
2729         ok_(__FILE__,line)(read_bytes == expected_result, "read_bytes %u expected %u\n", read_bytes, expected_result);
2730 
2731     read_bytes = 0xdeadbeef;
2732     res = GetOverlappedResult(reader, &overlapped, &read_bytes, FALSE);
2733     if (partial_read)
2734         ok_(__FILE__,line)(!res && GetLastError() == ERROR_MORE_DATA,
2735                            "GetOverlappedResult returned: %x (%u)\n", res, GetLastError());
2736     else
2737         ok_(__FILE__,line)(res, "GetOverlappedResult failed: %u\n", GetLastError());
2738     ok_(__FILE__,line)(read_bytes == expected_result, "read_bytes %u expected %u\n", read_bytes, expected_result);
2739     CloseHandle(overlapped.hEvent);
2740 }
2741 
2742 #define overlapped_read_async(a,b,c,d) _overlapped_read_async(__LINE__,a,b,c,d)
2743 static void _overlapped_read_async(unsigned line, HANDLE reader, void *buf, DWORD buf_size, OVERLAPPED *overlapped)
2744 {
2745     DWORD read_bytes = 0xdeadbeef;
2746     BOOL res;
2747 
2748     memset(overlapped, 0, sizeof(*overlapped));
2749     overlapped->hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
2750     res = ReadFile(reader, buf, buf_size, &read_bytes, overlapped);
2751     ok_(__FILE__,line)(!res && GetLastError() == ERROR_IO_PENDING, "ReadFile returned %x(%u)\n", res, GetLastError());
2752     ok_(__FILE__,line)(!read_bytes, "read_bytes %u expected 0\n", read_bytes);
2753 
2754     _test_not_signaled(line, overlapped->hEvent);
2755 }
2756 
2757 #define overlapped_write_sync(a,b,c) _overlapped_write_sync(__LINE__,a,b,c)
2758 static void _overlapped_write_sync(unsigned line, HANDLE writer, void *buf, DWORD size)
2759 {
2760     DWORD written_bytes = 0xdeadbeef;
2761     OVERLAPPED overlapped;
2762     BOOL res;
2763 
2764     memset(&overlapped, 0, sizeof(overlapped));
2765     overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
2766     res = WriteFile(writer, buf, size, &written_bytes, &overlapped);
2767     ok_(__FILE__,line)(res, "WriteFile returned %x(%u)\n", res, GetLastError());
2768     ok_(__FILE__,line)(written_bytes == size, "WriteFile returned written_bytes = %u\n", written_bytes);
2769 
2770     written_bytes = 0xdeadbeef;
2771     res = GetOverlappedResult(writer, &overlapped, &written_bytes, FALSE);
2772     ok_(__FILE__,line)(res, "GetOverlappedResult failed: %u\n", GetLastError());
2773     ok_(__FILE__,line)(written_bytes == size, "GetOverlappedResult returned written_bytes %u expected %u\n", written_bytes, size);
2774 
2775     CloseHandle(overlapped.hEvent);
2776 }
2777 
2778 #define overlapped_write_async(a,b,c,d) _overlapped_write_async(__LINE__,a,b,c,d)
2779 static void _overlapped_write_async(unsigned line, HANDLE writer, void *buf, DWORD size, OVERLAPPED *overlapped)
2780 {
2781     DWORD written_bytes = 0xdeadbeef;
2782     BOOL res;
2783 
2784     memset(overlapped, 0, sizeof(*overlapped));
2785     overlapped->hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
2786     res = WriteFile(writer, buf, size, &written_bytes, overlapped);
2787     ok_(__FILE__,line)(!res && GetLastError() == ERROR_IO_PENDING, "WriteFile returned %x(%u)\n", res, GetLastError());
2788     ok_(__FILE__,line)(!written_bytes, "written_bytes = %u\n", written_bytes);
2789 
2790     _test_not_signaled(line, overlapped->hEvent);
2791 }
2792 
2793 #define test_flush_sync(a) _test_flush_sync(__LINE__,a)
2794 static void _test_flush_sync(unsigned line, HANDLE pipe)
2795 {
2796     BOOL res;
2797 
2798     res = FlushFileBuffers(pipe);
2799     ok_(__FILE__,line)(res, "FlushFileBuffers failed: %u\n", GetLastError());
2800 }
2801 
2802 static DWORD expected_flush_error;
2803 
2804 static DWORD CALLBACK flush_proc(HANDLE pipe)
2805 {
2806     BOOL res;
2807 
2808     res = FlushFileBuffers(pipe);
2809     if (expected_flush_error == ERROR_SUCCESS)
2810         ok(res, "FlushFileBuffers failed: %u\n", GetLastError());
2811     else
2812         todo_wine ok(!res && GetLastError() == expected_flush_error, "FlushFileBuffers failed: %u\n", GetLastError());
2813     return 0;
2814 }
2815 
2816 #define test_flush_async(a,b) _test_flush_async(__LINE__,a,b)
2817 static HANDLE _test_flush_async(unsigned line, HANDLE pipe, DWORD error)
2818 {
2819     HANDLE thread;
2820     DWORD tid;
2821 
2822     expected_flush_error = error;
2823     thread = CreateThread(NULL, 0, flush_proc, pipe, 0, &tid);
2824     ok_(__FILE__,line)(thread != NULL, "CreateThread failed: %u\n", GetLastError());
2825 
2826     Sleep(50);
2827     _test_not_signaled(line, thread);
2828     return thread;
2829 }
2830 
2831 #define test_flush_done(a) _test_flush_done(__LINE__,a)
2832 static void _test_flush_done(unsigned line, HANDLE thread)
2833 {
2834     DWORD res = WaitForSingleObject(thread, 1000);
2835     ok_(__FILE__,line)(res == WAIT_OBJECT_0, "WaitForSingleObject returned %u (%u)\n", res, GetLastError());
2836     CloseHandle(thread);
2837 }
2838 
2839 #define test_overlapped_result(a,b,c,d) _test_overlapped_result(__LINE__,a,b,c,d)
2840 static void _test_overlapped_result(unsigned line, HANDLE handle, OVERLAPPED *overlapped, DWORD expected_result, BOOL partial_read)
2841 {
2842     DWORD result = 0xdeadbeef;
2843     BOOL res;
2844 
2845     _test_signaled(line, overlapped->hEvent);
2846 
2847     res = GetOverlappedResult(handle, overlapped, &result, FALSE);
2848     if (partial_read)
2849         ok_(__FILE__,line)(!res && GetLastError() == ERROR_MORE_DATA, "GetOverlappedResult returned: %x (%u)\n", res, GetLastError());
2850     else
2851         ok_(__FILE__,line)(res, "GetOverlappedResult failed: %u\n", GetLastError());
2852     ok_(__FILE__,line)(result == expected_result, "read_bytes = %u, expected %u\n", result, expected_result);
2853     CloseHandle(overlapped->hEvent);
2854 }
2855 
2856 #define test_overlapped_failure(a,b,c) _test_overlapped_failure(__LINE__,a,b,c)
2857 static void _test_overlapped_failure(unsigned line, HANDLE handle, OVERLAPPED *overlapped, DWORD error)
2858 {
2859     DWORD result;
2860     BOOL res;
2861 
2862     _test_signaled(line, overlapped->hEvent);
2863 
2864     res = GetOverlappedResult(handle, overlapped, &result, FALSE);
2865     ok_(__FILE__,line)(!res && GetLastError() == error, "GetOverlappedResult returned: %x (%u), expected error %u\n",
2866                        res, GetLastError(), error);
2867     ok_(__FILE__,line)(!result, "result = %u\n", result);
2868     CloseHandle(overlapped->hEvent);
2869 }
2870 
2871 #define cancel_overlapped(a,b) _cancel_overlapped(__LINE__,a,b)
2872 static void _cancel_overlapped(unsigned line, HANDLE handle, OVERLAPPED *overlapped)
2873 {
2874     BOOL res;
2875 
2876     res = pCancelIoEx(handle, overlapped);
2877     ok_(__FILE__,line)(res, "CancelIoEx failed: %u\n", GetLastError());
2878 
2879     _test_overlapped_failure(line, handle, overlapped, ERROR_OPERATION_ABORTED);
2880 }
2881 
2882 static void test_blocking_rw(HANDLE writer, HANDLE reader, DWORD buf_size, BOOL msg_mode, BOOL msg_read)
2883 {
2884     OVERLAPPED read_overlapped, read_overlapped2, write_overlapped, write_overlapped2;
2885     char buf[10000], read_buf[10000];
2886     HANDLE flush_thread;
2887 
2888     memset(buf, 0xaa, sizeof(buf));
2889 
2890     /* test pending read with overlapped event */
2891     overlapped_read_async(reader, read_buf, 1000, &read_overlapped);
2892     test_flush_sync(writer);
2893     test_peek_pipe(reader, 0, 0, 0);
2894 
2895     /* write more data than needed for read */
2896     overlapped_write_sync(writer, buf, 4000);
2897     test_overlapped_result(reader, &read_overlapped, 1000, msg_read);
2898 
2899     /* test pending write with overlapped event */
2900     overlapped_write_async(writer, buf, buf_size, &write_overlapped);
2901 
2902     /* write one more byte */
2903     overlapped_write_async(writer, buf, 1, &write_overlapped2);
2904     flush_thread = test_flush_async(writer, ERROR_SUCCESS);
2905     test_not_signaled(write_overlapped.hEvent);
2906 
2907     /* empty write will not block */
2908     overlapped_write_sync(writer, buf, 0);
2909     test_not_signaled(write_overlapped.hEvent);
2910     test_not_signaled(write_overlapped2.hEvent);
2911 
2912     /* read remaining data from the first write */
2913     overlapped_read_sync(reader, read_buf, 3000, 3000, FALSE);
2914     test_overlapped_result(writer, &write_overlapped, buf_size, FALSE);
2915     test_not_signaled(write_overlapped2.hEvent);
2916     test_not_signaled(flush_thread);
2917 
2918     /* read one byte so that the next write fits the buffer */
2919     overlapped_read_sync(reader, read_buf, 1, 1, msg_read);
2920     test_overlapped_result(writer, &write_overlapped2, 1, FALSE);
2921 
2922     /* read the whole buffer */
2923     overlapped_read_sync(reader, read_buf, buf_size, buf_size-msg_read, FALSE);
2924 
2925     if(msg_read)
2926         overlapped_read_sync(reader, read_buf, 1000, 1, FALSE);
2927 
2928     if(msg_mode) {
2929         /* we still have an empty message in queue */
2930         overlapped_read_sync(reader, read_buf, 1000, 0, FALSE);
2931     }
2932     test_flush_done(flush_thread);
2933 
2934     /* pipe is empty, the next read will block */
2935     overlapped_read_async(reader, read_buf, 0, &read_overlapped);
2936     overlapped_read_async(reader, read_buf, 1000, &read_overlapped2);
2937 
2938     /* write one byte */
2939     overlapped_write_sync(writer, buf, 1);
2940     test_overlapped_result(reader, &read_overlapped, 0, msg_read);
2941     test_overlapped_result(reader, &read_overlapped2, 1, FALSE);
2942 
2943     /* write a message larger than buffer */
2944     overlapped_write_async(writer, buf, buf_size+2000, &write_overlapped);
2945 
2946     /* read so that pending write is still larger than the buffer */
2947     overlapped_read_sync(reader, read_buf, 1999, 1999, msg_read);
2948     test_not_signaled(write_overlapped.hEvent);
2949 
2950     /* read one more byte */
2951     overlapped_read_sync(reader, read_buf, 1, 1, msg_read);
2952     test_overlapped_result(writer, &write_overlapped, buf_size+2000, FALSE);
2953 
2954     /* read remaining data */
2955     overlapped_read_sync(reader, read_buf, buf_size+1, buf_size, FALSE);
2956 
2957     /* simple pass of empty message */
2958     overlapped_write_sync(writer, buf, 0);
2959     if(msg_mode)
2960         overlapped_read_sync(reader, read_buf, 1, 0, FALSE);
2961 
2962     /* pipe is empty, the next read will block */
2963     test_flush_sync(writer);
2964     overlapped_read_async(reader, read_buf, 0, &read_overlapped);
2965     overlapped_read_async(reader, read_buf, 1, &read_overlapped2);
2966 
2967     /* 0 length write wakes one read in msg mode */
2968     overlapped_write_sync(writer, buf, 0);
2969     if(msg_mode)
2970         test_overlapped_result(reader, &read_overlapped, 0, FALSE);
2971     else
2972         test_not_signaled(read_overlapped.hEvent);
2973     test_not_signaled(read_overlapped2.hEvent);
2974     overlapped_write_sync(writer, buf, 1);
2975     test_overlapped_result(reader, &read_overlapped2, 1, FALSE);
2976 
2977     overlapped_write_sync(writer, buf, 20);
2978     test_peek_pipe(reader, 20, 20, msg_mode ? 20 : 0);
2979     overlapped_write_sync(writer, buf, 15);
2980     test_peek_pipe(reader, msg_mode ? 20 : 35, 35, msg_mode ? 20 : 0);
2981     overlapped_read_sync(reader, read_buf, 10, 10, msg_read);
2982     test_peek_pipe(reader, msg_mode ? 10 : 25, 25, msg_mode ? 10 : 0);
2983     overlapped_read_sync(reader, read_buf, 10, 10, FALSE);
2984     test_peek_pipe(reader, 15, 15, msg_mode ? 15 : 0);
2985     overlapped_read_sync(reader, read_buf, 15, 15, FALSE);
2986 
2987     if(!pCancelIoEx) {
2988         win_skip("CancelIoEx not available\n");
2989         return;
2990     }
2991 
2992     /* add one more pending read, then cancel the first one */
2993     overlapped_read_async(reader, read_buf, 1, &read_overlapped);
2994     overlapped_read_async(reader, read_buf, 1, &read_overlapped2);
2995     cancel_overlapped(reader, &read_overlapped2);
2996     test_not_signaled(read_overlapped.hEvent);
2997     overlapped_write_sync(writer, buf, 1);
2998     test_overlapped_result(reader, &read_overlapped, 1, FALSE);
2999 
3000     /* make two async writes, cancel the first one and make sure that we read from the second one */
3001     overlapped_write_async(writer, buf, buf_size+2000, &write_overlapped);
3002     overlapped_write_async(writer, buf, 1, &write_overlapped2);
3003     cancel_overlapped(writer, &write_overlapped);
3004     overlapped_read_sync(reader, read_buf, 1000, 1, FALSE);
3005     test_overlapped_result(writer, &write_overlapped2, 1, FALSE);
3006 
3007     /* same as above, but parially read written data before canceling */
3008     overlapped_write_async(writer, buf, buf_size+2000, &write_overlapped);
3009     overlapped_write_async(writer, buf, 1, &write_overlapped2);
3010     overlapped_read_sync(reader, read_buf, 10, 10, msg_read);
3011     test_not_signaled(write_overlapped.hEvent);
3012     cancel_overlapped(writer, &write_overlapped);
3013     overlapped_read_sync(reader, read_buf, 1000, 1, FALSE);
3014     test_overlapped_result(writer, &write_overlapped2, 1, FALSE);
3015 
3016     /* empty queue by canceling write and make sure that flush is signaled */
3017     overlapped_write_async(writer, buf, buf_size+2000, &write_overlapped);
3018     flush_thread = test_flush_async(writer, ERROR_SUCCESS);
3019     test_not_signaled(flush_thread);
3020     cancel_overlapped(writer, &write_overlapped);
3021     test_flush_done(flush_thread);
3022 }
3023 
3024 static void child_process_write_pipe(HANDLE pipe)
3025 {
3026     OVERLAPPED overlapped;
3027     char buf[10000];
3028 
3029     memset(buf, 'x', sizeof(buf));
3030     overlapped_write_async(pipe, buf, sizeof(buf), &overlapped);
3031 
3032     /* sleep until parent process terminates this process */
3033     Sleep(INFINITE);
3034 }
3035 
3036 static HANDLE create_writepipe_process(HANDLE pipe)
3037 {
3038     STARTUPINFOA si = { sizeof(si) };
3039     PROCESS_INFORMATION info;
3040     char **argv, buf[MAX_PATH];
3041     BOOL res;
3042 
3043     winetest_get_mainargs(&argv);
3044     sprintf(buf, "\"%s\" pipe writepipe %lx", argv[0], (UINT_PTR)pipe);
3045     res = CreateProcessA(NULL, buf, NULL, NULL, TRUE, 0L, NULL, NULL, &si, &info);
3046     ok(res, "CreateProcess failed: %u\n", GetLastError());
3047     CloseHandle(info.hThread);
3048 
3049     return info.hProcess;
3050 }
3051 
3052 static void create_overlapped_pipe(DWORD mode, HANDLE *client, HANDLE *server)
3053 {
3054     SECURITY_ATTRIBUTES sec_attr = { sizeof(sec_attr), NULL, TRUE };
3055     DWORD read_mode = mode & (PIPE_READMODE_BYTE | PIPE_READMODE_MESSAGE);
3056     OVERLAPPED overlapped;
3057     BOOL res;
3058 
3059     *server = CreateNamedPipeA(PIPENAME, FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX,
3060                                PIPE_WAIT | mode, 1, 5000, 6000, NMPWAIT_USE_DEFAULT_WAIT, NULL);
3061     ok(&server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %u\n", GetLastError());
3062     test_signaled(*server);
3063 
3064     memset(&overlapped, 0, sizeof(overlapped));
3065     overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
3066     res = ConnectNamedPipe(*server, &overlapped);
3067     ok(!res && GetLastError() == ERROR_IO_PENDING, "WriteFile returned %x(%u)\n", res, GetLastError());
3068     test_not_signaled(*server);
3069     test_not_signaled(overlapped.hEvent);
3070 
3071     *client = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, &sec_attr, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
3072     ok(*server != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError());
3073 
3074     res = SetNamedPipeHandleState(*client, &read_mode, NULL, NULL);
3075     ok(res, "SetNamedPipeHandleState failed: %u\n", GetLastError());
3076 
3077     test_signaled(*client);
3078     test_not_signaled(*server);
3079     test_overlapped_result(*server, &overlapped, 0, FALSE);
3080 }
3081 
3082 static void test_overlapped_transport(BOOL msg_mode, BOOL msg_read_mode)
3083 {
3084     OVERLAPPED overlapped, overlapped2;
3085     HANDLE server, client, flush;
3086     DWORD read_bytes;
3087     HANDLE process;
3088     char buf[60000];
3089     BOOL res;
3090 
3091     DWORD create_flags =
3092         (msg_mode ? PIPE_TYPE_MESSAGE : PIPE_TYPE_BYTE) |
3093         (msg_read_mode ? PIPE_READMODE_MESSAGE : PIPE_READMODE_BYTE);
3094 
3095     create_overlapped_pipe(create_flags, &client, &server);
3096 
3097     trace("testing %s, %s server->client writes...\n",
3098           msg_mode ? "message mode" : "byte mode", msg_read_mode ? "message read" : "byte read");
3099     test_blocking_rw(server, client, 5000, msg_mode, msg_read_mode);
3100     trace("testing %s, %s client->server writes...\n",
3101           msg_mode ? "message mode" : "byte mode", msg_read_mode ? "message read" : "byte read");
3102     test_blocking_rw(client, server, 6000, msg_mode, msg_read_mode);
3103 
3104     CloseHandle(client);
3105     CloseHandle(server);
3106 
3107     /* close client with pending writes */
3108     create_overlapped_pipe(create_flags, &client, &server);
3109     overlapped_write_async(server, buf, 7000, &overlapped);
3110     flush = test_flush_async(server, ERROR_BROKEN_PIPE);
3111     CloseHandle(client);
3112     test_overlapped_failure(server, &overlapped, ERROR_BROKEN_PIPE);
3113     test_flush_done(flush);
3114     CloseHandle(server);
3115 
3116     /* close server with pending writes */
3117     create_overlapped_pipe(create_flags, &client, &server);
3118     overlapped_write_async(client, buf, 7000, &overlapped);
3119     flush = test_flush_async(client, ERROR_BROKEN_PIPE);
3120     CloseHandle(server);
3121     test_overlapped_failure(client, &overlapped, ERROR_BROKEN_PIPE);
3122     test_flush_done(flush);
3123     CloseHandle(client);
3124 
3125     /* disconnect with pending writes */
3126     create_overlapped_pipe(create_flags, &client, &server);
3127     overlapped_write_async(client, buf, 7000, &overlapped);
3128     overlapped_write_async(server, buf, 7000, &overlapped2);
3129     flush = test_flush_async(client, ERROR_PIPE_NOT_CONNECTED);
3130     res = DisconnectNamedPipe(server);
3131     ok(res, "DisconnectNamedPipe failed: %u\n", GetLastError());
3132     test_overlapped_failure(client, &overlapped, ERROR_PIPE_NOT_CONNECTED);
3133     test_overlapped_failure(client, &overlapped2, ERROR_PIPE_NOT_CONNECTED);
3134     test_flush_done(flush);
3135     CloseHandle(server);
3136     CloseHandle(client);
3137 
3138     /* terminate process with pending write */
3139     create_overlapped_pipe(create_flags, &client, &server);
3140     process = create_writepipe_process(client);
3141     /* successfully read part of write that is pending in child process */
3142     res = ReadFile(server, buf, 10, &read_bytes, NULL);
3143     if(!msg_read_mode)
3144         ok(res, "ReadFile failed: %u\n", GetLastError());
3145     else
3146         ok(!res && GetLastError() == ERROR_MORE_DATA, "ReadFile returned: %x %u\n", res, GetLastError());
3147     ok(read_bytes == 10, "read_bytes = %u\n", read_bytes);
3148     TerminateProcess(process, 0);
3149     winetest_wait_child_process(process);
3150     /* after terminating process, there is no pending write and pipe buffer is empty */
3151     overlapped_read_async(server, buf, 10, &overlapped);
3152     overlapped_write_sync(client, buf, 1);
3153     test_overlapped_result(server, &overlapped, 1, FALSE);
3154     CloseHandle(process);
3155     CloseHandle(server);
3156     CloseHandle(client);
3157 }
3158 
3159 START_TEST(pipe)
3160 {
3161     char **argv;
3162     int argc;
3163     HMODULE hmod;
3164 
3165     hmod = GetModuleHandleA("advapi32.dll");
3166     pDuplicateTokenEx = (void *) GetProcAddress(hmod, "DuplicateTokenEx");
3167     hmod = GetModuleHandleA("kernel32.dll");
3168     pQueueUserAPC = (void *) GetProcAddress(hmod, "QueueUserAPC");
3169     pCancelIoEx = (void *) GetProcAddress(hmod, "CancelIoEx");
3170 
3171     argc = winetest_get_mainargs(&argv);
3172 
3173     if (argc > 3 && !strcmp(argv[2], "writepipe"))
3174     {
3175         UINT_PTR handle;
3176         sscanf(argv[3], "%lx", &handle);
3177         child_process_write_pipe((HANDLE)handle);
3178         return;
3179     }
3180 
3181     if (test_DisconnectNamedPipe())
3182         return;
3183     test_CreateNamedPipe_instances_must_match();
3184     test_NamedPipe_2();
3185     test_CreateNamedPipe(PIPE_TYPE_BYTE);
3186     test_CreateNamedPipe(PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE);
3187     test_CreatePipe();
3188     test_ReadFile();
3189     test_CloseHandle();
3190     test_impersonation();
3191     test_overlapped();
3192     test_overlapped_error();
3193     test_NamedPipeHandleState();
3194     test_GetNamedPipeInfo();
3195     test_readfileex_pending();
3196     test_overlapped_transport(TRUE, FALSE);
3197     test_overlapped_transport(TRUE, TRUE);
3198     test_overlapped_transport(FALSE, FALSE);
3199 }
3200