Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456/* * Mailslot regression test * * Copyright 2003 Mike McCormack * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
#include <stdarg.h>#include <stdlib.h>#include <stdio.h>
#include <ntstatus.h>#define WIN32_NO_STATUS#include <windef.h>#include <winbase.h>#include <winternl.h>#include "wine/test.h"#ifdef __REACTOS__#include "winehacks.h"#endif
static const char szmspath[] = "\\\\.\\mailslot\\wine_mailslot_test";
static int mailslot_test(void){ UNICODE_STRING nt_path = RTL_CONSTANT_STRING( L"\\??\\MAILSLOT\\wine_mailslot_test" ); HANDLE hSlot, hSlot2, hWriter, hWriter2; unsigned char buffer[16]; DWORD count, dwMax, dwNext, dwMsgCount, dwTimeout; FILE_MAILSLOT_QUERY_INFORMATION info; OBJECT_ATTRIBUTES attr; IO_STATUS_BLOCK io; BOOL ret;
/* sanity check on GetMailslotInfo */ dwMax = dwNext = dwMsgCount = dwTimeout = 0; ok( !GetMailslotInfo( INVALID_HANDLE_VALUE, &dwMax, &dwNext, &dwMsgCount, &dwTimeout ), "getmailslotinfo succeeded\n");
/* open a mailslot that doesn't exist */ hWriter = CreateFileA(szmspath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); ok( hWriter == INVALID_HANDLE_VALUE, "nonexistent mailslot\n");
/* open a mailslot without the right name */ hSlot = CreateMailslotA( "blah", 0, 0, NULL ); ok( hSlot == INVALID_HANDLE_VALUE, "Created mailslot with invalid name\n"); ok( GetLastError() == ERROR_INVALID_NAME, "error should be ERROR_INVALID_NAME\n");
/* open a mailslot with a null name */ hSlot = CreateMailslotA( NULL, 0, 0, NULL ); ok( hSlot == INVALID_HANDLE_VALUE, "Created mailslot with invalid name\n"); ok( GetLastError() == ERROR_PATH_NOT_FOUND, "error should be ERROR_PATH_NOT_FOUND\n");
/* valid open, but with wacky parameters ... then check them */ hSlot = CreateMailslotA( szmspath, -1, -1, NULL ); ok( hSlot != INVALID_HANDLE_VALUE , "mailslot with valid name failed\n"); dwMax = dwNext = dwMsgCount = dwTimeout = 0; ok( GetMailslotInfo( hSlot, &dwMax, &dwNext, &dwMsgCount, &dwTimeout ), "getmailslotinfo failed\n"); ok( dwMax == ~0U, "dwMax incorrect\n"); ok( dwNext == MAILSLOT_NO_MESSAGE, "dwNext incorrect\n"); ok( dwMsgCount == 0, "dwMsgCount incorrect\n"); ok( dwTimeout == ~0U, "dwTimeout incorrect\n"); ok( GetMailslotInfo( hSlot, NULL, NULL, NULL, NULL ), "getmailslotinfo failed\n"); ok( CloseHandle(hSlot), "failed to close mailslot\n");
/* now open it for real */ hSlot = CreateMailslotA( szmspath, 0, 0, NULL ); ok( hSlot != INVALID_HANDLE_VALUE , "valid mailslot failed\n");
/* try and read/write to it */ count = 0xdeadbeef; SetLastError(0xdeadbeef); ret = ReadFile(INVALID_HANDLE_VALUE, buffer, 0, &count, NULL); ok(!ret, "ReadFile should fail\n"); ok(GetLastError() == ERROR_INVALID_HANDLE, "wrong error %lu\n", GetLastError()); ok(count == 0, "expected 0, got %lu\n", count);
count = 0xdeadbeef; SetLastError(0xdeadbeef); ret = ReadFile(hSlot, buffer, 0, &count, NULL); ok(!ret, "ReadFile should fail\n"); ok(GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %lu\n", GetLastError()); ok(count == 0, "expected 0, got %lu\n", count);
count = 0; memset(buffer, 0, sizeof buffer); ret = ReadFile( hSlot, buffer, sizeof buffer, &count, NULL); ok( !ret, "slot read\n"); if (!ret) ok( GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %lu\n", GetLastError() ); else ok( count == 0, "wrong count %lu\n", count ); ok( !WriteFile( hSlot, buffer, sizeof buffer, &count, NULL), "slot write\n"); ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %lu\n", GetLastError() );
io.Status = 0xdeadbeef; io.Information = 0xdeadbeef; ret = NtReadFile( hSlot, NULL, NULL, NULL, &io, buffer, sizeof(buffer), NULL, NULL ); ok( ret == STATUS_IO_TIMEOUT, "got %#x\n", ret ); ok( io.Status == 0xdeadbeef, "got status %#lx\n", io.Status ); ok( io.Information == 0xdeadbeef, "got size %Iu\n", io.Information );
io.Status = 0xdeadbeef; io.Information = 0xdeadbeef; ret = NtWriteFile( hSlot, NULL, NULL, NULL, &io, buffer, sizeof(buffer), NULL, NULL ); ok( ret == STATUS_ACCESS_DENIED, "got %#x\n", ret ); ok( io.Status == 0xdeadbeef, "got status %#lx\n", io.Status ); ok( io.Information == 0xdeadbeef, "got size %Iu\n", io.Information );
/* now try and open the client, but with the wrong sharing mode */ hWriter = CreateFileA(szmspath, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); ok( hWriter != INVALID_HANDLE_VALUE /* vista */ || GetLastError() == ERROR_SHARING_VIOLATION, "error should be ERROR_SHARING_VIOLATION got %p / %lu\n", hWriter, GetLastError()); if (hWriter != INVALID_HANDLE_VALUE) CloseHandle( hWriter );
/* now open the client with the correct sharing mode */ hWriter = CreateFileA(szmspath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); ok( hWriter != INVALID_HANDLE_VALUE, "existing mailslot err %lu\n", GetLastError());
/* * opening a client should make no difference to * whether we can read or write the mailslot */ ret = ReadFile( hSlot, buffer, sizeof buffer/2, &count, NULL); ok( !ret, "slot read\n"); if (!ret) ok( GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %lu\n", GetLastError() ); else ok( count == 0, "wrong count %lu\n", count ); ok( !WriteFile( hSlot, buffer, sizeof buffer/2, &count, NULL), "slot write\n"); ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %lu\n", GetLastError() );
/* * we can't read from this client, * but we should be able to write to it */ ok( !ReadFile( hWriter, buffer, sizeof buffer/2, &count, NULL), "can read client\n"); ok( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_ACCESS_DENIED, "wrong error %lu\n", GetLastError() ); ok( WriteFile( hWriter, buffer, sizeof buffer/2, &count, NULL), "can't write client\n"); ok( !ReadFile( hWriter, buffer, sizeof buffer/2, &count, NULL), "can read client\n"); ok( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_ACCESS_DENIED, "wrong error %lu\n", GetLastError() );
io.Status = 0xdeadbeef; io.Information = 0xdeadbeef; ret = NtReadFile( hWriter, NULL, NULL, NULL, &io, buffer, sizeof(buffer), NULL, NULL ); todo_wine ok( ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret ); ok( io.Status == 0xdeadbeef, "got status %#lx\n", io.Status ); ok( io.Information == 0xdeadbeef, "got size %Iu\n", io.Information );
/* * seeing as there's something in the slot, * we should be able to read it once */ ok( ReadFile( hSlot, buffer, sizeof buffer, &count, NULL), "slot read\n"); ok( count == (sizeof buffer/2), "short read\n" );
/* but not again */ ret = ReadFile( hSlot, buffer, sizeof buffer, &count, NULL); ok( !ret, "slot read\n"); if (!ret) ok( GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %lu\n", GetLastError() ); else ok( count == 0, "wrong count %lu\n", count );
/* now try open another writer... should fail */ hWriter2 = CreateFileA(szmspath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); /* succeeds on vista, don't test */ if (hWriter2 != INVALID_HANDLE_VALUE) CloseHandle( hWriter2 );
/* now try open another as a reader ... also fails */ hWriter2 = CreateFileA(szmspath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); /* succeeds on vista, don't test */ if (hWriter2 != INVALID_HANDLE_VALUE) CloseHandle( hWriter2 );
/* now try open another as a writer ... still fails */ hWriter2 = CreateFileA(szmspath, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); /* succeeds on vista, don't test */ if (hWriter2 != INVALID_HANDLE_VALUE) CloseHandle( hWriter2 );
/* now open another one */ hSlot2 = CreateMailslotA( szmspath, 0, 0, NULL ); ok( hSlot2 == INVALID_HANDLE_VALUE , "opened two mailslots\n");
/* close the client again */ ok( CloseHandle( hWriter ), "closing the client\n");
/* * now try reopen it with slightly different permissions ... * shared writing */ hWriter = CreateFileA(szmspath, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); ok( hWriter != INVALID_HANDLE_VALUE, "sharing writer\n");
/* * now try open another as a writer ... * but don't share with the first ... fail */ hWriter2 = CreateFileA(szmspath, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); /* succeeds on vista, don't test */ if (hWriter2 != INVALID_HANDLE_VALUE) CloseHandle( hWriter2 );
/* now try open another as a writer ... and share with the first */ hWriter2 = CreateFileA(szmspath, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); ok( hWriter2 != INVALID_HANDLE_VALUE, "2nd sharing writer\n");
/* check the mailslot info */ dwMax = dwNext = dwMsgCount = dwTimeout = 0; ok( GetMailslotInfo( hSlot, &dwMax, &dwNext, &dwMsgCount, &dwTimeout ), "getmailslotinfo failed\n"); ok( dwNext == MAILSLOT_NO_MESSAGE, "dwNext incorrect\n"); ok( dwMax == 0, "dwMax incorrect\n"); ok( dwMsgCount == 0, "dwMsgCount incorrect\n"); ok( dwTimeout == 0, "dwTimeout incorrect\n");
/* check there's still no data */ ret = ReadFile( hSlot, buffer, sizeof buffer, &count, NULL); ok( !ret, "slot read\n"); if (!ret) ok( GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %lu\n", GetLastError() ); else ok( count == 0, "wrong count %lu\n", count );
/* write two messages */ buffer[0] = 'a'; ok( WriteFile( hWriter, buffer, 1, &count, NULL), "1st write failed\n");
/* check the mailslot info */ dwNext = dwMsgCount = 0; ok( GetMailslotInfo( hSlot, NULL, &dwNext, &dwMsgCount, NULL ), "getmailslotinfo failed\n"); ok( dwNext == 1, "dwNext incorrect\n"); ok( dwMsgCount == 1, "dwMsgCount incorrect\n");
buffer[0] = 'b'; buffer[1] = 'c'; ok( WriteFile( hWriter2, buffer, 2, &count, NULL), "2nd write failed\n");
/* check the mailslot info */ dwNext = dwMsgCount = 0; ok( GetMailslotInfo( hSlot, NULL, &dwNext, &dwMsgCount, NULL ), "getmailslotinfo failed\n"); ok( dwNext == 1, "dwNext incorrect\n"); ok( dwMsgCount == 2, "dwMsgCount incorrect\n");
/* write a 3rd message with zero size */ ok( WriteFile( hWriter2, buffer, 0, &count, NULL), "3rd write failed\n");
/* check the mailslot info */ dwNext = dwMsgCount = 0; ok( GetMailslotInfo( hSlot, NULL, &dwNext, &dwMsgCount, NULL ), "getmailslotinfo failed\n"); ok( dwNext == 1, "dwNext incorrect\n"); ok( dwMsgCount == 3, "dwMsgCount incorrect %lu\n", dwMsgCount);
buffer[0]=buffer[1]=0;
/* * then check that they come out with the correct order and size, * then the slot is empty */ ok( ReadFile( hSlot, buffer, sizeof buffer, &count, NULL), "1st slot read failed\n"); ok( count == 1, "failed to get 1st message\n"); ok( buffer[0] == 'a', "1st message wrong\n");
/* check the mailslot info */ dwNext = dwMsgCount = 0; ok( GetMailslotInfo( hSlot, NULL, &dwNext, &dwMsgCount, NULL ), "getmailslotinfo failed\n"); ok( dwNext == 2, "dwNext incorrect\n"); ok( dwMsgCount == 2, "dwMsgCount incorrect %lu\n", dwMsgCount);
/* read the second message */ ok( ReadFile( hSlot, buffer, sizeof buffer, &count, NULL), "2nd slot read failed\n"); ok( count == 2, "failed to get 2nd message\n"); ok( ( buffer[0] == 'b' ) && ( buffer[1] == 'c' ), "2nd message wrong\n");
/* check the mailslot info */ dwNext = dwMsgCount = 0; ok( GetMailslotInfo( hSlot, NULL, &dwNext, &dwMsgCount, NULL ), "getmailslotinfo failed\n"); ok( dwNext == 0, "dwNext incorrect %lu\n", dwNext); ok( dwMsgCount == 1, "dwMsgCount incorrect %lu\n", dwMsgCount);
/* read the 3rd (zero length) message */ ok( ReadFile( hSlot, buffer, sizeof buffer, &count, NULL), "3rd slot read failed\n"); ok( count == 0, "failed to get 3rd message\n");
/* * now there should be no more messages * check the mailslot info */ dwNext = dwMsgCount = 0; ok( GetMailslotInfo( hSlot, NULL, &dwNext, &dwMsgCount, NULL ), "getmailslotinfo failed\n"); ok( dwNext == MAILSLOT_NO_MESSAGE, "dwNext incorrect\n"); ok( dwMsgCount == 0, "dwMsgCount incorrect\n");
/* check that reads fail */ ret = ReadFile( hSlot, buffer, sizeof buffer, &count, NULL); ok( !ret, "3rd slot read succeeded\n"); if (!ret) ok( GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %lu\n", GetLastError() ); else ok( count == 0, "wrong count %lu\n", count );
/* Try to perform a partial read. */ count = 0; ret = WriteFile( hWriter, buffer, 2, &count, NULL ); ok( ret, "got %d\n", ret ); ok( count == 2, "got count %lu\n", count );
io.Status = 0xdeadbeef; io.Information = 0xdeadbeef; ret = NtReadFile( hSlot, NULL, NULL, NULL, &io, buffer, 1, NULL, NULL ); ok( ret == STATUS_BUFFER_TOO_SMALL, "got %#x\n", ret ); ok( io.Status == 0xdeadbeef, "got status %#lx\n", io.Status ); ok( io.Information == 0xdeadbeef, "got size %Iu\n", io.Information );
io.Status = 0xdeadbeef; io.Information = 0xdeadbeef; memset( &info, 0xcc, sizeof(info) ); ret = NtQueryInformationFile( hSlot, &io, &info, sizeof(info), FileMailslotQueryInformation ); ok( ret == STATUS_SUCCESS, "got %#x\n", ret ); ok( io.Status == STATUS_SUCCESS, "got status %#lx\n", io.Status ); ok( io.Information == sizeof(info), "got size %Iu\n", io.Information ); ok( !info.MaximumMessageSize, "got maximum size %lu\n", info.MaximumMessageSize ); ok( !info.MailslotQuota, "got quota %lu\n", info.MailslotQuota ); ok( info.NextMessageSize == 2, "got next size %lu\n", info.NextMessageSize ); ok( info.MessagesAvailable == 1, "got message count %lu\n", info.MessagesAvailable ); ok( !info.ReadTimeout.QuadPart, "got timeout %I64u\n", info.ReadTimeout.QuadPart );
io.Status = 0xdeadbeef; io.Information = 0xdeadbeef; memset( &info, 0xcc, sizeof(info) ); ret = NtQueryInformationFile( hWriter, &io, &info, sizeof(info), FileMailslotQueryInformation ); todo_wine ok( ret == STATUS_SUCCESS || ret == STATUS_INVALID_PARAMETER /* Win < 8 */, "got %#x\n", ret ); if (ret == STATUS_SUCCESS) { ok( io.Status == STATUS_SUCCESS, "got status %#lx\n", io.Status ); ok( io.Information == sizeof(info), "got size %Iu\n", io.Information ); ok( !info.MaximumMessageSize, "got maximum size %lu\n", info.MaximumMessageSize ); ok( !info.MailslotQuota, "got quota %lu\n", info.MailslotQuota ); ok( info.NextMessageSize == 2, "got next size %lu\n", info.NextMessageSize ); ok( info.MessagesAvailable == 1, "got message count %lu\n", info.MessagesAvailable ); ok( !info.ReadTimeout.QuadPart, "got timeout %I64u\n", info.ReadTimeout.QuadPart ); }
/* finally close the mailslot and its client */ ok( CloseHandle( hWriter2 ), "closing 2nd client\n"); ok( CloseHandle( hWriter ), "closing the client\n"); ok( CloseHandle( hSlot ), "closing the mailslot\n");
/* test timeouts */ hSlot = CreateMailslotA( szmspath, 0, 1000, NULL ); ok( hSlot != INVALID_HANDLE_VALUE , "valid mailslot failed\n"); count = 0; memset(buffer, 0, sizeof buffer); dwTimeout = GetTickCount(); ok( !ReadFile( hSlot, buffer, sizeof buffer, &count, NULL), "slot read\n"); ok( GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %lu\n", GetLastError() ); dwTimeout = GetTickCount() - dwTimeout; ok( dwTimeout >= 900, "timeout too short %lu\n", dwTimeout ); ok( CloseHandle( hSlot ), "closing the mailslot\n");
InitializeObjectAttributes( &attr, &nt_path, 0, NULL, NULL ); ret = NtCreateMailslotFile( &hSlot, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &attr, &io, 0, 0, 0, NULL ); ok( !ret, "got %#x\n", ret );
io.Status = 0xdeadbeef; io.Information = 0xdeadbeef; ret = NtWriteFile( hSlot, NULL, NULL, NULL, &io, buffer, sizeof(buffer), NULL, NULL ); todo_wine ok( ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret ); ok( io.Status == 0xdeadbeef, "got status %#lx\n", io.Status ); ok( io.Information == 0xdeadbeef, "got size %Iu\n", io.Information );
#ifdef __REACTOS__ if (is_reactos()) { ok(FALSE, "FIXME: This often bugchecks on ReactOS. This does not bugcheck on checked Windows builds.\n"); } else {#endif io.Status = 0xdeadbeef; io.Information = 0xdeadbeef; ret = NtReadFile( hSlot, NULL, NULL, NULL, &io, buffer, sizeof(buffer), NULL, NULL ); ok( ret == STATUS_PENDING, "got %#x\n", ret ); ok( io.Status == 0xdeadbeef, "got status %#lx\n", io.Status ); ok( io.Information == 0xdeadbeef, "got size %Iu\n", io.Information );#ifdef __REACTOS__ }#endif
ret = WaitForSingleObject( hSlot, 0 ); ok( ret == WAIT_TIMEOUT, "got %d\n", ret );
hWriter = CreateFileA( szmspath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );#ifdef __REACTOS__ ok( hWriter != INVALID_HANDLE_VALUE || broken(GetLastError() == ERROR_SHARING_VIOLATION) /* WS03 */, "got err %lu\n", GetLastError() );#else ok( hWriter != INVALID_HANDLE_VALUE, "got err %lu\n", GetLastError() );#endif
ret = WriteFile( hWriter, "data", 4, &count, NULL );#ifdef __REACTOS__ ok( ret == TRUE || broken(GetLastError() == ERROR_INVALID_HANDLE) /* WS03 */, "got error %lu\n", GetLastError() );#else ok( ret == TRUE, "got error %lu\n", GetLastError() );#endif
ret = WaitForSingleObject( hSlot, 1000 );#ifdef __REACTOS__ ok( !ret || broken(ret == WAIT_TIMEOUT) /* WS03 */, "got %d\n", ret ); ok( !io.Status || broken(io.Status == 0xdeadbeef) /* WS03 */, "got status %#lx\n", io.Status ); if (GetNTVersion() >= _WIN32_WINNT_VISTA)#else ok( !ret, "got %d\n", ret ); ok( !io.Status, "got status %#lx\n", io.Status );#endif ok( io.Information == 4, "got size %Iu\n", io.Information );
CloseHandle( hWriter ); CloseHandle( hSlot );
return 0;}
START_TEST(mailslot){ mailslot_test();}