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