kernel32/tests: Use '%d' to print GetLastError().
[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( !WriteFile( hSlot, buffer, sizeof buffer, &count, NULL),
86             "slot write\n");
87
88     /* now try and openthe client, but with the wrong sharing mode */
89     hWriter = CreateFile(szmspath, GENERIC_READ|GENERIC_WRITE,
90                              0, NULL, OPEN_EXISTING, 0, NULL);
91     ok( hWriter == INVALID_HANDLE_VALUE, "bad sharing mode\n");
92     ok( GetLastError() == ERROR_SHARING_VIOLATION,
93             "error should be ERROR_SHARING_VIOLATION\n");
94
95     /* now open the client with the correct sharing mode */
96     hWriter = CreateFile(szmspath, GENERIC_READ|GENERIC_WRITE,
97                              FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
98     ok( hWriter != INVALID_HANDLE_VALUE, "existing mailslot\n");
99
100     /*
101      * opening a client should make no difference to
102      * whether we can read or write the mailslot
103      */
104     ok( !ReadFile( hSlot, buffer, sizeof buffer/2, &count, NULL),
105             "slot read\n");
106     ok( !WriteFile( hSlot, buffer, sizeof buffer/2, &count, NULL),
107             "slot write\n");
108
109     /*
110      * we can't read from this client, 
111      * but we should be able to write to it
112      */
113     ok( !ReadFile( hWriter, buffer, sizeof buffer/2, &count, NULL),
114             "can read client\n");
115     ok( WriteFile( hWriter, buffer, sizeof buffer/2, &count, NULL),
116             "can't write client\n");
117     ok( !ReadFile( hWriter, buffer, sizeof buffer/2, &count, NULL),
118             "can read client\n");
119
120     /*
121      * seeing as there's something in the slot,
122      * we should be able to read it once
123      */
124     ok( ReadFile( hSlot, buffer, sizeof buffer, &count, NULL),
125             "slot read\n");
126     ok( count == (sizeof buffer/2), "short read\n" );
127
128     /* but not again */
129     ok( !ReadFile( hSlot, buffer, sizeof buffer, &count, NULL),
130             "slot read\n");
131
132     /* now try open another writer... should fail */
133     hWriter2 = CreateFile(szmspath, GENERIC_READ|GENERIC_WRITE,
134                      FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
135     ok( hWriter2 == INVALID_HANDLE_VALUE, "two writers\n");
136
137     /* now try open another as a reader ... also fails */
138     hWriter2 = CreateFile(szmspath, GENERIC_READ,
139                      FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
140     ok( hWriter2 == INVALID_HANDLE_VALUE, "writer + reader\n");
141
142     /* now try open another as a writer ... still fails */
143     hWriter2 = CreateFile(szmspath, GENERIC_WRITE,
144                      FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
145     ok( hWriter2 == INVALID_HANDLE_VALUE, "writer\n");
146
147     /* now open another one */
148     hSlot2 = CreateMailslot( szmspath, 0, 0, NULL );
149     ok( hSlot2 == INVALID_HANDLE_VALUE , "opened two mailslots\n");
150
151     /* close the client again */
152     ok( CloseHandle( hWriter ), "closing the client\n");
153
154     /*
155      * now try reopen it with slightly different permissions ...
156      * shared writing
157      */
158     hWriter = CreateFile(szmspath, GENERIC_WRITE,
159               FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
160     ok( hWriter != INVALID_HANDLE_VALUE, "sharing writer\n");
161
162     /*
163      * now try open another as a writer ...
164      * but don't share with the first ... fail
165      */
166     hWriter2 = CreateFile(szmspath, GENERIC_WRITE,
167                      FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
168     ok( hWriter2 == INVALID_HANDLE_VALUE, "greedy writer succeeded\n");
169
170     /* now try open another as a writer ... and share with the first */
171     hWriter2 = CreateFile(szmspath, GENERIC_WRITE,
172               FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
173     ok( hWriter2 != INVALID_HANDLE_VALUE, "2nd sharing writer\n");
174
175     /* check the mailslot info */
176     dwMax = dwNext = dwMsgCount = dwTimeout = 0;
177     ok( GetMailslotInfo( hSlot, &dwMax, &dwNext, &dwMsgCount, &dwTimeout ),
178         "getmailslotinfo failed\n");
179     ok( dwNext == MAILSLOT_NO_MESSAGE, "dwNext incorrect\n");
180     ok( dwMax == 0, "dwMax incorrect\n");
181     ok( dwMsgCount == 0, "dwMsgCount incorrect\n");
182     ok( dwTimeout == 0, "dwTimeout incorrect\n");
183
184     /* check there's still no data */
185     ok( !ReadFile( hSlot, buffer, sizeof buffer, &count, NULL), "slot read\n");
186
187     /* write two messages */
188     buffer[0] = 'a';
189     ok( WriteFile( hWriter, buffer, 1, &count, NULL), "1st write failed\n");
190
191     /* check the mailslot info */
192     dwNext = dwMsgCount = 0;
193     ok( GetMailslotInfo( hSlot, NULL, &dwNext, &dwMsgCount, NULL ),
194         "getmailslotinfo failed\n");
195     ok( dwNext == 1, "dwNext incorrect\n");
196     ok( dwMsgCount == 1, "dwMsgCount incorrect\n");
197
198     buffer[0] = 'b';
199     buffer[1] = 'c';
200     ok( WriteFile( hWriter2, buffer, 2, &count, NULL), "2nd write failed\n");
201
202     /* check the mailslot info */
203     dwNext = dwMsgCount = 0;
204     ok( GetMailslotInfo( hSlot, NULL, &dwNext, &dwMsgCount, NULL ),
205         "getmailslotinfo failed\n");
206     ok( dwNext == 1, "dwNext incorrect\n");
207     todo_wine {
208     ok( dwMsgCount == 2, "dwMsgCount incorrect\n");
209     }
210
211     /* write a 3rd message with zero size */
212     ok( WriteFile( hWriter2, buffer, 0, &count, NULL), "3rd write failed\n");
213
214     /* check the mailslot info */
215     dwNext = dwMsgCount = 0;
216     ok( GetMailslotInfo( hSlot, NULL, &dwNext, &dwMsgCount, NULL ),
217         "getmailslotinfo failed\n");
218     ok( dwNext == 1, "dwNext incorrect\n");
219     todo_wine {
220     ok( dwMsgCount == 3, "dwMsgCount incorrect\n");
221     }
222
223     buffer[0]=buffer[1]=0;
224
225     /*
226      * then check that they come out with the correct order and size,
227      * then the slot is empty
228      */
229     ok( ReadFile( hSlot, buffer, sizeof buffer, &count, NULL),
230         "1st slot read failed\n");
231     ok( count == 1, "failed to get 1st message\n");
232     ok( buffer[0] == 'a', "1st message wrong\n");
233
234     /* check the mailslot info */
235     dwNext = dwMsgCount = 0;
236     ok( GetMailslotInfo( hSlot, NULL, &dwNext, &dwMsgCount, NULL ),
237         "getmailslotinfo failed\n");
238     ok( dwNext == 2, "dwNext incorrect\n");
239     todo_wine {
240     ok( dwMsgCount == 2, "dwMsgCount incorrect\n");
241     }
242
243     /* read the second message */
244     ok( ReadFile( hSlot, buffer, sizeof buffer, &count, NULL),
245         "2nd slot read failed\n");
246     ok( count == 2, "failed to get 2nd message\n");
247     ok( ( buffer[0] == 'b' ) && ( buffer[1] == 'c' ), "2nd message wrong\n");
248
249     /* check the mailslot info */
250     dwNext = dwMsgCount = 0;
251     ok( GetMailslotInfo( hSlot, NULL, &dwNext, &dwMsgCount, NULL ),
252         "getmailslotinfo failed\n");
253     todo_wine {
254     ok( dwNext == 0, "dwNext incorrect\n");
255     ok( dwMsgCount == 1, "dwMsgCount incorrect\n");
256     }
257
258     /* read the 3rd (zero length) message */
259     todo_wine {
260     ok( ReadFile( hSlot, buffer, sizeof buffer, &count, NULL),
261         "3rd slot read failed\n");
262     }
263     ok( count == 0, "failed to get 3rd message\n");
264
265     /*
266      * now there should be no more messages
267      * check the mailslot info
268      */
269     dwNext = dwMsgCount = 0;
270     ok( GetMailslotInfo( hSlot, NULL, &dwNext, &dwMsgCount, NULL ),
271         "getmailslotinfo failed\n");
272     ok( dwNext == MAILSLOT_NO_MESSAGE, "dwNext incorrect\n");
273     ok( dwMsgCount == 0, "dwMsgCount incorrect\n");
274
275     /* check that reads fail */
276     ok( !ReadFile( hSlot, buffer, sizeof buffer, &count, NULL),
277         "3rd slot read succeeded\n");
278
279     /* finally close the mailslot and its client */
280     ok( CloseHandle( hWriter2 ), "closing 2nd client\n");
281     ok( CloseHandle( hWriter ), "closing the client\n");
282     ok( CloseHandle( hSlot ), "closing the mailslot\n");
283
284     return 0;
285 }
286
287 START_TEST(mailslot)
288 {
289     mailslot_test();
290 }