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