ReactOS 0.4.15-dev-8145-ga541a46
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
38static BOOL (WINAPI *pDuplicateTokenEx)(HANDLE,DWORD,LPSECURITY_ATTRIBUTES,
40static 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;
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)
117static 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)
125static 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)
132static 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
145static void test_CreateNamedPipe(int pipemode)
146{
147 HANDLE hnp;
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);
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 */
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);
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);
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
729static 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));
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;
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;
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;
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;
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;
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;
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
1209static VOID WINAPI completion_routine(DWORD errorcode, DWORD num_bytes, LPOVERLAPPED lpoverlapped)
1210{
1212 completion_errorcode = errorcode;
1213 completion_num_bytes = num_bytes;
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");
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");
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
1311static 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 */
1329 NULL, OPEN_EXISTING, 0, 0);
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");
1358 if (winetest_debug > 1) trace("exercizeServer returning\n");
1359}
1360
1361static 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}
1483static 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
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;
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
1551static 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
1598 ok(ret, "GetNamedPipeHandleState failed with %u\n", GetLastError());
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
1649 ok(ret, "GetNamedPipeHandleState failed with %u\n", GetLastError());
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
1708 ok(ret, "GetNamedPipeHandleState failed with %u\n", GetLastError());
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
1759 ok(ret, "GetNamedPipeHandleState failed with %u\n", GetLastError());
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{
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 */
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 {
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;
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
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
2028static 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
2049static 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
2065static 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
2080static 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
2096static 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
2111static 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
2131static 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
2148static 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
2164static 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);
2198 CloseHandle(hClientToken);
2203 CloseHandle(hClientToken);
2207
2210 CloseHandle(hClientToken);
2215 CloseHandle(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
2278static 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
2304static 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;
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
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;
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
2357 CloseHandle(pipe);
2358
2360}
2361
2363{
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());
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());
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
2463static 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
2516
2518}
2519
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. */
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 {
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);
2632 ret = ReadFile(INVALID_HANDLE_VALUE, read_buf, 0, &num_bytes, NULL);
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);
2644 ret = ReadFile(server, read_buf, 0, &num_bytes, &overlapped);
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;
2655 ret = WriteFile(client, test_string, 1, &num_bytes, NULL);
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;
2668 ret = ReadFile(server, read_buf, 1, &num_bytes, &overlapped);
2669 ok(ret, "ReadFile failed\n");
2670 ok(num_bytes == 1, "bytes %u\n", num_bytes);
2671
2675}
2676
2677#define test_peek_pipe(a,b,c,d) _test_peek_pipe(__LINE__,a,b,c,d)
2678static 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;
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)
2714static 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));
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)
2744static 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)
2759static 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));
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)
2780static 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)
2797static 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)
2835static 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
2885static 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 */
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);
2988