Added version information.
[wine] / dlls / kernel / tests / pipe.c
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 <winsock.h>
22
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <time.h>
26
27 #ifndef STANDALONE
28 #include "wine/test.h"
29 #else
30 #include <assert.h>
31 #define START_TEST(name) main(int argc, char **argv)
32 #define ok(condition, msg) assert(condition)
33 #define todo_wine
34 #endif
35
36 #include <wtypes.h>
37 #include <windef.h>
38 #include <winbase.h>
39 #include <winerror.h>
40
41 #define PIPENAME "\\\\.\\PiPe\\tests_" __FILE__
42
43 void test_CreateNamedPipeA(void)
44 {
45     HANDLE hnp;
46     HANDLE hFile;
47     const char obuf[] = "Bit Bucket";
48     char ibuf[32];
49     DWORD written;
50     DWORD gelesen;
51
52     /* Bad parameter checks */
53     hnp = CreateNamedPipeA("not a named pipe", 
54         PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE|PIPE_WAIT, 
55         /* nMaxInstances */ 1,
56         /* nOutBufSize */ 1024,
57         /* nInBufSize */ 1024,
58         /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
59         /* lpSecurityAttrib */ NULL);
60
61     if (hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) {
62         /* Is this the right way to notify user of skipped tests? */
63         ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED, 
64             "CreateNamedPipe not supported on this platform, skipping tests.");
65         return;
66     }
67     ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_NAME,
68         "CreateNamedPipe should fail if name doesn't start with \\\\.\\pipe");
69
70     hnp = CreateNamedPipeA(NULL, 
71         PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE|PIPE_WAIT, 
72         1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL);
73     ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PATH_NOT_FOUND,
74         "CreateNamedPipe should fail if name is NULL");
75
76     hFile = CreateFileA(PIPENAME, GENERIC_READ|GENERIC_WRITE, 0, 
77         NULL, OPEN_EXISTING, 0, 0);
78     ok(hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND, "connecting to nonexistent named pipe should fail with ERROR_FILE_NOT_FOUND");
79
80     /* Functional checks */
81
82     hnp = CreateNamedPipeA(PIPENAME,
83         PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE|PIPE_WAIT, 
84         /* nMaxInstances */ 1,
85         /* nOutBufSize */ 1024,
86         /* nInBufSize */ 1024,
87         /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
88         /* lpSecurityAttrib */ NULL);
89     ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed");
90
91     hFile = CreateFileA(PIPENAME, GENERIC_READ|GENERIC_WRITE, 0, 
92             NULL, OPEN_EXISTING, 0, 0);
93     todo_wine
94     {
95         ok(hFile != INVALID_HANDLE_VALUE, "CreateFile failed");
96     }
97
98     /* don't try to do i/o if one side couldn't be opened, as it hangs */
99     if (hFile != INVALID_HANDLE_VALUE) {
100         HANDLE hFile2;
101
102         /* Make sure we can read and write a few bytes in both directions*/
103         memset(ibuf, 0, sizeof(ibuf));
104         ok(WriteFile(hnp, obuf, sizeof(obuf), &written, NULL), "WriteFile");
105         ok(written == sizeof(obuf), "write file len");
106         ok(ReadFile(hFile, ibuf, sizeof(obuf), &gelesen, NULL), "ReadFile");
107         ok(gelesen == sizeof(obuf), "read file len");
108         ok(memcmp(obuf, ibuf, written) == 0, "content check");
109
110         memset(ibuf, 0, sizeof(ibuf));
111         ok(WriteFile(hFile, obuf, sizeof(obuf), &written, NULL), "WriteFile");
112         ok(written == sizeof(obuf), "write file len");
113         ok(ReadFile(hnp, ibuf, sizeof(obuf), &gelesen, NULL), "ReadFile");
114         ok(gelesen == sizeof(obuf), "read file len");
115         ok(memcmp(obuf, ibuf, written) == 0, "content check");
116
117         /* Picky conformance tests */
118
119         /* Verify that you can't connect to pipe again
120          * until server calls DisconnectNamedPipe+ConnectNamedPipe
121          * or creates a new pipe
122          * case 1: other client not yet closed
123          */
124         hFile2 = CreateFileA(PIPENAME, GENERIC_READ|GENERIC_WRITE, 0, 
125             NULL, OPEN_EXISTING, 0, 0);
126         ok(hFile2 == INVALID_HANDLE_VALUE, "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail");
127         ok(GetLastError() == ERROR_PIPE_BUSY, "connecting to named pipe before other client closes should fail with ERROR_PIPE_BUSY");
128
129         ok(CloseHandle(hFile), "CloseHandle");
130
131         /* case 2: other client already closed */
132         hFile = CreateFileA(PIPENAME, GENERIC_READ|GENERIC_WRITE, 0, 
133             NULL, OPEN_EXISTING, 0, 0);
134         ok(hFile == INVALID_HANDLE_VALUE, "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail");
135         ok(GetLastError() == ERROR_PIPE_BUSY, "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail with ERROR_PIPE_BUSY");
136
137         ok(DisconnectNamedPipe(hnp), "DisconnectNamedPipe");
138
139         /* case 3: server has called DisconnectNamedPipe but not ConnectNamed Pipe */
140         hFile = CreateFileA(PIPENAME, GENERIC_READ|GENERIC_WRITE, 0, 
141             NULL, OPEN_EXISTING, 0, 0);
142         ok(hFile == INVALID_HANDLE_VALUE, "connecting to named pipe after other client closes but before DisconnectNamedPipe should fail");
143         ok(GetLastError() == ERROR_PIPE_BUSY, "connecting to named pipe after other client closes but before ConnectNamedPipe should fail with ERROR_PIPE_BUSY");
144
145         /* to be complete, we'd call ConnectNamedPipe here and loop,
146          * but by default that's blocking, so we'd either have
147          * to turn on the uncommon nonblocking mode, or
148          * use another thread.
149          */
150     }
151
152     ok(CloseHandle(hnp), "CloseHandle");
153 }
154
155 START_TEST(pipe)
156 {
157     test_CreateNamedPipeA();
158 }