#include <aclapi.h>
Pipe::Pipe()
{
_Handle = NULL;
}
Pipe::~Pipe()
{
ClosePipe();
}
void Pipe::ClosePipe()
{
if(_Handle != NULL)
{
FlushFileBuffers(_Handle);
DisconnectNamedPipe(_Handle);
CloseHandle(_Handle);
_Handle = NULL;
}
}
void Pipe::CreatePipe(const String &PipeName)
{
ClosePipe();
const UINT PipeBufferSize = 100000;
DWORD dwRes;
PSID pEveryoneSID = NULL, pAdminSID = NULL;
PACL pACL = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
EXPLICIT_ACCESS ea[1];
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
SECURITY_ATTRIBUTES Attributes;
HKEY hkSub = NULL;
BOOL Success = AllocateAndInitializeSid(&SIDAuthWorld, 1,
SECURITY_WORLD_RID,
0, 0, 0, 0, 0, 0, 0,
&pEveryoneSID);
Assert(Success != FALSE, "AllocateAndInitializeSid failed in Pipe::CreatePipe");
ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
ea[0].grfAccessPermissions = FILE_ALL_ACCESS;
ea[0].grfAccessMode = SET_ACCESS;
ea[0].grfInheritance= NO_INHERITANCE;
ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea[0].Trustee.ptstrName = (LPTSTR) pEveryoneSID;
dwRes = SetEntriesInAcl(1, ea, NULL, &pACL);
Assert(dwRes == ERROR_SUCCESS, "SetEntriesInAcl failed in Pipe::CreatePipe");
pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
Assert(pSD != NULL, "LocalAlloc failed in Pipe::CreatePipe");
Success = InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
Assert(Success != FALSE, "InitializeSecurityDescriptor failed in Pipe::CreatePipe");
Success = SetSecurityDescriptorDacl(pSD,
TRUE, pACL,
FALSE);
Assert(Success != FALSE, "SetSecurityDescriptorDacl failed in Pipe::CreatePipe");
Attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
Attributes.lpSecurityDescriptor = pSD;
Attributes.bInheritHandle = FALSE;
String FullPipeName = String("\\\\.\\pipe\\") + PipeName;
_Handle = CreateNamedPipe(
FullPipeName.CString(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, PipeBufferSize, PipeBufferSize, NMPWAIT_USE_DEFAULT_WAIT, &Attributes); Assert(_Handle != INVALID_HANDLE_VALUE, "CreateNamedPipe failed in Pipe::CreatePipe");
BOOL Connected = (ConnectNamedPipe(_Handle, NULL) != 0);
Assert(Connected != FALSE, "ConnectNamedPipe failed in Pipe::CreatePipe");
}
void Pipe::ConnectToLocalPipe(const String &PipeName)
{
ConnectToPipe(String("\\\\.\\pipe\\") + PipeName);
}
void Pipe::ConnectToPipe(const String &PipeName)
{
ClosePipe();
bool Done = false;
while(!Done)
{
_Handle = CreateFile(
PipeName.CString(), GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, 0, NULL); if(_Handle != INVALID_HANDLE_VALUE)
{
Done = true;
}
Sleep(100);
}
DWORD Mode = PIPE_READMODE_MESSAGE;
BOOL Success = SetNamedPipeHandleState(
_Handle, &Mode, NULL, NULL); Assert(Success != FALSE, "SetNamedPipeHandleState failed in Pipe::ConnectToPipe");
}
bool Pipe::MessagePresent()
{
Assert(_Handle != NULL, "Pipe invalid in Pipe::MessagePresent");
DWORD BytesReady = 0;
BOOL Success = PeekNamedPipe(
_Handle,
NULL,
0,
NULL,
&BytesReady,
NULL);
Assert(Success != FALSE, "PeekNamedPipe failed in Pipe::MessagePresent");
return (BytesReady > 0);
}
bool Pipe::ReadMessage(Vector<BYTE> &Message)
{
Assert(_Handle != NULL, "Pipe invalid in Pipe::ReadMessage");
DWORD BytesReady = 0;
BOOL Success = PeekNamedPipe(
_Handle,
NULL,
0,
NULL,
&BytesReady,
NULL);
Assert(Success != FALSE, "PeekNamedPipe failed in Pipe::ReadMessage");
Message.Allocate(BytesReady);
if(BytesReady == 0)
{
return false;
}
DWORD BytesRead;
Success = ReadFile(
_Handle, Message.CArray(), Message.Length(), &BytesRead, NULL); Assert(Success != FALSE && BytesRead > 0, "ReadFile failed in Pipe::ReadMessage");
return true;
}
void Pipe::SendMessage(const Vector<BYTE> &Message)
{
SendMessage(Message.CArray(), Message.Length());
}
void Pipe::SendMessage(const BYTE *Message, UINT MessageLength)
{
Assert(_Handle != NULL, "Pipe invalid in Pipe::SendMessage");
DWORD BytesWritten;
BOOL Success = WriteFile(
_Handle, Message, MessageLength, &BytesWritten, NULL); Assert(Success != FALSE, "WriteFile failed in Pipe::ReadMessage");
Assert(BytesWritten == MessageLength, "WriteFile failed to send entire message in Pipe::ReadMessage");
}
UINT Pipe::ActiveInstances()
{
Assert(_Handle != NULL, "Pipe invalid in Pipe::ActiveInstances");
DWORD Instances;
BOOL Success = GetNamedPipeHandleState(
_Handle,
NULL,
&Instances,
NULL,
NULL,
NULL,
0);
Assert(Success != FALSE, "GetNamedPipeHandleState failed in Pipe::ActiveInstances");
return Instances;
}
String Pipe::UserName()
{
Assert(_Handle != NULL, "Pipe invalid in Pipe::UserName");
char Buffer[512];
BOOL Success = GetNamedPipeHandleState(
_Handle,
NULL,
NULL,
NULL,
NULL,
Buffer,
512);
Assert(Success != FALSE, "GetNamedPipeHandleState failed in Pipe::UserName");
return String(Buffer);
}