Added a test for mailslots.
[wine] / dlls / kernel / tests / mailslot.c
1 /*
2  *  Mailslot regression test
3  *
4  *  Copyright 2003 Mike McCormack
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 <stdarg.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24
25 #include <windef.h>
26 #include <winbase.h>
27
28 #ifndef STANDALONE
29 #include "wine/test.h"
30 #else
31 #define START_TEST(name) main(int argc, char **argv)
32
33 #define ok(cond,str) do{ if(!(cond)) printf("line %d: %s\n",__LINE__,str); }while (0)
34 #define todo_wine
35
36 #endif
37
38 const char szmspath[] = "\\\\.\\mailslot\\wine_mailslot_test";
39
40 int mailslot_test()
41 {
42     HANDLE hSlot, hSlot2, hWriter, hWriter2;
43     unsigned char buffer[16];
44     DWORD count, dwMax, dwNext, dwMsgCount, dwTimeout;
45
46     /* sanity check on GetMailslotInfo */
47     dwMax = dwNext = dwMsgCount = dwTimeout = 0;
48     ok( !GetMailslotInfo( INVALID_HANDLE_VALUE, &dwMax, &dwNext,
49             &dwMsgCount, &dwTimeout ), "getmailslotinfo succeeded");
50
51     /* open a mailslot that doesn't exist */
52     hWriter = CreateFile(szmspath, GENERIC_READ|GENERIC_WRITE,
53                              FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
54     ok( hWriter == INVALID_HANDLE_VALUE, "non-existing mailslot");
55
56     /* open a mailslot without the right name */
57     hSlot = CreateMailslot( "blah", 0, 0, NULL );
58     ok( hSlot == INVALID_HANDLE_VALUE,
59             "Created mailslot with invalid name");
60     todo_wine
61     {
62        ok( GetLastError() == ERROR_INVALID_NAME,
63            "error should be ERROR_INVALID_NAME");
64     }
65
66     /* open a mailslot with a null name */
67     hSlot = CreateMailslot( NULL, 0, 0, NULL );
68     ok( hSlot == INVALID_HANDLE_VALUE,
69             "Created mailslot with invalid name");
70     todo_wine
71     {
72         ok( GetLastError() == ERROR_PATH_NOT_FOUND,
73             "error should be ERROR_PATH_NOT_FOUND");
74     }
75
76     todo_wine
77     {
78     /* valid open, but with wacky parameters ... then check them */
79     hSlot = CreateMailslot( szmspath, -1, -1, NULL );
80     ok( hSlot != INVALID_HANDLE_VALUE , "mailslot with valid name failed");
81     dwMax = dwNext = dwMsgCount = dwTimeout = 0;
82     ok( GetMailslotInfo( hSlot, &dwMax, &dwNext, &dwMsgCount, &dwTimeout ),
83            "getmailslotinfo failed");
84     ok( dwMax == -1, "dwMax incorrect");
85     ok( dwNext == MAILSLOT_NO_MESSAGE, "dwNext incorrect");
86     }
87     ok( dwMsgCount == 0, "dwMsgCount incorrect");
88     todo_wine
89     {
90     ok( dwTimeout == -1, "dwTimeout incorrect");
91     ok( GetMailslotInfo( hSlot, NULL, NULL, NULL, NULL ),
92             "getmailslotinfo failed");
93     ok( CloseHandle(hSlot), "failed to close mailslot");
94     }
95
96     todo_wine
97     {
98     /* now open it for real */
99     hSlot = CreateMailslot( szmspath, 0, 0, NULL );
100     ok( hSlot != INVALID_HANDLE_VALUE , "valid mailslot failed");
101     }
102
103     /* try and read/write to it */
104     count = 0;
105     memset(buffer, 0, sizeof buffer);
106     ok( !ReadFile( hSlot, buffer, sizeof buffer, &count, NULL),
107             "slot read");
108     ok( !WriteFile( hSlot, buffer, sizeof buffer, &count, NULL),
109             "slot write");
110
111     /* now try and openthe client, but with the wrong sharing mode */
112     hWriter = CreateFile(szmspath, GENERIC_READ|GENERIC_WRITE,
113                              0, NULL, OPEN_EXISTING, 0, NULL);
114     ok( hWriter == INVALID_HANDLE_VALUE, "bad sharing mode");
115     todo_wine
116     {
117     ok( GetLastError() == ERROR_SHARING_VIOLATION,
118             "error should be ERROR_SHARING_VIOLATION");
119
120     /* now open the client with the correct sharing mode */
121     hWriter = CreateFile(szmspath, GENERIC_READ|GENERIC_WRITE,
122                              FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
123     ok( hWriter != INVALID_HANDLE_VALUE, "existing mailslot");
124     }
125
126     /*
127      * opening a client should make no difference to
128      * whether we can read or write the mailslot
129      */
130     ok( !ReadFile( hSlot, buffer, sizeof buffer/2, &count, NULL),
131             "slot read");
132     ok( !WriteFile( hSlot, buffer, sizeof buffer/2, &count, NULL),
133             "slot write");
134
135     /*
136      * we can't read from this client, 
137      * but we should be able to write to it
138      */
139     ok( !ReadFile( hWriter, buffer, sizeof buffer/2, &count, NULL),
140             "can read client");
141     todo_wine
142     {
143     ok( WriteFile( hWriter, buffer, sizeof buffer/2, &count, NULL),
144             "can't write client");
145     }
146     ok( !ReadFile( hWriter, buffer, sizeof buffer/2, &count, NULL),
147             "can read client");
148
149     /*
150      * seeing as there's something in the slot,
151      * we should be able to read it once
152      */
153     todo_wine
154     {
155     ok( ReadFile( hSlot, buffer, sizeof buffer, &count, NULL),
156             "slot read");
157     ok( count == (sizeof buffer/2), "short read" );
158     }
159
160     /* but not again */
161     ok( !ReadFile( hSlot, buffer, sizeof buffer, &count, NULL),
162             "slot read");
163
164     /* now try open another writer... should fail */
165     hWriter2 = CreateFile(szmspath, GENERIC_READ|GENERIC_WRITE,
166                      FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
167     ok( hWriter2 == INVALID_HANDLE_VALUE, "two writers");
168
169     /* now try open another as a reader ... also fails */
170     hWriter2 = CreateFile(szmspath, GENERIC_READ,
171                      FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
172     ok( hWriter2 == INVALID_HANDLE_VALUE, "writer + reader");
173
174     /* now try open another as a writer ... still fails */
175     hWriter2 = CreateFile(szmspath, GENERIC_WRITE,
176                      FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
177     ok( hWriter2 == INVALID_HANDLE_VALUE, "writer");
178
179     /* now open another one */
180     hSlot2 = CreateMailslot( szmspath, 0, 0, NULL );
181     ok( hSlot2 == INVALID_HANDLE_VALUE , "opened two mailslots");
182
183     todo_wine
184     {
185     /* close the client again */
186     ok( CloseHandle( hWriter ), "closing the client");
187
188     /*
189      * now try reopen it with slightly different permissions ...
190      * shared writing
191      */
192     hWriter = CreateFile(szmspath, GENERIC_WRITE,
193               FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
194     ok( hWriter != INVALID_HANDLE_VALUE, "sharing writer");
195     }
196
197     /*
198      * now try open another as a writer ...
199      * but don't share with the first ... fail
200      */
201     hWriter2 = CreateFile(szmspath, GENERIC_WRITE,
202                      FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
203     ok( hWriter2 == INVALID_HANDLE_VALUE, "greedy writer succeeded");
204
205     todo_wine
206     {
207     /* now try open another as a writer ... and share with the first */
208     hWriter2 = CreateFile(szmspath, GENERIC_WRITE,
209               FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
210     ok( hWriter2 != INVALID_HANDLE_VALUE, "2nd sharing writer");
211
212     /* check the mailslot info */
213     dwMax = dwNext = dwMsgCount = dwTimeout = 0;
214     ok( GetMailslotInfo( hSlot, &dwMax, &dwNext, &dwMsgCount, &dwTimeout ),
215         "getmailslotinfo failed");
216     ok( dwNext == MAILSLOT_NO_MESSAGE, "dwNext incorrect");
217     }
218     ok( dwMax == 0, "dwMax incorrect");
219     ok( dwMsgCount == 0, "dwMsgCount incorrect");
220     ok( dwTimeout == 0, "dwTimeout incorrect");
221
222     /* check there's still no data */
223     ok( !ReadFile( hSlot, buffer, sizeof buffer, &count, NULL), "slot read");
224
225     /* write two messages */
226     todo_wine
227     {
228     buffer[0] = 'a';
229     ok( WriteFile( hWriter, buffer, 1, &count, NULL), "1st write failed");
230
231     /* check the mailslot info */
232     dwNext = dwMsgCount = 0;
233     ok( GetMailslotInfo( hSlot, NULL, &dwNext, &dwMsgCount, NULL ),
234         "getmailslotinfo failed");
235     ok( dwNext == 1, "dwNext incorrect");
236     ok( dwMsgCount == 1, "dwMsgCount incorrect");
237
238     buffer[0] = 'b';
239     buffer[1] = 'c';
240     ok( WriteFile( hWriter2, buffer, 2, &count, NULL), "2nd write failed");
241
242     /* check the mailslot info */
243     dwNext = dwMsgCount = 0;
244     ok( GetMailslotInfo( hSlot, NULL, &dwNext, &dwMsgCount, NULL ),
245         "getmailslotinfo failed");
246     ok( dwNext == 1, "dwNext incorrect");
247     ok( dwMsgCount == 2, "dwMsgCount incorrect");
248
249     /* write a 3rd message with zero size */
250     ok( WriteFile( hWriter2, buffer, 0, &count, NULL), "3rd write failed");
251
252     /* check the mailslot info */
253     dwNext = dwMsgCount = 0;
254     ok( GetMailslotInfo( hSlot, NULL, &dwNext, &dwMsgCount, NULL ),
255         "getmailslotinfo failed");
256     ok( dwNext == 1, "dwNext incorrect");
257     ok( dwMsgCount == 3, "dwMsgCount incorrect");
258
259     buffer[0]=buffer[1]=0;
260
261     /*
262      * then check that they come out with the correct order and size,
263      * then the slot is empty
264      */
265     ok( ReadFile( hSlot, buffer, sizeof buffer, &count, NULL),
266         "1st slot read failed");
267     ok( count == 1, "failed to get 1st message");
268     ok( buffer[0] == 'a', "1st message wrong");
269
270     /* check the mailslot info */
271     dwNext = dwMsgCount = 0;
272     ok( GetMailslotInfo( hSlot, NULL, &dwNext, &dwMsgCount, NULL ),
273         "getmailslotinfo failed");
274     ok( dwNext == 2, "dwNext incorrect");
275     ok( dwMsgCount == 2, "dwMsgCount incorrect");
276
277     /* read the second message */
278     ok( ReadFile( hSlot, buffer, sizeof buffer, &count, NULL),
279         "2nd slot read failed");
280     ok( count == 2, "failed to get 2nd message");    
281     ok( ( buffer[0] == 'b' ) && ( buffer[1] == 'c' ), "2nd message wrong");
282
283     /* check the mailslot info */
284     dwNext = dwMsgCount = 0;
285     ok( GetMailslotInfo( hSlot, NULL, &dwNext, &dwMsgCount, NULL ),
286         "getmailslotinfo failed");
287     }
288     ok( dwNext == 0, "dwNext incorrect");
289     todo_wine
290     {
291     ok( dwMsgCount == 1, "dwMsgCount incorrect");
292
293     /* read the 3rd (zero length) message */
294     ok( ReadFile( hSlot, buffer, sizeof buffer, &count, NULL),
295         "3rd slot read failed");
296     }
297     ok( count == 0, "failed to get 3rd message");    
298
299     /*
300      * now there should be no more messages
301      * check the mailslot info
302      */
303     todo_wine
304     {
305     dwNext = dwMsgCount = 0;
306     ok( GetMailslotInfo( hSlot, NULL, &dwNext, &dwMsgCount, NULL ),
307         "getmailslotinfo failed");
308     ok( dwNext == MAILSLOT_NO_MESSAGE, "dwNext incorrect");
309     }
310     ok( dwMsgCount == 0, "dwMsgCount incorrect");
311
312     /* check that reads fail */
313     ok( !ReadFile( hSlot, buffer, sizeof buffer, &count, NULL),
314         "3rd slot read succeeded");
315
316     /* finally close the mailslot and its client */
317     todo_wine
318     {
319     ok( CloseHandle( hWriter2 ), "closing 2nd client");
320     ok( CloseHandle( hWriter ), "closing the client");
321     ok( CloseHandle( hSlot ), "closing the mailslot");
322     }
323
324     return 0;
325 }
326
327 START_TEST(mailslot)
328 {
329     mailslot_test();
330 }