SmsFilter/IPCQueue.h
#pragma once
#pragma warning(push, 3)
#include <Windows.h>
#include <msgqueue.h>
#pragma warning(pop)
#include "IPCMsg.h"
#define MICRO_SLEEP 350
#define MAX_TIMEOUT 3 * 60 * 1000 // 3 Minuti di attesa massima
class IPCQueue
{
private:
HANDLE hQueue;
MSGQUEUEOPTIONS qOpts;
LPWSTR lpwName;
public:
IPCQueue(LPWSTR Name, bool bRead)
: hQueue(INVALID_HANDLE_VALUE), lpwName(NULL)
{
ZeroMemory(&qOpts, sizeof(qOpts));
qOpts.dwSize = sizeof(MSGQUEUEOPTIONS);
qOpts.dwFlags = MSGQUEUE_NOPRECOMMIT | MSGQUEUE_ALLOW_BROKEN;
qOpts.cbMaxMessage = 1024 * 4;
qOpts.dwMaxMessages = 0;
qOpts.bReadAccess = FALSE;
if (bRead)
qOpts.bReadAccess = TRUE;
lpwName = wcsdup(Name);
}
virtual ~IPCQueue(void)
{
if (lpwName)
free(lpwName);
if (hQueue != INVALID_HANDLE_VALUE)
CloseMsgQueue(hQueue);
}
bool Open()
{
hQueue = CreateMsgQueue(lpwName, &qOpts);
if (hQueue == NULL)
{
// WCHAR str[256] = {0};
//wsprintf(str, L"WriteMsgQueue ERROR %d", GetLastError());
// MessageBox(NULL, str, L"DEBUG", MB_OK);
return false;
}
return true;
}
LPBYTE Read(LPBYTE lpBuf, DWORD cbSize, LPDWORD lpcbNumberOfBytesRead, DWORD dwTimeout = 0)
{
if (lpBuf == NULL)
{
(*lpcbNumberOfBytesRead) = 0;
return NULL;
}
DWORD dwFlags = 0;
BOOL bOk = ReadMsgQueue(hQueue, lpBuf, cbSize, lpcbNumberOfBytesRead, dwTimeout, &dwFlags);
if (bOk == FALSE)
{
DWORD dwErr = GetLastError();
switch (dwErr)
{
case ERROR_TIMEOUT:
break;
default:
// wprintf(L"ReadMsgQueue failed [ERROR %08x]\n", GetLastError());
break;
}
(*lpcbNumberOfBytesRead) = 0;
}
return lpBuf;
}
bool Write(LPBYTE lpData, DWORD cbSize, DWORD dwTimeout = 1000)
{
if (lpData == NULL)
return false;
// MessageBox(NULL, L"Writing message to queue.", L"DEBUG", MB_OK);
BOOL bOk = WriteMsgQueue(hQueue, lpData, cbSize, dwTimeout, 0);
if (bOk == FALSE)
{
//WCHAR str[256] = {0};
//wsprintf(str, L"WriteMsgQueue ERROR %d", GetLastError());
// MessageBox(NULL, str, L"DEBUG", MB_OK);
return false;
}
// MessageBox(NULL, L"Message written to queue.", L"DEBUG", MB_OK);
return true;
}
IPCMsg* WaitForReply()
{
DWORD cbNumberOfBytesRead = 0;
LPBYTE lpData = (LPBYTE) LocalAlloc(LPTR, 1024);
for (UINT i = 0; i < MAX_TIMEOUT / MICRO_SLEEP; i++) // 10 seconds of waiting
{
lpData = Read(lpData, 1024, &cbNumberOfBytesRead);
if (cbNumberOfBytesRead != 0)
break;
Sleep(MICRO_SLEEP);
}
if (lpData == NULL)
return NULL;
return IPCMsg::UnserializeReply(lpData, cbNumberOfBytesRead);
}
bool WriteMessage(IPCMsg* message)
{
DWORD cbSize = 0;
LPBYTE lpData = message->Serialize(&cbSize);
if (lpData == NULL)
return false;
for (UINT i = 0; i < 20; i++)
{
if (Write(lpData, cbSize) == true)
{
delete[] lpData;
return true;
}
Sleep(MICRO_SLEEP);
}
delete[] lpData;
return false;
}
};