home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 31
/
CDASC_31_1996_juillet_aout.iso
/
vrac
/
cuj0796.zip
/
HEYMAN.ZIP
/
NMPIPE.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1996-05-08
|
7KB
|
312 lines
#include <stdio.h>
#include <stdarg.h>
#include <windows.h>
#include "nmpipe.h"
#ifdef REPORT_ERRORS
#define REPORT (printf)
#else
inline void REPORT(...) { }
#endif
nmpipe_cNamedPipe::nmpipe_cNamedPipe()
: hPipe(INVALID_HANDLE_VALUE)
, bInError(FALSE)
{
memset(&Overlap, 0, sizeof(Overlap));
Overlap.hEvent = CreateEvent(NULL,
FALSE, // Event semaphore resets itself automatically.
FALSE, // It is initially in an unsignaled state.
NULL);
if (!Overlap.hEvent) {
REPORT("Failure: CreateEvent() -- WinError = %u\n", GetLastError());
bInError = TRUE;
}
}
nmpipe_cNamedPipe::~nmpipe_cNamedPipe()
{
}
nmpipe_eRetcode nmpipe_cNamedPipe::GetAvailableData(DWORD cbExpected)
{
DWORD cbTransfer;
BOOL bSuccess = GetOverlappedResult(hPipe, &Overlap, &cbTransfer, TRUE);
if (!bSuccess) {
DWORD rc = GetLastError();
switch (rc) {
case ERROR_MORE_DATA:
return nmpipeOK;
case ERROR_PIPE_NOT_CONNECTED:
case ERROR_BROKEN_PIPE:
case ERROR_NO_DATA:
REPORT("Failure: GetOverlappedResult() -- broken pipe\n");
return nmpipeDisconnect;
default:
REPORT("Failure: GetOverlappedResult() -- WinError = %u\n",
GetLastError());
return nmpipeError;
}
}
if (cbExpected != cbTransfer) {
// We didn't get all of the data expected.
REPORT("Failure: Expected %u bytes, transferred %u bytes\n",
cbExpected, cbTransfer);
return nmpipeError;
}
return nmpipeOK;
}
nmpipe_eRetcode nmpipe_cNamedPipe::BlockForIO(HANDLE hUserEvent,
DWORD TimeOut, DWORD cbExpected)
{
HANDLE hEvents[2];
int NumEvents = 0;
hEvents[NumEvents++] = Overlap.hEvent;
if (hUserEvent) {
hEvents[NumEvents++] = hUserEvent;
}
DWORD rc = WaitForMultipleObjects(NumEvents, hEvents,
FALSE, // Wait for pipe operation or "user" event.
TimeOut);
if (rc == WAIT_FAILED) {
REPORT("Failure: WaitForMultipleObjects() -- WinError = %u\n",
GetLastError());
return nmpipeError;
}
if (rc == WAIT_TIMEOUT) {
REPORT("Failure: WaitForMultipleObjects() -- time-out\n");
return nmpipeTimeOut;
}
DWORD ihEvents = rc - WAIT_OBJECT_0;
if (hUserEvent && (hEvents[ihEvents] == hUserEvent)) {
REPORT("User event received.\n");
return nmpipeEvent;
}
if (hEvents[ihEvents] == Overlap.hEvent) {
return GetAvailableData(cbExpected);
}
REPORT("Failure: WaitForMultipleObjects() -- WinError = %u\n",
GetLastError());
return nmpipeError;
}
nmpipe_eRetcode nmpipe_cNamedPipe::Read(void *pBuffer, DWORD cbBuffer,
DWORD TimeOut)
{
DWORD cbRead;
BOOL bSuccess = ReadFile(hPipe, pBuffer, cbBuffer, &cbRead, &Overlap);
if (!bSuccess) {
DWORD rc = GetLastError();
switch (rc) {
case ERROR_BROKEN_PIPE:
case ERROR_NO_DATA:
REPORT("Failure: ReadFile() -- broken pipe\n");
return nmpipeDisconnect;
case ERROR_IO_PENDING:
return BlockForIO((HANDLE) NULL, TimeOut, cbBuffer);
case ERROR_MORE_DATA:
return nmpipeOK;
default:
REPORT("Failure: ReadFile() -- WinError = %u\n",
GetLastError());
return nmpipeError;
}
}
if (cbRead != cbBuffer) {
REPORT("Warning: Expected %u bytes, read %u bytes (retrying)\n",
cbBuffer, cbRead);
return Read((char *) pBuffer + cbRead, cbBuffer - cbRead, TimeOut);
}
return nmpipeOK;
}
nmpipe_eRetcode nmpipe_cNamedPipe::Write(const void *pBuffer, DWORD cbBuffer,
DWORD TimeOut)
{
DWORD cbWritten;
BOOL bSuccess = WriteFile(hPipe, pBuffer, cbBuffer, &cbWritten, &Overlap);
if (!bSuccess) {
DWORD rc = GetLastError();
switch (rc) {
case ERROR_BROKEN_PIPE:
case ERROR_NO_DATA:
REPORT("Failure: WriteFile() -- broken pipe\n");
return nmpipeDisconnect;
case ERROR_IO_PENDING:
return BlockForIO((HANDLE) NULL, TimeOut, cbBuffer);
default:
REPORT("Failure: WriteFile() -- WinError = %u\n",
GetLastError());
return nmpipeError;
}
}
if (cbWritten != cbBuffer) {
REPORT("Warning: Expected %u bytes, wrote %u bytes (retrying)\n",
cbBuffer, cbWritten);
return Write((char *) pBuffer + cbWritten, cbBuffer - cbWritten, TimeOut);
}
return nmpipeOK;
}
nmpipe_cConnector::nmpipe_cConnector(const char *pPipeName, int MaxRetries)
{
if (bInError) {
return;
}
for (int i=0; i<MaxRetries; i++) {
BOOL bSuccess = WaitNamedPipe(pPipeName, NMPWAIT_USE_DEFAULT_WAIT);
if (bSuccess) {
hPipe = CreateFile(pPipeName,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
if (hPipe != INVALID_HANDLE_VALUE) {
return;
}
REPORT("Failure: CreateFile() -- WinError = %u\n", GetLastError());
}
else {
REPORT("Warning: WaitNamedPipe() failed (retrying)"
" -- WinError = %u\n", GetLastError());
}
}
REPORT("Failure: WaitNamedPipe() -- retry limit exceeded\n");
bInError = TRUE;
}
nmpipe_cConnector::~nmpipe_cConnector()
{
if (hPipe != INVALID_HANDLE_VALUE) {
FlushFileBuffers(hPipe);
CloseHandle(hPipe);
}
}
nmpipe_cListener::nmpipe_cListener(const char *pPipeName,
HANDLE hEventShutdown_, DWORD ClientConnectionTimeOut)
: hEventShutdown(hEventShutdown_)
{
if (bInError) {
return;
}
SECURITY_DESCRIPTOR SecDesc;
memset(&SecDesc, 0, sizeof(SecDesc));
InitializeSecurityDescriptor(&SecDesc, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&SecDesc, TRUE, (PACL) NULL, FALSE);
SECURITY_ATTRIBUTES SecAttr;
memset(&SecAttr, 0, sizeof(SecAttr));
SecAttr.nLength = sizeof(SecAttr);
SecAttr.lpSecurityDescriptor = &SecDesc;
SecAttr.bInheritHandle = TRUE;
hPipe = CreateNamedPipe(pPipeName,
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_WAIT | PIPE_READMODE_BYTE | PIPE_TYPE_BYTE,
PIPE_UNLIMITED_INSTANCES, 0, 0,
ClientConnectionTimeOut, &SecAttr);
if (hPipe == INVALID_HANDLE_VALUE) {
REPORT("Failure: CreateNamedPipe() -- WinError = %u\n",
GetLastError());
bInError = TRUE;
}
}
nmpipe_cListener::~nmpipe_cListener()
{
if (hPipe != INVALID_HANDLE_VALUE) {
CloseHandle(hPipe);
}
}
nmpipe_eRetcode nmpipe_cListener::Connect(DWORD ServerConnectionTimeOut)
{
BOOL bConnected = ConnectNamedPipe(hPipe, &Overlap);
if (!bConnected) {
DWORD rc = GetLastError();
switch (rc) {
case ERROR_PIPE_CONNECTED:
break;
case ERROR_IO_PENDING:
return BlockForIO(hEventShutdown, ServerConnectionTimeOut, 0);
default:
REPORT("Failure: ConnectNamedPipe() -- WinError = %u\n",
GetLastError());
return nmpipeError;
}
}
return nmpipeOK;
}
nmpipe_eRetcode nmpipe_cListener::Disconnect()
{
FlushFileBuffers(hPipe);
if (!DisconnectNamedPipe(hPipe)) {
REPORT("Failure: DisconnectNamedPipe() -- WinError = %u\n",
GetLastError());
return nmpipeError;
}
return nmpipeOK;
}