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