2 * Unit tests for named pipe functions in Wine
4 * Copyright (c) 2002 Dan Kegel
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #include "wine/test.h"
32 #define START_TEST(name) main(int argc, char **argv)
33 #define ok(condition, msg) \
37 fprintf(stderr,"failed at %d\n",__LINE__); \
50 #define PIPENAME "\\\\.\\PiPe\\tests_" __FILE__
52 void test_CreateNamedPipe(void)
56 const char obuf[] = "Bit Bucket";
61 trace("test_CreateNamedPipe starting\n");
62 /* Bad parameter checks */
63 hnp = CreateNamedPipe("not a named pipe", PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
64 /* nMaxInstances */ 1,
65 /* nOutBufSize */ 1024,
66 /* nInBufSize */ 1024,
67 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
68 /* lpSecurityAttrib */ NULL);
70 if (hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) {
71 /* Is this the right way to notify user of skipped tests? */
72 ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED,
73 "CreateNamedPipe not supported on this platform, skipping tests.");
76 ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_NAME,
77 "CreateNamedPipe should fail if name doesn't start with \\\\.\\pipe");
79 hnp = CreateNamedPipe(NULL,
80 PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
81 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL);
82 ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
83 "CreateNamedPipe should fail if name is NULL");
85 hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
86 ok(hFile == INVALID_HANDLE_VALUE
87 && GetLastError() == ERROR_FILE_NOT_FOUND,
88 "connecting to nonexistent named pipe should fail with ERROR_FILE_NOT_FOUND");
90 /* Functional checks */
92 hnp = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
93 /* nMaxInstances */ 1,
94 /* nOutBufSize */ 1024,
95 /* nInBufSize */ 1024,
96 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
97 /* lpSecurityAttrib */ NULL);
98 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed");
100 hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
101 ok(hFile != INVALID_HANDLE_VALUE, "CreateFile failed");
103 /* don't try to do i/o if one side couldn't be opened, as it hangs */
104 if (hFile != INVALID_HANDLE_VALUE) {
107 /* Make sure we can read and write a few bytes in both directions */
108 memset(ibuf, 0, sizeof(ibuf));
109 ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile");
110 ok(written == sizeof(obuf), "write file len");
111 ok(ReadFile(hFile, ibuf, sizeof(obuf), &readden, NULL), "ReadFile");
112 ok(readden == sizeof(obuf), "read file len");
113 ok(memcmp(obuf, ibuf, written) == 0, "content check");
115 memset(ibuf, 0, sizeof(ibuf));
116 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile");
117 ok(written == sizeof(obuf), "write file len");
118 ok(ReadFile(hnp, ibuf, sizeof(obuf), &readden, NULL), "ReadFile");
119 ok(readden == sizeof(obuf), "read file len");
120 ok(memcmp(obuf, ibuf, written) == 0, "content check");
122 /* Picky conformance tests */
124 /* Verify that you can't connect to pipe again
125 * until server calls DisconnectNamedPipe+ConnectNamedPipe
126 * or creates a new pipe
127 * case 1: other client not yet closed
129 hFile2 = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
130 ok(hFile2 == INVALID_HANDLE_VALUE,
131 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail");
132 ok(GetLastError() == ERROR_PIPE_BUSY,
133 "connecting to named pipe before other client closes should fail with ERROR_PIPE_BUSY");
135 ok(CloseHandle(hFile), "CloseHandle");
137 /* case 2: other client already closed */
138 hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
139 ok(hFile == INVALID_HANDLE_VALUE,
140 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail");
141 ok(GetLastError() == ERROR_PIPE_BUSY,
142 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail with ERROR_PIPE_BUSY");
144 ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe");
146 /* case 3: server has called DisconnectNamedPipe but not ConnectNamed Pipe */
147 hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
148 ok(hFile == INVALID_HANDLE_VALUE,
149 "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail");
150 ok(GetLastError() == ERROR_PIPE_BUSY,
151 "connecting to named pipe after other client closes but before ConnectNamedPipe should fail with ERROR_PIPE_BUSY");
153 /* to be complete, we'd call ConnectNamedPipe here and loop,
154 * but by default that's blocking, so we'd either have
155 * to turn on the uncommon nonblocking mode, or
156 * use another thread.
160 ok(CloseHandle(hnp), "CloseHandle");
162 trace("test_CreateNamedPipe returning\n");
165 void test_CreateNamedPipe_instances_must_match(void)
169 /* Check no mismatch */
170 hnp = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
171 /* nMaxInstances */ 2,
172 /* nOutBufSize */ 1024,
173 /* nInBufSize */ 1024,
174 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
175 /* lpSecurityAttrib */ NULL);
176 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed");
178 hnp2 = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
179 /* nMaxInstances */ 2,
180 /* nOutBufSize */ 1024,
181 /* nInBufSize */ 1024,
182 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
183 /* lpSecurityAttrib */ NULL);
184 ok(hnp2 != INVALID_HANDLE_VALUE, "CreateNamedPipe failed");
186 ok(CloseHandle(hnp), "CloseHandle");
187 ok(CloseHandle(hnp2), "CloseHandle");
189 /* Check nMaxInstances */
190 hnp = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
191 /* nMaxInstances */ 1,
192 /* nOutBufSize */ 1024,
193 /* nInBufSize */ 1024,
194 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
195 /* lpSecurityAttrib */ NULL);
196 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed");
198 hnp2 = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
199 /* nMaxInstances */ 1,
200 /* nOutBufSize */ 1024,
201 /* nInBufSize */ 1024,
202 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
203 /* lpSecurityAttrib */ NULL);
204 ok(hnp2 == INVALID_HANDLE_VALUE
205 && GetLastError() == ERROR_PIPE_BUSY, "nMaxInstances not obeyed");
207 ok(CloseHandle(hnp), "CloseHandle");
209 /* Check PIPE_ACCESS_* */
210 hnp = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
211 /* nMaxInstances */ 2,
212 /* nOutBufSize */ 1024,
213 /* nInBufSize */ 1024,
214 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
215 /* lpSecurityAttrib */ NULL);
216 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed");
218 hnp2 = CreateNamedPipe(PIPENAME, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE | PIPE_WAIT,
219 /* nMaxInstances */ 1,
220 /* nOutBufSize */ 1024,
221 /* nInBufSize */ 1024,
222 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
223 /* lpSecurityAttrib */ NULL);
224 ok(hnp2 == INVALID_HANDLE_VALUE
225 && GetLastError() == ERROR_ACCESS_DENIED, "PIPE_ACCESS_* mismatch allowed");
227 ok(CloseHandle(hnp), "CloseHandle");
232 /** implementation of alarm() */
233 static DWORD CALLBACK alarmThreadMain(LPVOID arg)
235 DWORD timeout = (DWORD) arg;
236 trace("alarmThreadMain\n");
243 HANDLE hnp = INVALID_HANDLE_VALUE;
245 /** Trivial byte echo server - disconnects after each session */
246 static DWORD CALLBACK serverThreadMain1(LPVOID arg)
250 trace("serverThreadMain1 start\n");
251 /* Set up a simple echo server */
252 hnp = CreateNamedPipe(PIPENAME "serverThreadMain1", PIPE_ACCESS_DUPLEX,
253 PIPE_TYPE_BYTE | PIPE_WAIT,
254 /* nMaxInstances */ 1,
255 /* nOutBufSize */ 1024,
256 /* nInBufSize */ 1024,
257 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
258 /* lpSecurityAttrib */ NULL);
260 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed");
267 /* Wait for client to connect */
268 trace("Server calling ConnectNamedPipe...\n");
269 ok(ConnectNamedPipe(hnp, NULL)
270 || GetLastError() == ERROR_PIPE_CONNECTED, "ConnectNamedPipe");
271 trace("ConnectNamedPipe returned.\n");
273 /* Echo bytes once */
274 memset(buf, 0, sizeof(buf));
276 trace("Server reading...\n");
277 success = ReadFile(hnp, buf, sizeof(buf), &readden, NULL);
278 trace("Server done reading.\n");
279 ok(success, "ReadFile");
280 ok(readden, "short read");
282 trace("Server writing...\n");
283 ok(WriteFile(hnp, buf, readden, &written, NULL), "WriteFile");
284 trace("Server done writing.\n");
285 ok(written == readden, "write file len");
287 /* finish this connection, wait for next one */
288 ok(FlushFileBuffers(hnp), "FlushFileBuffers");
289 trace("Server done flushing.\n");
290 ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe");
291 trace("Server done disconnecting.\n");
295 /** Trivial byte echo server - closes after each connection */
296 static DWORD CALLBACK serverThreadMain2(LPVOID arg)
301 trace("serverThreadMain2\n");
302 /* Set up a simple echo server */
303 hnp = CreateNamedPipe(PIPENAME "serverThreadMain2", PIPE_ACCESS_DUPLEX,
304 PIPE_TYPE_BYTE | PIPE_WAIT,
305 /* nMaxInstances */ 2,
306 /* nOutBufSize */ 1024,
307 /* nInBufSize */ 1024,
308 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
309 /* lpSecurityAttrib */ NULL);
310 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed");
318 /* Wait for client to connect */
319 trace("Server calling ConnectNamedPipe...\n");
320 ok(ConnectNamedPipe(hnp, NULL)
321 || GetLastError() == ERROR_PIPE_CONNECTED, "ConnectNamedPipe");
322 trace("ConnectNamedPipe returned.\n");
324 /* Echo bytes once */
325 memset(buf, 0, sizeof(buf));
327 trace("Server reading...\n");
328 success = ReadFile(hnp, buf, sizeof(buf), &readden, NULL);
329 trace("Server done reading.\n");
330 ok(success, "ReadFile");
332 trace("Server writing...\n");
333 ok(WriteFile(hnp, buf, readden, &written, NULL), "WriteFile");
334 trace("Server done writing.\n");
335 ok(written == readden, "write file len");
337 /* finish this connection, wait for next one */
338 ok(FlushFileBuffers(hnp), "FlushFileBuffers");
339 ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe");
341 /* Set up next echo server */
343 CreateNamedPipe(PIPENAME "serverThreadMain2", PIPE_ACCESS_DUPLEX,
344 PIPE_TYPE_BYTE | PIPE_WAIT,
345 /* nMaxInstances */ 2,
346 /* nOutBufSize */ 1024,
347 /* nInBufSize */ 1024,
348 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
349 /* lpSecurityAttrib */ NULL);
351 ok(hnpNext != INVALID_HANDLE_VALUE, "CreateNamedPipe failed");
353 ok(CloseHandle(hnp), "CloseHandle");
358 /** Trivial byte echo server - uses overlapped named pipe calls */
359 static DWORD CALLBACK serverThreadMain3(LPVOID arg)
364 trace("serverThreadMain3\n");
365 /* Set up a simple echo server */
366 hnp = CreateNamedPipe(PIPENAME "serverThreadMain3", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
367 PIPE_TYPE_BYTE | PIPE_WAIT,
368 /* nMaxInstances */ 1,
369 /* nOutBufSize */ 1024,
370 /* nInBufSize */ 1024,
371 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
372 /* lpSecurityAttrib */ NULL);
373 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed");
375 hEvent = CreateEvent(NULL, /* security attribute */
376 TRUE, /* manual reset event */
377 FALSE, /* initial state */
379 ok(hEvent != NULL, "CreateEvent");
388 int letWFSOEwait = (i & 2);
389 int letGORwait = (i & 1);
392 memset(&oOverlap, 0, sizeof(oOverlap));
393 oOverlap.hEvent = hEvent;
395 /* Wait for client to connect */
396 trace("Server calling overlapped ConnectNamedPipe...\n");
397 success = ConnectNamedPipe(hnp, &oOverlap);
398 err = GetLastError();
399 ok(success || err == ERROR_IO_PENDING
400 || err == ERROR_PIPE_CONNECTED, "overlapped ConnectNamedPipe");
401 trace("overlapped ConnectNamedPipe returned.\n");
402 if (!success && (err == ERROR_IO_PENDING) && letWFSOEwait)
403 ok(WaitForSingleObjectEx(hEvent, INFINITE, TRUE) == 0, "wait ConnectNamedPipe");
404 success = GetOverlappedResult(hnp, &oOverlap, &dummy, letGORwait);
405 if (!letGORwait && !letWFSOEwait && !success) {
406 ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult");
407 success = GetOverlappedResult(hnp, &oOverlap, &dummy, TRUE);
409 ok(success, "GetOverlappedResult ConnectNamedPipe");
410 trace("overlapped ConnectNamedPipe operation complete.\n");
412 /* Echo bytes once */
413 memset(buf, 0, sizeof(buf));
415 trace("Server reading...\n");
416 success = ReadFile(hnp, buf, sizeof(buf), NULL, &oOverlap);
417 trace("Server ReadFile returned...\n");
418 err = GetLastError();
419 ok(success || err == ERROR_IO_PENDING, "overlapped ReadFile");
420 trace("overlapped ReadFile returned.\n");
421 if (!success && (err == ERROR_IO_PENDING) && letWFSOEwait)
422 ok(WaitForSingleObjectEx(hEvent, INFINITE, TRUE) == 0, "wait ReadFile");
423 success = GetOverlappedResult(hnp, &oOverlap, &readden, letGORwait);
424 if (!letGORwait && !letWFSOEwait && !success) {
425 ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult");
426 success = GetOverlappedResult(hnp, &oOverlap, &readden, TRUE);
428 trace("Server done reading.\n");
429 ok(success, "overlapped ReadFile");
431 trace("Server writing...\n");
432 success = WriteFile(hnp, buf, readden, NULL, &oOverlap);
433 trace("Server WriteFile returned...\n");
434 err = GetLastError();
435 ok(success || err == ERROR_IO_PENDING, "overlapped WriteFile");
436 trace("overlapped WriteFile returned.\n");
437 if (!success && (err == ERROR_IO_PENDING) && letWFSOEwait)
438 ok(WaitForSingleObjectEx(hEvent, INFINITE, TRUE) == 0, "wait WriteFile");
439 success = GetOverlappedResult(hnp, &oOverlap, &written, letGORwait);
440 if (!letGORwait && !letWFSOEwait && !success) {
441 ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult");
442 success = GetOverlappedResult(hnp, &oOverlap, &written, TRUE);
444 trace("Server done writing.\n");
445 ok(success, "overlapped WriteFile");
446 ok(written == readden, "write file len");
448 /* finish this connection, wait for next one */
449 ok(FlushFileBuffers(hnp), "FlushFileBuffers");
450 ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe");
454 static void exercizeServer(const char *pipename, HANDLE serverThread)
458 trace("exercizeServer starting\n");
459 for (i = 0; i < 8; i++) {
460 HANDLE hFile=INVALID_HANDLE_VALUE;
461 const char obuf[] = "Bit Bucket";
467 for (loop = 0; loop < 3; loop++) {
469 trace("Client connecting...\n");
470 /* Connect to the server */
471 hFile = CreateFileA(pipename, GENERIC_READ | GENERIC_WRITE, 0,
472 NULL, OPEN_EXISTING, 0, 0);
473 if (hFile != INVALID_HANDLE_VALUE)
475 err = GetLastError();
477 ok(err == ERROR_PIPE_BUSY || err == ERROR_FILE_NOT_FOUND, "connecting to pipe");
479 ok(err == ERROR_PIPE_BUSY, "connecting to pipe");
480 trace("connect failed, retrying\n");
483 ok(hFile != INVALID_HANDLE_VALUE, "client opening named pipe");
485 /* Make sure it can echo */
486 memset(ibuf, 0, sizeof(ibuf));
487 trace("Client writing...\n");
488 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile to client end of pipe");
489 ok(written == sizeof(obuf), "write file len");
490 trace("Client reading...\n");
491 ok(ReadFile(hFile, ibuf, sizeof(obuf), &readden, NULL), "ReadFile from client end of pipe");
492 ok(readden == sizeof(obuf), "read file len");
493 ok(memcmp(obuf, ibuf, written) == 0, "content check");
495 trace("Client closing...\n");
496 ok(CloseHandle(hFile), "CloseHandle");
499 ok(TerminateThread(serverThread, 0), "TerminateThread");
501 trace("exercizeServer returning\n");
504 void test_NamedPipe_2(void)
507 DWORD serverThreadId;
511 trace("test_NamedPipe_2 starting\n");
512 /* Set up a ten second timeout */
513 alarmThread = CreateThread(NULL, 0, alarmThreadMain, (void *) 10000, 0, &alarmThreadId);
515 /* The servers we're about to exercize do try to clean up carefully,
516 * but to reduce the change of a test failure due to a pipe handle
517 * leak in the test code, we'll use a different pipe name for each server.
521 serverThread = CreateThread(NULL, 0, serverThreadMain1, 0, 0, &serverThreadId);
522 ok(serverThread != INVALID_HANDLE_VALUE, "CreateThread");
523 exercizeServer(PIPENAME "serverThreadMain1", serverThread);
526 serverThread = CreateThread(NULL, 0, serverThreadMain2, 0, 0, &serverThreadId);
527 ok(serverThread != INVALID_HANDLE_VALUE, "CreateThread");
528 exercizeServer(PIPENAME "serverThreadMain2", serverThread);
530 if( 0 ) /* overlapped pipe server doesn't work yet - it randomly fails */
533 serverThread = CreateThread(NULL, 0, serverThreadMain3, 0, 0, &serverThreadId);
534 ok(serverThread != INVALID_HANDLE_VALUE, "CreateThread");
535 exercizeServer(PIPENAME "serverThreadMain3", serverThread);
538 ok(TerminateThread(alarmThread, 0), "TerminateThread");
539 trace("test_NamedPipe_2 returning\n");
542 void test_DisconnectNamedPipe(void)
546 const char obuf[] = "Bit Bucket";
551 hnp = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
552 /* nMaxInstances */ 1,
553 /* nOutBufSize */ 1024,
554 /* nInBufSize */ 1024,
555 /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
556 /* lpSecurityAttrib */ NULL);
557 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed");
559 ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL) == 0
560 && GetLastError() == ERROR_PIPE_LISTENING, "WriteFile to not-yet-connected pipe");
561 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL) == 0
562 && GetLastError() == ERROR_PIPE_LISTENING, "ReadFile from not-yet-connected pipe");
564 hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
565 ok(hFile != INVALID_HANDLE_VALUE, "CreateFile failed");
567 /* don't try to do i/o if one side couldn't be opened, as it hangs */
568 if (hFile != INVALID_HANDLE_VALUE) {
570 /* see what happens if server calls DisconnectNamedPipe
571 * when there are bytes in the pipe
574 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile");
575 ok(written == sizeof(obuf), "write file len");
576 ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe while messages waiting");
577 ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL) == 0
578 && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "WriteFile to disconnected pipe");
579 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL) == 0
580 && GetLastError() == ERROR_PIPE_NOT_CONNECTED,
581 "ReadFile from disconnected pipe with bytes waiting");
582 ok(CloseHandle(hFile), "CloseHandle");
585 ok(CloseHandle(hnp), "CloseHandle");
591 trace("test 1 of 4:\n");
592 test_DisconnectNamedPipe();
593 trace("test 2 of 4:\n");
594 test_CreateNamedPipe_instances_must_match();
595 trace("test 3 of 4:\n");
597 trace("test 4 of 4:\n");
598 test_CreateNamedPipe();
599 trace("all tests done\n");