(file) Return to wsock32_main.c CVS log (file) (dir) Up to [RizwankCVS] / wine4 / wine / dlls / wsock32 / tests

  1 rizwank 1.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 19              */
 20             
 21             #include <assert.h>
 22 rizwank 1.1 #include <stdarg.h>
 23             #include <stdlib.h>
 24             #include <stdio.h>
 25             #include <time.h>
 26             
 27             #include <windef.h>
 28             #include <winbase.h>
 29             #include <winsock.h>
 30             
 31             #ifndef STANDALONE
 32             #include "wine/test.h"
 33             #else
 34             #include <assert.h>
 35             #define START_TEST(name) main(int argc, char **argv)
 36             #define ok(condition, msg) \
 37             	do { \
 38             		if(!(condition)) \
 39             		{ \
 40             			fprintf(stderr,"failed at %d\n",__LINE__); \
 41             			exit(0); \
 42             		} \
 43 rizwank 1.1 	} while(0)
 44             
 45             #define todo_wine
 46             #endif
 47             
 48             #include <wtypes.h>
 49             #include <winerror.h>
 50             
 51             #define PIPENAME "\\\\.\\PiPe\\tests_pipe.c"
 52             
 53             #define NB_SERVER_LOOPS 8
 54             
 55             static HANDLE alarm_event;
 56             
 57             static void test_CreateNamedPipe(int pipemode)
 58             {
 59                 HANDLE hnp;
 60                 HANDLE hFile;
 61                 static const char obuf[] = "Bit Bucket";
 62                 static const char obuf2[] = "More bits";
 63                 char ibuf[32], *pbuf;
 64 rizwank 1.1     DWORD written;
 65                 DWORD readden;
 66                 DWORD avail;
 67                 DWORD lpmode;
 68             
 69                 if (pipemode == PIPE_TYPE_BYTE)
 70                     trace("test_CreateNamedPipe starting in byte mode\n");
 71                 else
 72                     trace("test_CreateNamedPipe starting in message mode\n");
 73                 /* Bad parameter checks */
 74                 hnp = CreateNamedPipe("not a named pipe", PIPE_ACCESS_DUPLEX, pipemode | PIPE_WAIT,
 75                     /* nMaxInstances */ 1,
 76                     /* nOutBufSize */ 1024,
 77                     /* nInBufSize */ 1024,
 78                     /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
 79                     /* lpSecurityAttrib */ NULL);
 80             
 81                 if (hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) {
 82                     /* Is this the right way to notify user of skipped tests? */
 83                     ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED,
 84                         "CreateNamedPipe not supported on this platform, skipping tests.\n");
 85 rizwank 1.1         return;
 86                 }
 87                 ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_NAME,
 88                     "CreateNamedPipe should fail if name doesn't start with \\\\.\\pipe\n");
 89             
 90                 hnp = CreateNamedPipe(NULL,
 91                     PIPE_ACCESS_DUPLEX, pipemode | PIPE_WAIT,
 92                     1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL);
 93                 ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
 94                     "CreateNamedPipe should fail if name is NULL\n");
 95             
 96                 hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
 97                 ok(hFile == INVALID_HANDLE_VALUE
 98                     && GetLastError() == ERROR_FILE_NOT_FOUND,
 99                     "connecting to nonexistent named pipe should fail with ERROR_FILE_NOT_FOUND\n");
