void TUI::CheckMailslot() { DWORD cbMessage, cMessage, cbRead; BOOL fResult; LPSTR lpszBuffer; cbMessage = cMessage = cbRead = 0; fResult = GetMailslotInfo(hMailSlot, // mailslot handle (LPDWORD) NULL, // no maximum message size &cbMessage, // size of next message &cMessage, // number of messages (LPDWORD) NULL); // no read time-out R_ASSERT2(fResult,"Can't get mailslot info"); if (cbMessage == MAILSLOT_NO_MESSAGE) return; while (cMessage != 0) // retrieve all messages { // Allocate memory for the message. lpszBuffer = (LPSTR) GlobalAlloc(GPTR, cbMessage); lpszBuffer[0] = '\0'; fResult = ReadFile(hMailSlot, lpszBuffer, cbMessage, &cbRead, (LPOVERLAPPED) NULL); if (!fResult) { GlobalFree((HGLOBAL) lpszBuffer); throw Exception("Can't ReadFile"); } OnReceiveMail(lpszBuffer); GlobalFree((HGLOBAL) lpszBuffer); fResult = GetMailslotInfo(hMailSlot, // mailslot handle (LPDWORD) NULL, // no maximum message size &cbMessage, // size of next message &cMessage, // number of messages (LPDWORD) NULL); // no read time-out R_ASSERT2(fResult,"Can't get mailslot info"); } }
void msRead(void) { DWORD cbMessage, cMessage, cbRead; BOOL fResult; LPSTR lpszBuffer; cbMessage = cMessage = cbRead = 0; fResult = GetMailslotInfo(hLocalSlot, // mailslot handle (LPDWORD)NULL, // no maximum message size &cbMessage, // size of next message &cMessage, // number of messages (LPDWORD)NULL); // no read time-out if (!fResult) return; if (cbMessage == MAILSLOT_NO_MESSAGE) return; while (cMessage != 0) // retrieve all messages { // Allocate memory for the message. lpszBuffer = (LPSTR)GlobalAlloc(GPTR, cbMessage); lpszBuffer[0] = '\0'; fResult = ReadFile(hLocalSlot, lpszBuffer, cbMessage, &cbRead, (LPOVERLAPPED)NULL); if (!fResult) { GlobalFree((HGLOBAL)lpszBuffer); return; } msParse(lpszBuffer); GlobalFree((HGLOBAL)lpszBuffer); fResult = GetMailslotInfo(hLocalSlot, // mailslot handle (LPDWORD)NULL, // no maximum message size &cbMessage, // size of next message &cMessage, // number of messages (LPDWORD)NULL); // no read time-out if (!fResult) return; } }
int jumpMessageQueueWaitForMessage(JUMPPlatformCString type, int32 timeout){ DWORD cbBytes, cbMessage, cMessage = 0; BOOL fResult; char buffer; DWORD err, to;// error code, time out parameter HANDLE hSlot = mailslotGet(type, NULL); if (hSlot == NULL) { printf("ERROR: jumpMessageQueueWaitForMessage - MessageQueue does not exist\n"); return 1; } fResult = GetMailslotInfo(hSlot, // mailslot handle (LPDWORD) NULL, // no maximum message size &cbMessage, // size of next message &cMessage, // number of messages &to); // retrieves read time-out if (to != timeout){ if (timeout < 0){ to = MAILSLOT_WAIT_FOREVER; } else { to = timeout; } fResult = SetMailslotInfo(hSlot, to); if (JUMP_WIN_DEBUG) { printf("jumpMessageQueueWaitForMessage: read timeout set to %d\n", to); } } if (cMessage > 0) { // there are messages waiting in the MessageQueue return 1; } // Wait for message using blocking read fResult = ReadFile(hSlot, // handle to mailslot &buffer, // buffer to receive data 0, // size of buffer &cbBytes, // number of bytes read NULL); // not overlapped I/O if (fResult == 0) { err = GetLastError(); if (err != ERROR_INSUFFICIENT_BUFFER && err != ERROR_SEM_TIMEOUT) { printf("ERROR: jumpMessageQueueWaitForMessage - error in reading file (%d)\n", err); } } if (JUMP_WIN_DEBUG) { GetMailslotInfo(hSlot, // mailslot handle (LPDWORD) NULL, // no maximum message size &cbMessage, // size of next message &cMessage, // number of messages NULL); // no read time-out printf("jumpMessageQueueWaitForMessage: # of messages in MessageQueue: %d\n", cMessage); } return 0; }
int mailslotRead(HANDLE mailbox, void *msg, int msgSize) { /* Read a msg from a mailslot, return nr */ /* of successful bytes read */ /* Read a msg from a mailslot, return nr */ /* of successful bytes read */ DWORD nextSize, messages, cbRead; BOOL fResult; fResult = GetMailslotInfo(mailbox, (LPDWORD)NULL, &nextSize, &messages, (LPDWORD)NULL); if (!fResult) { MessageBox(NULL, "GetMailslotInfo Error", "Error!!", MB_OK); printf("GetMailslotInfo Error: %d\n", GetLastError()); return 0; } if (messages != 0) { fResult = ReadFile(mailbox, (char*)msg, nextSize, &cbRead, (LPOVERLAPPED)NULL); if (!fResult) { printf("ReadFile Error: %d\n", GetLastError()); MessageBox(NULL, "ReadFile Error", "Error!!", MB_OK); return 0; } return cbRead; } return 0; }
int mailslotRead(HANDLE mailbox, void *msg, int msgSize) { /* Read a msg from a mailslot, return nr */ /* of successful bytes read */ /* Read a msg from a mailslot, return nr */ /* of successful bytes read */ DWORD nextSize, messages, cbRead; BOOL fResult; fResult = GetMailslotInfo(mailbox, (LPDWORD)NULL, &nextSize, &messages, (LPDWORD)NULL); if (!fResult) { printf("GetMailslotInfo Error: %d\n", GetLastError()); return 0; } *((char**)msg) = (char*)calloc(nextSize, sizeof(char)); fResult = ReadFile(mailbox, *((char**)msg), nextSize, &cbRead, (LPOVERLAPPED)NULL); if (!fResult) { printf("ReadFile Error: %d\n", GetLastError()); return 0; } return cbRead; }
int mailslotRead (HANDLE mailbox, void *msg, int msgSize) { /* Read a msg from a mailslot, return nr */ /* of successful bytes read */ DWORD sizeOfNextMessage = MAILSLOT_NO_MESSAGE, nrMessages, nrBytesRead; int fResult; fResult = GetMailslotInfo(mailbox, // mailslot handle (LPDWORD)NULL, // no maximum message size &sizeOfNextMessage, // size of next message &nrMessages, // number of messages (LPDWORD)NULL); // no read time-out if (sizeOfNextMessage > msgSize) return 0; //Buffer overflow ReadFile( mailbox, msg, sizeOfNextMessage, &nrBytesRead, NULL); return nrBytesRead; }
// Repeatedly read input from the input slot. // Returns when last player exits game. void GameServer::run() { DWORD nNextMessageSize, nMessagesLeft, nBytesRead; InputData idMessage; char szBuffer[245]; // Call randomize() in the GameServer's operational thread (usually same thread as main()) myRandomize(); while ( true ) { nMessagesLeft = 0; nNextMessageSize = MAILSLOT_NO_MESSAGE; // Check the status of the slot. GetMailslotInfo(hInputSlot, NULL, &nNextMessageSize, &nMessagesLeft, NULL); // If there's no input, sleep and then return to top of loop. if ( nNextMessageSize == MAILSLOT_NO_MESSAGE ) { Sleep(100); continue; } // If there's a message, read it and process it. if ( nMessagesLeft > 0 ) { // Ignore invalid message sizes (see MS Knowledge Base Q192276) if ( nNextMessageSize < 0 || nNextMessageSize > 500 ) continue; ReadFile(hInputSlot, szBuffer, nNextMessageSize, &nBytesRead, NULL); idMessage = szBuffer; enterCritical(); handleInput(idMessage); leaveCritical(); // If last player just exited, shut down the server. if ( idMessage.nType == IP_FINISHED && nPlayersInGame == 0 ) { CloseHandle(hInputSlot); DeleteCriticalSection(&csCritical); return; } } } }
int jumpMessageQueueReceive(JUMPPlatformCString messageType, char *buffer, int bufferLength) { DWORD cbBytes, cbMessage, cMessage, timeout; BOOL fResult; HANDLE hSlot = mailslotGet(messageType, NULL); if (hSlot == NULL) { printf("ERROR: jumpMessageQueueReceive - MessageQueue does not exists\n"); return 0; } fResult = GetMailslotInfo(hSlot, // mailslot handle (LPDWORD) NULL, // no maximum message size &cbMessage, // size of next message &cMessage, // number of messages (LPDWORD) &timeout); // no read time-out if (JUMP_WIN_DEBUG) { printf("jumpMessageQueueReceive: %d new Messages\n", cMessage); } if (cbMessage > bufferLength) { // buffer smaller than the next message return -1; } //Read client message fResult = ReadFile(hSlot, // handle to mailslot buffer, // buffer to receive data bufferLength, // size of buffer &cbBytes, // number of bytes read NULL); // not overlapped I/O if ( (!fResult) || (0 == cbBytes)) { printf("ERROR: jumpMessageQueueReceive - occurred while reading from the client: %d", GetLastError()); return 0; //Error } else { if (JUMP_WIN_DEBUG) { printf("jumpMessageQueueReceive: ReadFile() was successful.\n"); } } if (JUMP_WIN_DEBUG) { printf("jumpMessageQueueReceive: Client sent the following message: %s\n", buffer); } return cbBytes; //Success }
// Reads text from the output mailslot. bool getOutput() { DWORD nNextMessageSize, nMessagesLeft, nBytesRead; bool bMessagesFound = false; char szBuffer[245]; OutputData odMessage; // Loop as long as there's output do { // If unable to check the mailslot, abort door if ( !GetMailslotInfo(hOutputSlot, NULL, &nNextMessageSize, &nMessagesLeft, NULL) ) exitDoor(2); // If messages left, read them if ( nMessagesLeft > 0 && nNextMessageSize != MAILSLOT_NO_MESSAGE ) { // Ignore invalid message sizes (see MS Knowledge Base Q192276) // In this case, simply wait for getOutput() to be called again next timeslice. if ( nNextMessageSize < 0 || nNextMessageSize > 500 ) return bMessagesFound; if ( !ReadFile(hOutputSlot, szBuffer, nNextMessageSize, &nBytesRead, NULL) ) { local("error reading from slot"); return bMessagesFound; } // Convert the text into an OutputData object odMessage = szBuffer; // Handle the output message handleOutput(odMessage); bMessagesFound = true; nPending = 0; } } while ( nNextMessageSize != MAILSLOT_NO_MESSAGE ); return bMessagesFound; }
int ReadFromMailslot(HANDLE hmailslot, char *buffer, int *size) { DWORD dwMessageSize, dwMessageNum, dwMessageReadSize; BOOL bRes; int i; bRes = GetMailslotInfo(hmailslot,NULL,&dwMessageSize,&dwMessageNum,(LPDWORD)NULL); if(bRes==FALSE || dwMessageSize==MAILSLOT_NO_MESSAGE) return FALSE; for(i=0;i<10;i++){ bRes = ReadFile(hMailslot,buffer,dwMessageSize,&dwMessageReadSize,(LPOVERLAPPED)NULL); #ifdef W32GUI_DEBUG PrintfDebugWnd("[%s]\n",buffer); #endif if(bRes==TRUE){ break; } Sleep(300); } if(bRes==TRUE){ *size = (int)dwMessageSize; return TRUE; } else return FALSE; }
__declspec(dllexport) void __cdecl VDDDispatch(void) { char str[512]; DWORD count; DWORD msgs; int retval; int node_num; BYTE* p; vdd_status_t* status; static DWORD writes; static DWORD bytes_written; static DWORD reads; static DWORD bytes_read; static DWORD inbuf_poll; static DWORD online_poll; static DWORD status_poll; static DWORD vdd_yields; static DWORD vdd_calls; VDD_IO_HANDLERS IOHandlers = { NULL }; static VDD_IO_PORTRANGE PortRange; retval=0; node_num=getBH(); lprintf(LOG_DEBUG,"VDD_OP: (handle=%d) %d (arg=%X)", getAX(),getBL(),getCX()); vdd_calls++; switch(getBL()) { case VDD_OPEN: sscanf("$Revision: 1.40 $", "%*s %s", revision); lprintf(LOG_INFO,"Synchronet Virtual Device Driver, rev %s %s %s" ,revision, __DATE__, __TIME__); #if 0 sprintf(str,"sbbsexec%d.log",node_num); fp=fopen(str,"wb"); #endif sprintf(str,"\\\\.\\mailslot\\sbbsexec\\wr%d",node_num); rdslot=CreateMailslot(str ,0 //LINEAR_RX_BUFLEN /* Max message size (0=any) */ ,MAILSLOT_WAIT_FOREVER /* Read timeout */ ,NULL); if(rdslot==INVALID_HANDLE_VALUE) { lprintf(LOG_ERR,"!VDD_OPEN: Error %d opening %s" ,GetLastError(),str); retval=1; break; } sprintf(str,"\\\\.\\mailslot\\sbbsexec\\rd%d",node_num); wrslot=CreateFile(str ,GENERIC_WRITE ,FILE_SHARE_READ ,NULL ,OPEN_EXISTING ,FILE_ATTRIBUTE_NORMAL ,(HANDLE) NULL); if(wrslot==INVALID_HANDLE_VALUE) { lprintf(LOG_ERR,"!VDD_OPEN: Error %d opening %s" ,GetLastError(),str); retval=2; break; } if(RingBufInit(&rdbuf, RINGBUF_SIZE_IN)!=0) { retval=3; break; } sprintf(str,"sbbsexec_hungup%d",node_num); hungup_event=OpenEvent( EVENT_ALL_ACCESS, /* access flag */ FALSE, /* inherit flag */ str); /* pointer to event-object name */ if(hungup_event==NULL) { lprintf(LOG_ERR,"!VDD_OPEN: Error %d opening %s" ,GetLastError(),str); retval=4; break; } sprintf(str,"sbbsexec_hangup%d",node_num); hangup_event=OpenEvent( EVENT_ALL_ACCESS, /* access flag */ FALSE, /* inherit flag */ str); /* pointer to event-object name */ if(hangup_event==NULL) { lprintf(LOG_WARNING,"!VDD_OPEN: Error %d opening %s" ,GetLastError(),str); } status_poll=0; inbuf_poll=0; online_poll=0; yields=0; lprintf(LOG_INFO,"Yield interval: %f milliseconds", yield_interval); if(virtualize_uart) { lprintf(LOG_INFO,"Virtualizing UART (0x%x, IRQ %u)" ,uart_io_base, uart_irq); IOHandlers.inb_handler = uart_rdport; IOHandlers.outb_handler = uart_wrport; PortRange.First=uart_io_base; PortRange.Last=uart_io_base + UART_IO_RANGE; VDDInstallIOHook((HANDLE)getAX(), 1, &PortRange, &IOHandlers); interrupt_event=CreateEvent(NULL,FALSE,FALSE,NULL); InitializeCriticalSection(&interrupt_mutex); _beginthread(interrupt_thread, 0, NULL); } lprintf(LOG_DEBUG,"VDD_OPEN: Opened successfully (wrslot=%p)", wrslot); _beginthread(input_thread, 0, NULL); retval=0; break; case VDD_CLOSE: lprintf(LOG_INFO,"VDD_CLOSE: rdbuf=%u " "status_poll=%u inbuf_poll=%u online_poll=%u yields=%u vdd_yields=%u vdd_calls=%u" ,RingBufFull(&rdbuf),status_poll,inbuf_poll,online_poll ,yields,vdd_yields,vdd_calls); lprintf(LOG_INFO," read=%u bytes (in %u calls)",bytes_read,reads); lprintf(LOG_INFO," wrote=%u bytes (in %u calls)",bytes_written,writes); if(virtualize_uart) { lprintf(LOG_INFO,"Uninstalling Virtualizaed UART IO Hook"); VDDDeInstallIOHook((HANDLE)getAX(), 1, &PortRange); } CloseHandle(rdslot); CloseHandle(wrslot); if(hungup_event!=NULL) CloseHandle(hungup_event); if(hangup_event!=NULL) CloseHandle(hangup_event); #if 0 /* This isn't strictly necessary... and possibly the cause of a NULL dereference in the input_thread */ RingBufDispose(&rdbuf); #endif status_poll=0; retval=0; break; case VDD_READ: count = getCX(); if(count != 1) lprintf(LOG_DEBUG,"VDD_READ of %d",count); p = (BYTE*) GetVDMPointer((ULONG)((getES() << 16)|getDI()) ,count,FALSE); retval=vdd_read(p, count); reads++; bytes_read+=retval; reset_yield(); break; case VDD_PEEK: count = getCX(); if(count != 1) lprintf(LOG_DEBUG,"VDD_PEEK of %d",count); p = (BYTE*) GetVDMPointer((ULONG)((getES() << 16)|getDI()) ,count,FALSE); retval=RingBufPeek(&rdbuf,p,count); reset_yield(); break; case VDD_WRITE: count = getCX(); if(count != 1) lprintf(LOG_DEBUG,"VDD_WRITE of %d",count); p = (BYTE*) GetVDMPointer((ULONG)((getES() << 16)|getDI()) ,count,FALSE); if(!WriteFile(wrslot,p,count,&retval,NULL)) { lprintf(LOG_ERR,"!VDD_WRITE: WriteFile Error %d (size=%d)" ,GetLastError(),retval); retval=0; } else { writes++; bytes_written+=retval; reset_yield(); } break; case VDD_STATUS: status_poll++; count = getCX(); if(count != sizeof(vdd_status_t)) { lprintf(LOG_DEBUG,"!VDD_STATUS: wrong size (%d!=%d)",count,sizeof(vdd_status_t)); retval=sizeof(vdd_status_t); break; } status = (vdd_status_t*) GetVDMPointer((ULONG)((getES() << 16)|getDI()) ,count,FALSE); status->inbuf_size=RINGBUF_SIZE_IN; status->inbuf_full=RingBufFull(&rdbuf); msgs=0; /* OUTBUF FULL/SIZE */ if(!GetMailslotInfo( wrslot, /* mailslot handle */ &status->outbuf_size, /* address of maximum message size */ &status->outbuf_full, /* address of size of next message */ &msgs, /* address of number of messages */ NULL /* address of read time-out */ )) { lprintf(LOG_ERR,"!VDD_STATUS: GetMailSlotInfo(%p) failed, error %u (msgs=%u, inbuf_full=%u, inbuf_size=%u)" ,wrslot ,GetLastError(), msgs, status->inbuf_full, status->inbuf_size); status->outbuf_full=0; status->outbuf_size=DEFAULT_MAX_MSG_SIZE; } else lprintf(LOG_DEBUG,"VDD_STATUS: MailSlot maxmsgsize=%u, nextmsgsize=%u, msgs=%u" ,status->outbuf_size ,status->outbuf_full ,msgs); if(status->outbuf_full==MAILSLOT_NO_MESSAGE) status->outbuf_full=0; status->outbuf_full*=msgs; /* ONLINE */ if(WaitForSingleObject(hungup_event,0)==WAIT_OBJECT_0) status->online=0; else status->online=1; retval=0; /* success */ break; case VDD_INBUF_PURGE: RingBufReInit(&rdbuf); retval=0; break; case VDD_OUTBUF_PURGE: lprintf(LOG_WARNING,"!VDD_OUTBUF_PURGE: NOT IMPLEMENTED"); retval=0; break; case VDD_INBUF_FULL: retval=RingBufFull(&rdbuf); inbuf_poll++; break; case VDD_INBUF_SIZE: retval=RINGBUF_SIZE_IN; break; case VDD_OUTBUF_FULL: if(!GetMailslotInfo( wrslot, /* mailslot handle */ NULL, /* address of maximum message size */ &retval, /* address of size of next message */ &msgs, /* address of number of messages */ NULL /* address of read time-out */ )) retval=0; if(retval==MAILSLOT_NO_MESSAGE) retval=0; retval*=msgs; break; case VDD_OUTBUF_SIZE: if(!GetMailslotInfo( wrslot, /* mailslot handle */ &retval, /* address of maximum message size */ NULL, /* address of size of next message */ NULL, /* address of number of messages */ NULL /* address of read time-out */ )) retval=DEFAULT_MAX_MSG_SIZE; break; case VDD_ONLINE: if(WaitForSingleObject(hungup_event,0)==WAIT_OBJECT_0) retval=0; else retval=1; online_poll++; break; case VDD_YIELD: /* forced yield */ vdd_yields++; yield(); break; case VDD_MAYBE_YIELD: /* yield if YieldInterval is enabled and expired */ maybe_yield(); break; case VDD_LOAD_INI_FILE: /* Load and parse settings file */ { FILE* fp; char cwd[MAX_PATH+1]; /* Load exec/sbbsexec.ini first (setting default values) */ count = getCX(); p = (BYTE*)GetVDMPointer((ULONG)((getES() << 16)|getDI()) ,count,FALSE); iniFileName(ini_fname, sizeof(ini_fname), p, INI_FILENAME); if((fp=fopen(ini_fname,"r"))!=NULL) { ini=iniReadFile(fp); fclose(fp); parse_ini(ROOT_SECTION); } /* Load cwd/sbbsexec.ini second (over-riding default values) */ GetCurrentDirectory(sizeof(cwd),cwd); iniFileName(ini_fname, sizeof(ini_fname), cwd, INI_FILENAME); if((fp=fopen(ini_fname,"r"))!=NULL) { ini=iniReadFile(fp); fclose(fp); parse_ini(ROOT_SECTION); } } break; case VDD_LOAD_INI_SECTION: /* Parse (program-specific) sub-section of settings file */ count = getCX(); p = (BYTE*)GetVDMPointer((ULONG)((getES() << 16)|getDI()) ,count,FALSE); parse_ini(p); break; case VDD_DEBUG_OUTPUT: /* Send string to debug output */ count = getCX(); p = (BYTE*)GetVDMPointer((ULONG)((getES() << 16)|getDI()) ,count,FALSE); lputs(LOG_INFO, p); break; case VDD_HANGUP: hangup(); break; default: lprintf(LOG_ERR,"!UNKNOWN VDD_OP: %d",getBL()); break; } setAX((WORD)retval); }
// Função para leitura de um mailslot. Recebe como parâmetros o handle do mailslot em questão // e um buffer para receber a mensagem lida. // Adapatada da função ReadSlot do MSDN: // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365785%28v=vs.85%29.aspx BOOL ReadSlot(HANDLE hSlot, char* outStr) // Foi adicionado o parâmetro do HANDLE, para poder diferenciar // entre os mailslots criados. Foi também adicionado um vetor // de saída, para transportar a mensagem. { DWORD cbMessage, cMessage, cbRead; BOOL fResult; LPTSTR lpszBuffer; TCHAR achID[80]; DWORD cAllMessages; HANDLE hEvent; OVERLAPPED ov; cbMessage = cMessage = cbRead = 0; hEvent = CreateEvent(NULL, FALSE, FALSE, TEXT("hMailSlot")); if( NULL == hEvent ) return FALSE; ov.Offset = 0; ov.OffsetHigh = 0; ov.hEvent = hEvent; fResult = GetMailslotInfo( hSlot, // mailslot handle (LPDWORD) NULL, // no maximum message size &cbMessage, // size of next message &cMessage, // number of messages (LPDWORD) NULL); // no read time-out if (!fResult) { printf("GetMailslotInfo failed with %d.\n", GetLastError()); return FALSE; } if (cbMessage == MAILSLOT_NO_MESSAGE) { printf("Waiting for a message...\n"); return TRUE; } cAllMessages = cMessage; while (cMessage != 0) // retrieve all messages { // Create a message-number string. StringCchPrintf((LPTSTR) achID, 80, TEXT("\nMessage #%d of %d\n"), cAllMessages - cMessage + 1, cAllMessages); // Allocate memory for the message. lpszBuffer = (LPTSTR) GlobalAlloc(GPTR, lstrlen((LPTSTR) achID)*sizeof(TCHAR) + cbMessage); if( NULL == lpszBuffer ) return FALSE; lpszBuffer[0] = '\0'; fResult = ReadFile(hSlot, lpszBuffer, cbMessage, &cbRead, &ov); if (!fResult) { printf("ReadFile failed with %d.\n", GetLastError()); GlobalFree((HGLOBAL) lpszBuffer); return FALSE; } // Concatenate the message and the message-number string. StringCbCat(lpszBuffer, lstrlen((LPTSTR) achID)*sizeof(TCHAR)+cbMessage, (LPTSTR) achID); // Display the message. //_tprintf(TEXT("Contents of the mailslot: %s\n"), lpszBuffer); strcpy_s(outStr, 100, lpszBuffer); fResult = GetMailslotInfo(hSlot, // mailslot handle (LPDWORD) NULL, // no maximum message size &cbMessage, // size of next message &cMessage, // number of messages (LPDWORD) NULL); // no read time-out if (!fResult) { printf("GetMailslotInfo failed (%d)\n", GetLastError()); return FALSE; } } CloseHandle(hEvent); return TRUE; }
//Return FALSE if no message is available //Return TRUE and write the output to message in case of no error. BOOL ReadSlot(HANDLE hSlot, char* message) { DWORD cbMessage, cMessage, cbRead; BOOL fResult; LPTSTR lpszBuffer; TCHAR achID[80]; DWORD cAllMessages; HANDLE hEvent; OVERLAPPED ov; //Clear message contents message[0] = '\0'; cbMessage = cMessage = cbRead = 0; hEvent = CreateEvent(NULL, FALSE, FALSE, TEXT("ExampleSlot")); if( NULL == hEvent ) return FALSE; ov.Offset = 0; ov.OffsetHigh = 0; ov.hEvent = hEvent; fResult = GetMailslotInfo( hSlot, // mailslot handle (LPDWORD) NULL, // no maximum message size &cbMessage, // size of next message &cMessage, // number of messages (LPDWORD) NULL); // no read time-out if (!fResult) { std::cout << "GetMailslotInfo failed." << std::endl; return FALSE; } if (cbMessage == MAILSLOT_NO_MESSAGE) { //std::cout << "Waiting for a message..." << std::endl; return FALSE; } cAllMessages = cMessage; if (cMessage != 0) { while (cMessage != 0) // retrieve all messages { // Allocate memory for the message. lpszBuffer = (LPTSTR) GlobalAlloc(GPTR, lstrlen((LPTSTR) achID)*sizeof(TCHAR) + cbMessage); if( NULL == lpszBuffer ) return FALSE; lpszBuffer[0] = '\0'; fResult = ReadFile(hSlot, lpszBuffer, cbMessage, &cbRead, &ov); if (!fResult) { std::cout << "ReadFile failed." << std::endl; GlobalFree((HGLOBAL) lpszBuffer); return FALSE; } // Write the message. strcpy_s(message, 1024, lpszBuffer); //std::cout << message << std::endl; GlobalFree((HGLOBAL) lpszBuffer); fResult = GetMailslotInfo(hSlot, // mailslot handle (LPDWORD) NULL, // no maximum message size &cbMessage, // size of next message &cMessage, // number of messages (LPDWORD) NULL); // no read time-out if (!fResult) { std::cout << "GetMailslotInfo failed." << std::endl; return FALSE; } } CloseHandle(hEvent); return TRUE; } CloseHandle(hEvent); return FALSE; }
int msgRead(HANDLE hSlot) { TCHAR eventNameTCHAR[STR_SIZE]; char eventName[STR_SIZE]; DWORD cbMessage, cMessage, cbRead; BOOL fResult; int receivedMsg; HANDLE hEvent; OVERLAPPED ov; cbMessage = cMessage = cbRead = 0; sprintf(eventName,"%d_event",GetCurrentProcessId()); charToTCHAR(eventNameTCHAR, eventName); hEvent = CreateEvent(NULL, FALSE, FALSE, eventNameTCHAR); if( NULL == hEvent ) return FALSE; ov.Offset = 0; ov.OffsetHigh = 0; ov.hEvent = hEvent; fResult = GetMailslotInfo(hSlot, // mailslot handle (LPDWORD) NULL, // no maximum message size &cbMessage, // size of next message &cMessage, // number of messages (LPDWORD) NULL); // no read time-out if (!fResult) { printf("GetMailslotInfo failed with %d.\n", GetLastError()); exit(0); } if (cbMessage == MAILSLOT_NO_MESSAGE) { /*no message in the mail box*/ return MSG_NO_MESSAGE; } /*with the way we set up the mail box, there should only be 1 message waiting*/ if(cMessage!=1) { printf("ERROR messaging system is not synchronized\n"); exit(0); } if(cbMessage!=4) { printf("ERROR message size is incorrect\n"); exit(0); } /*retrieve the message*/ fResult = ReadFile(hSlot, &receivedMsg, cbMessage, &cbRead, &ov); if (!fResult) { printf("ReadFile failed with %d.\n", GetLastError()); exit(0); } CloseHandle(hEvent); return receivedMsg; }
//MailSlot of flush DNS cache Monitor bool __fastcall FlushDNSMailSlotMonitor( void) { //System security setting std::shared_ptr<SECURITY_ATTRIBUTES> SecurityAttributes(new SECURITY_ATTRIBUTES()); std::shared_ptr<SECURITY_DESCRIPTOR> SecurityDescriptor(new SECURITY_DESCRIPTOR()); std::shared_ptr<char> ACL_Buffer(new char[PACKET_MAXSIZE]()); memset(ACL_Buffer.get(), 0, PACKET_MAXSIZE); PSID SID_Value = nullptr; InitializeSecurityDescriptor(SecurityDescriptor.get(), SECURITY_DESCRIPTOR_REVISION); InitializeAcl((PACL)ACL_Buffer.get(), PACKET_MAXSIZE, ACL_REVISION); ConvertStringSidToSidW(SID_ADMINISTRATORS_GROUP, &SID_Value); AddAccessAllowedAce((PACL)ACL_Buffer.get(), ACL_REVISION, GENERIC_ALL, SID_Value); SetSecurityDescriptorDacl(SecurityDescriptor.get(), true, (PACL)ACL_Buffer.get(), false); SecurityAttributes->lpSecurityDescriptor = SecurityDescriptor.get(); SecurityAttributes->bInheritHandle = true; //Create mailslot. HANDLE hSlot = CreateMailslotW(MAILSLOT_NAME, PACKET_MAXSIZE - 1U, MAILSLOT_WAIT_FOREVER, SecurityAttributes.get()); if (hSlot == INVALID_HANDLE_VALUE) { LocalFree(SID_Value); PrintError(LOG_ERROR_SYSTEM, L"Create mailslot error", GetLastError(), nullptr, 0); return false; } ACL_Buffer.reset(); LocalFree(SID_Value); //Initialization BOOL Result = FALSE; bool FlushDNS = false; DWORD cbMessage = 0, cMessage = 0, cbRead = 0; std::shared_ptr<wchar_t> lpszBuffer(new wchar_t[PACKET_MAXSIZE]()); wmemset(lpszBuffer.get(), 0, PACKET_MAXSIZE); //MailSlot Monitor for (;;) { cbMessage = 0; cMessage = 0; //Get mailslot messages. Result = GetMailslotInfo(hSlot, nullptr, &cbMessage, &cMessage, nullptr); if (Result == FALSE) { PrintError(LOG_ERROR_SYSTEM, L"Mailslot Monitor initialization error", GetLastError(), nullptr, 0); CloseHandle(hSlot); return false; } //Wait for messages. if (cbMessage == MAILSLOT_NO_MESSAGE) { Sleep(LOOP_INTERVAL_TIME_MONITOR); continue; } //Got messages. FlushDNS = false; while (cMessage > 0) { Result = ReadFile(hSlot, lpszBuffer.get(), cbMessage, &cbRead, nullptr); if (Result == FALSE) { PrintError(LOG_ERROR_SYSTEM, L"MailSlot read messages error", GetLastError(), nullptr, 0); CloseHandle(hSlot); return false; } if (!FlushDNS && memcmp(lpszBuffer.get(), MAILSLOT_MESSAGE_FLUSH_DNS, wcslen(MAILSLOT_MESSAGE_FLUSH_DNS)) == EXIT_SUCCESS) { FlushDNS = true; FlushAllDNSCache(); } memset(lpszBuffer.get(), 0, PACKET_MAXSIZE); //Get other mailslot messages. Result = GetMailslotInfo(hSlot, nullptr, &cbMessage, &cMessage, nullptr); if (Result == FALSE) { PrintError(LOG_ERROR_SYSTEM, L"Mailslot Monitor initialization error", GetLastError(), nullptr, 0); CloseHandle(hSlot); return false; } } Sleep(LOOP_INTERVAL_TIME_MONITOR); } //Monitor terminated CloseHandle(hSlot); PrintError(LOG_ERROR_SYSTEM, L"MailSlot module Monitor terminated", 0, nullptr, 0); return false; }
BOOL UMailSlot::read(LPTSTR sMessage) { if (m_hObj == INVALID_HANDLE_VALUE) return FALSE; DWORD cbMessageBytes = 0; // Size of the message in bytes DWORD cbBytesRead = 0; // Number of bytes read from the slot DWORD cMessages = 0; // Number of messages in the mailslot DWORD nMessageId = 0; // Message ID BOOL bResult; LPTSTR lpszBuffer; // A buffer used to store one message ///////////////////////////////////////////////////////////////////////// // Check for the number of messages in the mailslot. // bResult = GetMailslotInfo( m_hObj, // Handle of the mailslot NULL, // No maximum message size &cbMessageBytes, // Size of next message &cMessages, // Number of messages NULL); // No read time-out if (!bResult) { _tprintf(_T("GetMailslotInfo failed w/err 0x%08lx\n"), GetLastError()); return FALSE; } if (cbMessageBytes == MAILSLOT_NO_MESSAGE) { // There are no new messages in the mailslot at present _putts(_T("No new messages.")); return TRUE; } ///////////////////////////////////////////////////////////////////////// // Retrieve the messages one by one from the mailslot. // while (cMessages != 0) // If there are still un-read messages in the slot { nMessageId++; // Allocate the memory for the message based on its size info, // cbMessageBytes, which was retrieved from GetMailslotInfo. lpszBuffer = (LPTSTR) GlobalAlloc(GPTR, cbMessageBytes); if (NULL == lpszBuffer) return FALSE; bResult = ReadFile( // Read from the mailslot. m_hObj, // Handle of the slot lpszBuffer, // Buffer to receive data cbMessageBytes, // Size of buffer in bytes &cbBytesRead, // Number of bytes read NULL); // Not overlapped I/O if (!bResult) { _tprintf(_T("ReadFile failed w/err 0x%08lx\n"), GetLastError()); GlobalFree((HGLOBAL)lpszBuffer); return FALSE; } // Display the message. _tprintf(_T("Message #%ld: %s\n"), nMessageId, lpszBuffer); GlobalFree((HGLOBAL) lpszBuffer); // Free the buffer // Get the current number of un-read messages in the slot. The number // may not equal the initial message number because new messages may // arrive while we are reading the items in the slot. bResult = GetMailslotInfo( m_hObj, // Handle of the mailslot NULL, // No maximum message size &cbMessageBytes, // Size of next message &cMessages, // Number of messages NULL); // No read time-out if (!bResult) { _tprintf(_T("GetMailslotInfo failed w/err 0x%08lx\n"), GetLastError()); return FALSE; } } return TRUE; }
static int mailslot_test(void) { HANDLE hSlot, hSlot2, hWriter, hWriter2; unsigned char buffer[16]; DWORD count, dwMax, dwNext, dwMsgCount, dwTimeout; /* 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 = CreateFile(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 = CreateMailslot( "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 = CreateMailslot( 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 = CreateMailslot( 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 = CreateMailslot( szmspath, 0, 0, NULL ); ok( hSlot != INVALID_HANDLE_VALUE , "valid mailslot failed\n"); /* try and read/write to it */ count = 0; memset(buffer, 0, sizeof buffer); ok( !ReadFile( hSlot, buffer, sizeof buffer, &count, NULL), "slot read\n"); ok( !WriteFile( hSlot, buffer, sizeof buffer, &count, NULL), "slot write\n"); /* now try and openthe client, but with the wrong sharing mode */ hWriter = CreateFile(szmspath, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); ok( hWriter == INVALID_HANDLE_VALUE, "bad sharing mode\n"); ok( GetLastError() == ERROR_SHARING_VIOLATION, "error should be ERROR_SHARING_VIOLATION\n"); /* now open the client with the correct sharing mode */ hWriter = CreateFile(szmspath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); ok( hWriter != INVALID_HANDLE_VALUE, "existing mailslot\n"); /* * opening a client should make no difference to * whether we can read or write the mailslot */ ok( !ReadFile( hSlot, buffer, sizeof buffer/2, &count, NULL), "slot read\n"); ok( !WriteFile( hSlot, buffer, sizeof buffer/2, &count, NULL), "slot write\n"); /* * 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( 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"); /* * 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 */ ok( !ReadFile( hSlot, buffer, sizeof buffer, &count, NULL), "slot read\n"); /* now try open another writer... should fail */ hWriter2 = CreateFile(szmspath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); ok( hWriter2 == INVALID_HANDLE_VALUE, "two writers\n"); /* now try open another as a reader ... also fails */ hWriter2 = CreateFile(szmspath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); ok( hWriter2 == INVALID_HANDLE_VALUE, "writer + reader\n"); /* now try open another as a writer ... still fails */ hWriter2 = CreateFile(szmspath, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); ok( hWriter2 == INVALID_HANDLE_VALUE, "writer\n"); /* now open another one */ hSlot2 = CreateMailslot( 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 = CreateFile(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 = CreateFile(szmspath, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); ok( hWriter2 == INVALID_HANDLE_VALUE, "greedy writer succeeded\n"); /* now try open another as a writer ... and share with the first */ hWriter2 = CreateFile(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 */ ok( !ReadFile( hSlot, buffer, sizeof buffer, &count, NULL), "slot read\n"); /* 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"); todo_wine { 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"); todo_wine { ok( dwMsgCount == 3, "dwMsgCount incorrect\n"); } 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"); todo_wine { ok( dwMsgCount == 2, "dwMsgCount incorrect\n"); } /* 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"); todo_wine { ok( dwNext == 0, "dwNext incorrect\n"); ok( dwMsgCount == 1, "dwMsgCount incorrect\n"); } /* read the 3rd (zero length) message */ todo_wine { 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 */ ok( !ReadFile( hSlot, buffer, sizeof buffer, &count, NULL), "3rd slot read succeeded\n"); /* 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"); return 0; }
DWORD WINAPI MailslotThread(LPVOID pData) { HANDLE hSlot; // Handle for the Mailslot hSlot = CreateMailslot(NIFTYKB_MAILSLOT_PATH, 0, // no max msg size MAILSLOT_WAIT_FOREVER, (LPSECURITY_ATTRIBUTES)NULL); // default security if (hSlot == INVALID_HANDLE_VALUE) { ts3Functions.logMessage("Failed CreateMailslot", LogLevel_ERROR, "NiftyKb Plugin", 0); return PLUGIN_ERROR_CREATESLOT_FAILED; } ts3Functions.logMessage("Mailslot Created", LogLevel_INFO, "NiftyKb Plugin", 0); // While the plugin is running while (pluginRunning) { //DWORD timerWait = MsgWaitForMultipleObjects(1, &hPttDelayTimer, FALSE, PLUGIN_THREAD_TIMEOUT, QS_ALLINPUT); //if (timerWait == WAIT_FAILED) { // break; //} //if (timerWait == WAIT_OBJECT_0) { // PTTDelayCallback(NULL, 0, 0); //} DWORD messageSize, messageCount, messageBytesRead; char *messageStr, *arg; DWORD messageTimeout = PLUGIN_THREAD_TIMEOUT; BOOL ok; ok = GetMailslotInfo(hSlot, (LPDWORD)NULL, // No max size &messageSize, &messageCount, (LPDWORD)NULL); //&messageTimeout); if (!ok) { DWORD err = GetLastError(); if (err == WAIT_TIMEOUT) { continue; } ts3Functions.logMessage("Failed GetMailslotInfo", LogLevel_ERROR, "NiftyKb Plugin", 0); return PLUGIN_ERROR_READ_FAILED; } if (messageSize == MAILSLOT_NO_MESSAGE) { ::SleepEx(5, TRUE); // allow timers to fire continue; } // Retrieve message messageStr = (LPTSTR)malloc(messageSize + 1); ok = ReadFile(hSlot, messageStr, messageSize, &messageBytesRead, NULL); // not overlapped i/o if (!ok || messageBytesRead == 0) { ts3Functions.logMessage("Failed mailslot ReadFile", LogLevel_ERROR, "NiftyKb Plugin", 0); return PLUGIN_ERROR_READ_FAILED; } // Separate the argument from the command arg = strchr(messageStr, ' '); if (arg != NULL) { // Split the string by inserting a NULL-terminator *arg = (char)NULL; arg++; } // Parse debug string ParseCommand(messageStr, arg); // Free the debug string free(messageStr); } return PLUGIN_ERROR_NONE; }