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