100             
101                 /* Functional checks */
102             
103                 hnp = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, pipemode | PIPE_WAIT,
104                     /* nMaxInstances */ 1,
105                     /* nOutBufSize */ 1024,
106 rizwank 1.1         /* nInBufSize */ 1024,
107                     /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
108                     /* lpSecurityAttrib */ NULL);
109                 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
110             
111                 hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
112                 ok(hFile != INVALID_HANDLE_VALUE, "CreateFile failed\n");
113             
114                 /* don't try to do i/o if one side couldn't be opened, as it hangs */
115                 if (hFile != INVALID_HANDLE_VALUE) {
116                     HANDLE hFile2;
117             
118                     /* Make sure we can read and write a few bytes in both directions */
119                     memset(ibuf, 0, sizeof(ibuf));
120                     ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile\n");
121                     ok(written == sizeof(obuf), "write file len 1\n");
122                     ok(PeekNamedPipe(hFile, NULL, 0, NULL, &readden, NULL), "Peek\n");
123                     ok(readden == sizeof(obuf), "peek 1 got %ld bytes\n", readden);
124                     ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
125                     ok(readden == sizeof(obuf), "read 1 got %ld bytes\n", readden);
126                     ok(memcmp(obuf, ibuf, written) == 0, "content 1 check\n");
127 rizwank 1.1 
128                     memset(ibuf, 0, sizeof(ibuf));
129                     ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), "WriteFile\n");
130                     ok(written == sizeof(obuf2), "write file len 2\n");
131                     ok(PeekNamedPipe(hnp, NULL, 0, NULL, &readden, NULL), "Peek\n");
132                     ok(readden == sizeof(obuf2), "peek 2 got %ld bytes\n", readden);
133                     ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
134                     ok(readden == sizeof(obuf2), "read 2 got %ld bytes\n", readden);
135                     ok(memcmp(obuf2, ibuf, written) == 0, "content 2 check\n");
136             
137                     /* Test reading of multiple writes */
138                     memset(ibuf, 0, sizeof(ibuf));
139                     ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile3a\n");
140                     ok(written == sizeof(obuf), "write file len 3a\n");
141                     ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), " WriteFile3b\n");
142                     ok(written == sizeof(obuf2), "write file len 3b\n");
143                     ok(PeekNamedPipe(hFile, ibuf, sizeof(ibuf), &readden, &avail, NULL), "Peek3\n");
144                     if (pipemode == PIPE_TYPE_BYTE) {
145                         todo_wine {
146                             /* should return all 23 bytes */
147                             ok(readden == sizeof(obuf) + sizeof(obuf2), "peek3 got %ld bytes\n", readden);
148 rizwank 1.1             }
149                     }
150                     else
151                         ok(readden == sizeof(obuf), "peek3 got %ld bytes\n", readden);
152                     todo_wine {
153                         ok(avail == sizeof(obuf) + sizeof(obuf2), "peek3 got %ld bytes available\n", avail);
154                     }
155                     pbuf = ibuf;
156                     ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "pipe content 3a check\n");
157                     if (pipemode == PIPE_TYPE_BYTE) {
158                         todo_wine {
159                             pbuf += sizeof(obuf);
160                             ok(memcmp(obuf2, pbuf, sizeof(obuf2)) == 0, "pipe content 3b check\n");
161                         }
162                     }
163                     ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
164                     ok(readden == sizeof(obuf) + sizeof(obuf2), "read 3 got %ld bytes\n", readden);
165                     pbuf = ibuf;
166                     ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 3a check\n");
167                     pbuf += sizeof(obuf);
168                     ok(memcmp(obuf2, pbuf, sizeof(obuf2)) == 0, "content 3b check\n");
169 rizwank 1.1 
170                     /* Multiple writes in the reverse direction */
171                     memset(ibuf, 0, sizeof(ibuf));
172                     ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile4a\n");
173                     ok(written == sizeof(obuf), "write file len 4a\n");
174                     ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), " WriteFile4b\n");
175                     ok(written == sizeof(obuf2), "write file len 4b\n");
176                     ok(PeekNamedPipe(hnp, ibuf, sizeof(ibuf), &readden, &avail, NULL), "Peek4\n");
177                     if (pipemode == PIPE_TYPE_BYTE) {
178                         todo_wine {
179                             /* should return all 23 bytes */
180                             ok(readden == sizeof(obuf) + sizeof(obuf2), "peek4 got %ld bytes\n", readden);
181                         }
182                     }
183                     else
184                         ok(readden == sizeof(obuf), "peek4 got %ld bytes\n", readden);
185                     todo_wine {
186                         ok(avail == sizeof(obuf) + sizeof(obuf2), "peek4 got %ld bytes available\n", avail);
187                     }
188                     pbuf = ibuf;
189                     ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "pipe content 4a check\n");
190 rizwank 1.1         if (pipemode == PIPE_TYPE_BYTE) {
191                         todo_wine {
192                             pbuf += sizeof(obuf);
193                             ok(memcmp(obuf2, pbuf, sizeof(obuf2)) == 0, "pipe content 4b check\n");
194                         }
195                     }
196                     ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
197                     if (pipemode == PIPE_TYPE_BYTE) {
198                         ok(readden == sizeof(obuf) + sizeof(obuf2), "read 4 got %ld bytes\n", readden);
199                     }
200                     else {
201                         todo_wine {
202                             ok(readden == sizeof(obuf), "read 4 got %ld bytes\n", readden);
203                         }
204                     }
205                     pbuf = ibuf;
206                     ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 4a check\n");
207                     if (pipemode == PIPE_TYPE_BYTE) {
208                         pbuf += sizeof(obuf);
209                         ok(memcmp(obuf2, pbuf, sizeof(obuf2)) == 0, "content 4b check\n");
210                     }
211 rizwank 1.1 
212                     /* Test reading of multiple writes after a mode change
213                       (CreateFile always creates a byte mode pipe) */
214                     lpmode = PIPE_READMODE_MESSAGE;
215                     if (pipemode == PIPE_TYPE_BYTE) {
216                         /* trying to change the client end of a byte pipe to message mode should fail */
217                         ok(!SetNamedPipeHandleState(hFile, &lpmode, NULL, NULL), "Change mode\n");
218                     }
219                     else {
220                         todo_wine {
221                             ok(SetNamedPipeHandleState(hFile, &lpmode, NULL, NULL), "Change mode\n");
222                         }
223                     
224                         memset(ibuf, 0, sizeof(ibuf));
225                         ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile5a\n");
226                         ok(written == sizeof(obuf), "write file len 3a\n");
227                         ok(WriteFile(hnp, obuf2, sizeof(obuf2), &written, NULL), " WriteFile5b\n");
228                         ok(written == sizeof(obuf2), "write file len 3b\n");
229                         ok(PeekNamedPipe(hFile, ibuf, sizeof(ibuf), &readden, &avail, NULL), "Peek5\n");
230                         ok(readden == sizeof(obuf), "peek5 got %ld bytes\n", readden);
231                         todo_wine {
232 rizwank 1.1                 ok(avail == sizeof(obuf) + sizeof(obuf2), "peek5 got %ld bytes available\n", avail);
233                         }
234                         pbuf = ibuf;
235                         ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 5a check\n");
236                         ok(ReadFile(hFile, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
237                         todo_wine {
238                             ok(readden == sizeof(obuf), "read 5 got %ld bytes\n", readden);
239                         }
240                         pbuf = ibuf;
241                         ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 5a check\n");
242                 
243                         /* Multiple writes in the reverse direction */
244                         /* the write of obuf2 from write4 should still be in the buffer */
245                         ok(PeekNamedPipe(hnp, ibuf, sizeof(ibuf), &readden, &avail, NULL), "Peek6a\n");
246                         todo_wine {
247                             ok(readden == sizeof(obuf2), "peek6a got %ld bytes\n", readden);
248                             ok(avail == sizeof(obuf2), "peek6a got %ld bytes available\n", avail);
249                         }
250                         if (avail > 0) {
251                             ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
252                             ok(readden == sizeof(obuf2), "read 6a got %ld bytes\n", readden);
253 rizwank 1.1                 pbuf = ibuf;
254                             ok(memcmp(obuf2, pbuf, sizeof(obuf2)) == 0, "content 6a check\n");
255                         }
256                         memset(ibuf, 0, sizeof(ibuf));
257                         ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile6a\n");
258                         ok(written == sizeof(obuf), "write file len 6a\n");
259                         ok(WriteFile(hFile, obuf2, sizeof(obuf2), &written, NULL), " WriteFile6b\n");
260                         ok(written == sizeof(obuf2), "write file len 6b\n");
261                         ok(PeekNamedPipe(hnp, ibuf, sizeof(ibuf), &readden, &avail, NULL), "Peek6\n");
262                         ok(readden == sizeof(obuf), "peek6 got %ld bytes\n", readden);
263                         todo_wine {
264                             ok(avail == sizeof(obuf) + sizeof(obuf2), "peek6b got %ld bytes available\n", avail);
265                         }
266                         pbuf = ibuf;
267                         ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 6a check\n");
268                         ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL), "ReadFile\n");
269                         todo_wine {
270                             ok(readden == sizeof(obuf), "read 6b got %ld bytes\n", readden);
271                         }
272                         pbuf = ibuf;
273                         ok(memcmp(obuf, pbuf, sizeof(obuf)) == 0, "content 6a check\n");
274 rizwank 1.1         }
275             
276                     /* Picky conformance tests */
277             
278                     /* Verify that you can't connect to pipe again
279                      * until server calls DisconnectNamedPipe+ConnectNamedPipe
280                      * or creates a new pipe
281                      * case 1: other client not yet closed
282                      */
283                     hFile2 = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
284                     ok(hFile2 == INVALID_HANDLE_VALUE,
285                         "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n");
286                     ok(GetLastError() == ERROR_PIPE_BUSY,
287                         "connecting to named pipe before other client closes should fail with ERROR_PIPE_BUSY\n");
288             
289                     ok(CloseHandle(hFile), "CloseHandle\n");
290             
291                     /* case 2: other client already closed */
292                     hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
293                     ok(hFile == INVALID_HANDLE_VALUE,
294                         "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n");
295 rizwank 1.1         ok(GetLastError() == ERROR_PIPE_BUSY,
296                         "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail with ERROR_PIPE_BUSY\n");
297             
298                     ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n");
299             
300                     /* case 3: server has called DisconnectNamedPipe but not ConnectNamed Pipe */
301                     hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
302                     ok(hFile == INVALID_HANDLE_VALUE,
303                         "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail\n");
304                     ok(GetLastError() == ERROR_PIPE_BUSY,
305                         "connecting to named pipe after other client closes but before ConnectNamedPipe should fail with ERROR_PIPE_BUSY\n");
306             
307                     /* to be complete, we'd call ConnectNamedPipe here and loop,
308                      * but by default that's blocking, so we'd either have
309                      * to turn on the uncommon nonblocking mode, or
310                      * use another thread.
311                      */
312                 }
313             
314                 ok(CloseHandle(hnp), "CloseHandle\n");
315             
316 rizwank 1.1     trace("test_CreateNamedPipe returning\n");
317             }
318             
319             void test_CreateNamedPipe_instances_must_match(void)
320             {
321                 HANDLE hnp, hnp2;
322             
323                 /* Check no mismatch */
324                 hnp = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
325                     /* nMaxInstances */ 2,
326                     /* nOutBufSize */ 1024,
327                     /* nInBufSize */ 1024,
328                     /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
329                     /* lpSecurityAttrib */ NULL);
330                 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
331             
332                 hnp2 = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
333                     /* nMaxInstances */ 2,
334                     /* nOutBufSize */ 1024,
335                     /* nInBufSize */ 1024,
336                     /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
337 rizwank 1.1         /* lpSecurityAttrib */ NULL);
338                 ok(hnp2 != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
339             
340                 ok(CloseHandle(hnp), "CloseHandle\n");
341                 ok(CloseHandle(hnp2), "CloseHandle\n");
342             
343                 /* Check nMaxInstances */
344                 hnp = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
345                     /* nMaxInstances */ 1,
346                     /* nOutBufSize */ 1024,
347                     /* nInBufSize */ 1024,
348                     /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
349                     /* lpSecurityAttrib */ NULL);
350                 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
351             
352                 hnp2 = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
353                     /* nMaxInstances */ 1,
354                     /* nOutBufSize */ 1024,
355                     /* nInBufSize */ 1024,
356                     /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
357                     /* lpSecurityAttrib */ NULL);
358 rizwank 1.1     ok(hnp2 == INVALID_HANDLE_VALUE
359                     && GetLastError() == ERROR_PIPE_BUSY, "nMaxInstances not obeyed\n");
360             
361                 ok(CloseHandle(hnp), "CloseHandle\n");
362             
363                 /* Check PIPE_ACCESS_* */
364                 hnp = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
365                     /* nMaxInstances */ 2,
366                     /* nOutBufSize */ 1024,
367                     /* nInBufSize */ 1024,
368                     /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
369                     /* lpSecurityAttrib */ NULL);
370                 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
371             
372                 hnp2 = CreateNamedPipe(PIPENAME, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE | PIPE_WAIT,
373                     /* nMaxInstances */ 1,
374                     /* nOutBufSize */ 1024,
375                     /* nInBufSize */ 1024,
376                     /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
377                     /* lpSecurityAttrib */ NULL);
378                 ok(hnp2 == INVALID_HANDLE_VALUE
379 rizwank 1.1         && GetLastError() == ERROR_ACCESS_DENIED, "PIPE_ACCESS_* mismatch allowed\n");
380             
381                 ok(CloseHandle(hnp), "CloseHandle\n");
382             
383                 /* etc, etc */
384             }
385             
386             /** implementation of alarm() */
387             static DWORD CALLBACK alarmThreadMain(LPVOID arg)
388             {
389                 DWORD timeout = (DWORD) arg;
390                 trace("alarmThreadMain\n");
391                 if (WaitForSingleObject( alarm_event, timeout ) == WAIT_TIMEOUT)
392                 {
393                     ok(FALSE, "alarm\n");
394                     ExitProcess(1);
395                 }
396                 return 1;
397             }
398             
399             HANDLE hnp = INVALID_HANDLE_VALUE;
400 rizwank 1.1 
401             /** Trivial byte echo server - disconnects after each session */
402             static DWORD CALLBACK serverThreadMain1(LPVOID arg)
403             {
404                 int i;
405             
406                 trace("serverThreadMain1 start\n");
407                 /* Set up a simple echo server */
408                 hnp = CreateNamedPipe(PIPENAME "serverThreadMain1", PIPE_ACCESS_DUPLEX,
409                     PIPE_TYPE_BYTE | PIPE_WAIT,
410                     /* nMaxInstances */ 1,
411                     /* nOutBufSize */ 1024,
412                     /* nInBufSize */ 1024,
413                     /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
414                     /* lpSecurityAttrib */ NULL);
415             
416                 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
417                 for (i = 0; i < NB_SERVER_LOOPS; i++) {
418                     char buf[512];
419                     DWORD written;
420                     DWORD readden;
421 rizwank 1.1         DWORD success;
422             
423                     /* Wait for client to connect */
424                     trace("Server calling ConnectNamedPipe...\n");
425                     ok(ConnectNamedPipe(hnp, NULL)
426                         || GetLastError() == ERROR_PIPE_CONNECTED, "ConnectNamedPipe\n");
427                     trace("ConnectNamedPipe returned.\n");
428             
429                     /* Echo bytes once */
430                     memset(buf, 0, sizeof(buf));
431             
432                     trace("Server reading...\n");
433                     success = ReadFile(hnp, buf, sizeof(buf), &readden, NULL);
434                     trace("Server done reading.\n");
435                     ok(success, "ReadFile\n");
436                     ok(readden, "short read\n");
437             
438                     trace("Server writing...\n");
439                     ok(WriteFile(hnp, buf, readden, &written, NULL), "WriteFile\n");
440                     trace("Server done writing.\n");
441                     ok(written == readden, "write file len\n");
442 rizwank 1.1 
443                     /* finish this connection, wait for next one */
444                     ok(FlushFileBuffers(hnp), "FlushFileBuffers\n");
445                     trace("Server done flushing.\n");
446                     ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n");
447                     trace("Server done disconnecting.\n");
448                 }
449                 return 0;
450             }
451             
452             /** Trivial byte echo server - closes after each connection */
453             static DWORD CALLBACK serverThreadMain2(LPVOID arg)
454             {
455                 int i;
456                 HANDLE hnpNext = 0;
457             
458                 trace("serverThreadMain2\n");
459                 /* Set up a simple echo server */
460                 hnp = CreateNamedPipe(PIPENAME "serverThreadMain2", PIPE_ACCESS_DUPLEX,
461                     PIPE_TYPE_BYTE | PIPE_WAIT,
462                     /* nMaxInstances */ 2,
463 rizwank 1.1         /* nOutBufSize */ 1024,
464                     /* nInBufSize */ 1024,
465                     /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
466                     /* lpSecurityAttrib */ NULL);
467                 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
468             
469                 for (i = 0; i < NB_SERVER_LOOPS; i++) {
470                     char buf[512];
471                     DWORD written;
472                     DWORD readden;
473                     DWORD success;
474             
475                     /* Wait for client to connect */
476                     trace("Server calling ConnectNamedPipe...\n");
477                     ok(ConnectNamedPipe(hnp, NULL)
478                         || GetLastError() == ERROR_PIPE_CONNECTED, "ConnectNamedPipe\n");
479                     trace("ConnectNamedPipe returned.\n");
480             
481                     /* Echo bytes once */
482                     memset(buf, 0, sizeof(buf));
483             
484 rizwank 1.1         trace("Server reading...\n");
485                     success = ReadFile(hnp, buf, sizeof(buf), &readden, NULL);
486                     trace("Server done reading.\n");
487                     ok(success, "ReadFile\n");
488             
489                     trace("Server writing...\n");
490                     ok(WriteFile(hnp, buf, readden, &written, NULL), "WriteFile\n");
491                     trace("Server done writing.\n");
492                     ok(written == readden, "write file len\n");
493             
494                     /* finish this connection, wait for next one */
495                     ok(FlushFileBuffers(hnp), "FlushFileBuffers\n");
496                     ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n");
497             
498                     /* Set up next echo server */
499                     hnpNext =
500                         CreateNamedPipe(PIPENAME "serverThreadMain2", PIPE_ACCESS_DUPLEX,
501                         PIPE_TYPE_BYTE | PIPE_WAIT,
502                         /* nMaxInstances */ 2,
503                         /* nOutBufSize */ 1024,
504                         /* nInBufSize */ 1024,
505 rizwank 1.1             /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
506                         /* lpSecurityAttrib */ NULL);
507             
508                     ok(hnpNext != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
509             
510                     ok(CloseHandle(hnp), "CloseHandle\n");
511                     hnp = hnpNext;
512                 }
513                 return 0;
514             }
515             
516             /** Trivial byte echo server - uses overlapped named pipe calls */
517             static DWORD CALLBACK serverThreadMain3(LPVOID arg)
518             {
519                 int i;
520                 HANDLE hEvent;
521             
522                 trace("serverThreadMain3\n");
523                 /* Set up a simple echo server */
524                 hnp = CreateNamedPipe(PIPENAME "serverThreadMain3", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
525                     PIPE_TYPE_BYTE | PIPE_WAIT,
526 rizwank 1.1         /* nMaxInstances */ 1,
527                     /* nOutBufSize */ 1024,
528                     /* nInBufSize */ 1024,
529                     /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
530                     /* lpSecurityAttrib */ NULL);
531                 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
532             
533                 hEvent = CreateEvent(NULL,  /* security attribute */
534                     TRUE,                   /* manual reset event */
535                     FALSE,                  /* initial state */
536                     NULL);                  /* name */
537                 ok(hEvent != NULL, "CreateEvent\n");
538             
539                 for (i = 0; i < NB_SERVER_LOOPS; i++) {
540                     char buf[512];
541                     DWORD written;
542                     DWORD readden;
543                     DWORD dummy;
544                     DWORD success;
545                     OVERLAPPED oOverlap;
546                     int letWFSOEwait = (i & 2);
547 rizwank 1.1         int letGORwait = (i & 1);
548             	DWORD err;
549             
550                     memset(&oOverlap, 0, sizeof(oOverlap));
551                     oOverlap.hEvent = hEvent;
552             
553                     /* Wait for client to connect */
554                     trace("Server calling overlapped ConnectNamedPipe...\n");
555                     success = ConnectNamedPipe(hnp, &oOverlap);
556                     err = GetLastError();
557                     ok(success || err == ERROR_IO_PENDING
558                         || err == ERROR_PIPE_CONNECTED, "overlapped ConnectNamedPipe\n");
559                     trace("overlapped ConnectNamedPipe returned.\n");
560                     if (!success && (err == ERROR_IO_PENDING) && letWFSOEwait)
561                         ok(WaitForSingleObjectEx(hEvent, INFINITE, TRUE) == 0, "wait ConnectNamedPipe\n");
562                     success = GetOverlappedResult(hnp, &oOverlap, &dummy, letGORwait);
563             	if (!letGORwait && !letWFSOEwait && !success) {
564             	    ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult\n");
565             	    success = GetOverlappedResult(hnp, &oOverlap, &dummy, TRUE);
566             	}
567             	ok(success, "GetOverlappedResult ConnectNamedPipe\n");
568 rizwank 1.1         trace("overlapped ConnectNamedPipe operation complete.\n");
569             
570                     /* Echo bytes once */
571                     memset(buf, 0, sizeof(buf));
572             
573                     trace("Server reading...\n");
574                     success = ReadFile(hnp, buf, sizeof(buf), NULL, &oOverlap);
575                     trace("Server ReadFile returned...\n");
576                     err = GetLastError();
577                     ok(success || err == ERROR_IO_PENDING, "overlapped ReadFile\n");
578                     trace("overlapped ReadFile returned.\n");
579                     if (!success && (err == ERROR_IO_PENDING) && letWFSOEwait)
580                         ok(WaitForSingleObjectEx(hEvent, INFINITE, TRUE) == 0, "wait ReadFile\n");
581                     success = GetOverlappedResult(hnp, &oOverlap, &readden, letGORwait);
582             	if (!letGORwait && !letWFSOEwait && !success) {
583             	    ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult\n");
584             	    success = GetOverlappedResult(hnp, &oOverlap, &readden, TRUE);
585             	}
586                     trace("Server done reading.\n");
587                     ok(success, "overlapped ReadFile\n");
588             
589 rizwank 1.1         trace("Server writing...\n");
590                     success = WriteFile(hnp, buf, readden, NULL, &oOverlap);
591                     trace("Server WriteFile returned...\n");
592                     err = GetLastError();
593                     ok(success || err == ERROR_IO_PENDING, "overlapped WriteFile\n");
594                     trace("overlapped WriteFile returned.\n");
595                     if (!success && (err == ERROR_IO_PENDING) && letWFSOEwait)
596                         ok(WaitForSingleObjectEx(hEvent, INFINITE, TRUE) == 0, "wait WriteFile\n");
597                     success = GetOverlappedResult(hnp, &oOverlap, &written, letGORwait);
598             	if (!letGORwait && !letWFSOEwait && !success) {
599             	    ok(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult\n");
600             	    success = GetOverlappedResult(hnp, &oOverlap, &written, TRUE);
601             	}
602                     trace("Server done writing.\n");
603                     ok(success, "overlapped WriteFile\n");
604                     ok(written == readden, "write file len\n");
605             
606                     /* finish this connection, wait for next one */
607                     ok(FlushFileBuffers(hnp), "FlushFileBuffers\n");
608                     ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe\n");
609                 }
610 rizwank 1.1     return 0;
611             }
612             
613             static void exercizeServer(const char *pipename, HANDLE serverThread)
614             {
615                 int i;
616             
617                 trace("exercizeServer starting\n");
618                 for (i = 0; i < NB_SERVER_LOOPS; i++) {
619                     HANDLE hFile=INVALID_HANDLE_VALUE;
620                     static const char obuf[] = "Bit Bucket";
621                     char ibuf[32];
622                     DWORD written;
623                     DWORD readden;
624                     int loop;
625             
626                     for (loop = 0; loop < 3; loop++) {
627             	    DWORD err;
628                         trace("Client connecting...\n");
629                         /* Connect to the server */
630                         hFile = CreateFileA(pipename, GENERIC_READ | GENERIC_WRITE, 0,
631 rizwank 1.1                 NULL, OPEN_EXISTING, 0, 0);
632                         if (hFile != INVALID_HANDLE_VALUE)
633                             break;
634             	    err = GetLastError();
635             	    if (loop == 0)
636             	        ok(err == ERROR_PIPE_BUSY || err == ERROR_FILE_NOT_FOUND, "connecting to pipe\n");
637             	    else
638             	        ok(err == ERROR_PIPE_BUSY, "connecting to pipe\n");
639                         trace("connect failed, retrying\n");
640                         Sleep(200);
641                     }
642                     ok(hFile != INVALID_HANDLE_VALUE, "client opening named pipe\n");
643             
644                     /* Make sure it can echo */
645                     memset(ibuf, 0, sizeof(ibuf));
646                     trace("Client writing...\n");
647                     ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile to client end of pipe\n");
648                     ok(written == sizeof(obuf), "write file len\n");
649                     trace("Client reading...\n");
650                     ok(ReadFile(hFile, ibuf, sizeof(obuf), &readden, NULL), "ReadFile from client end of pipe\n");
651                     ok(readden == sizeof(obuf), "read file len\n");
652 rizwank 1.1         ok(memcmp(obuf, ibuf, written) == 0, "content check\n");
653             
654                     trace("Client closing...\n");
655                     ok(CloseHandle(hFile), "CloseHandle\n");
656                 }
657             
658                 ok(WaitForSingleObject(serverThread,INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject\n");
659                 CloseHandle(hnp);
660                 trace("exercizeServer returning\n");
661             }
662             
663             static void test_NamedPipe_2(void)
664             {
665                 HANDLE serverThread;
666                 DWORD serverThreadId;
667                 HANDLE alarmThread;
668                 DWORD alarmThreadId;
669             
670                 trace("test_NamedPipe_2 starting\n");
671                 /* Set up a ten second timeout */
672                 alarm_event = CreateEvent( NULL, TRUE, FALSE, NULL );
673 rizwank 1.1     alarmThread = CreateThread(NULL, 0, alarmThreadMain, (void *) 10000, 0, &alarmThreadId);
674             
675                 /* The servers we're about to exercize do try to clean up carefully,
676                  * but to reduce the change of a test failure due to a pipe handle
677                  * leak in the test code, we'll use a different pipe name for each server.
678                  */
679             
680                 /* Try server #1 */
681                 serverThread = CreateThread(NULL, 0, serverThreadMain1, (void *)8, 0, &serverThreadId);
682                 ok(serverThread != INVALID_HANDLE_VALUE, "CreateThread\n");
683                 exercizeServer(PIPENAME "serverThreadMain1", serverThread);
684             
685                 /* Try server #2 */
686                 serverThread = CreateThread(NULL, 0, serverThreadMain2, 0, 0, &serverThreadId);
687                 ok(serverThread != INVALID_HANDLE_VALUE, "CreateThread\n");
688                 exercizeServer(PIPENAME "serverThreadMain2", serverThread);
689             
690                 if( 0 ) /* overlapped pipe server doesn't work yet - it randomly fails */
691                 {
692                 /* Try server #3 */
693                 serverThread = CreateThread(NULL, 0, serverThreadMain3, 0, 0, &serverThreadId);
694 rizwank 1.1     ok(serverThread != INVALID_HANDLE_VALUE, "CreateThread\n");
695                 exercizeServer(PIPENAME "serverThreadMain3", serverThread);
696                 }
697             
698                 ok(SetEvent( alarm_event ), "SetEvent\n");
699                 CloseHandle( alarm_event );
700                 trace("test_NamedPipe_2 returning\n");
701             }
702             
703             static void test_DisconnectNamedPipe(void)
704             {
705                 HANDLE hnp;
706                 HANDLE hFile;
707                 static const char obuf[] = "Bit Bucket";
708                 char ibuf[32];
709                 DWORD written;
710                 DWORD readden;
711             
712                 hnp = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT,
713                     /* nMaxInstances */ 1,
714                     /* nOutBufSize */ 1024,
715 rizwank 1.1         /* nInBufSize */ 1024,
716                     /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
717                     /* lpSecurityAttrib */ NULL);
718                 ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
719             
720                 ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL) == 0
721                     && GetLastError() == ERROR_PIPE_LISTENING, "WriteFile to not-yet-connected pipe\n");
722                 ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL) == 0
723                     && GetLastError() == ERROR_PIPE_LISTENING, "ReadFile from not-yet-connected pipe\n");
724             
725                 hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
726                 ok(hFile != INVALID_HANDLE_VALUE, "CreateFile failed\n");
727             
728                 /* don't try to do i/o if one side couldn't be opened, as it hangs */
729                 if (hFile != INVALID_HANDLE_VALUE) {
730             
731                     /* see what happens if server calls DisconnectNamedPipe
732                      * when there are bytes in the pipe
733                      */
734             
735                     ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile\n");
736 rizwank 1.1         ok(written == sizeof(obuf), "write file len\n");
737                     ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe while messages waiting\n");
738                     ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL) == 0
739                         && GetLastError() == ERROR_PIPE_NOT_CONNECTED, "WriteFile to disconnected pipe\n");
740                     ok(ReadFile(hnp, ibuf, sizeof(ibuf), &readden, NULL) == 0
741                         && GetLastError() == ERROR_PIPE_NOT_CONNECTED,
742                         "ReadFile from disconnected pipe with bytes waiting\n");
743                     ok(CloseHandle(hFile), "CloseHandle\n");
744                 }
745             
746                 ok(CloseHandle(hnp), "CloseHandle\n");
747             
748             }
749             
750             START_TEST(wsock32_main)
751             {
752                 trace("test 1 of 4:\n");
753                 test_DisconnectNamedPipe();
754                 trace("test 2 of 4:\n");
755                 test_CreateNamedPipe_instances_must_match();
756                 trace("test 3 of 4:\n");
757 rizwank 1.1     test_NamedPipe_2();
758                 trace("test 4 of 4:\n");
759                 test_CreateNamedPipe(PIPE_TYPE_BYTE);
760                 trace("all tests done\n");
761                 test_CreateNamedPipe(PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE);
762                 trace("all tests done\n");
763             }

Rizwan Kassim
Powered by
ViewCVS 0.9.2