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