📄 netapiwrappers.h
字号:
#if !defined(AFX_PROTOCOLWRAPPERS_H__20010923_BB2C_8F54_F0B7_0080AD509054__INCLUDED_)
#define AFX_PROTOCOLWRAPPERS_H__20010923_BB2C_8F54_F0B7_0080AD509054__INCLUDED_
#pragma once
/////////////////////////////////////////////////////////////////////////////
// Network Protocol API Wrappers
//
// Wrappers for the following Windows protocols:
// MailSlot
// Named Pipes
// TCP/IP (Winsock)
//
// Written by Bjarke Viksoe (bjarke@viksoe.dk)
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name is included.
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability if it causes any damage to you or your
// computer whatsoever. It's free, so don't hassle me about it.
//
// Beware of bugs.
//
/////////////////////////////////////////////////////////////////////////////
// Mail Slots
class CMailSlot
{
public:
HANDLE m_hMailSlot;
bool m_fReadSlot;
CMailSlot(HANDLE hMailSlot = INVALID_HANDLE_VALUE) : m_hMailSlot(hMailSlot)
{
}
~CMailSlot()
{
Close();
}
BOOL Create(LPCTSTR pstrName, DWORD dwMaxMsgSize=420, DWORD dwTimeOut=MAILSLOT_WAIT_FOREVER, LPSECURITY_ATTRIBUTES pSec = NULL)
{
_ASSERTE(m_hMailSlot==INVALID_HANDLE_VALUE);
_ASSERTE(!::IsBadStringPtr(pstrName,-1));
// NOTE: Mailslot creation is only supported on Windows NT.
// NOTE: Messages sized below 425 bytes are sent as datagrams.
// Various limitations on all Win platforms apply for larger messages.
if( (m_hMailSlot = ::CreateMailslot(pstrName, dwMaxMsgSize, dwTimeOut, pSec)) == INVALID_HANDLE_VALUE ) return FALSE;
m_fReadSlot = true;
return TRUE;
}
BOOL Open(LPCTSTR pstrName)
{
_ASSERTE(m_hMailSlot==INVALID_HANDLE_VALUE);
_ASSERTE(!::IsBadStringPtr(pstrName,-1));
if( (m_hMailSlot = ::CreateFile(pstrName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE ) return FALSE;
m_fReadSlot = false;
return TRUE;
}
void Close()
{
if( m_hMailSlot == INVALID_HANDLE_VALUE ) return;
::CloseHandle(m_hMailSlot);
m_hMailSlot = INVALID_HANDLE_VALUE;
}
BOOL IsNull() const
{
return m_hMailSlot == INVALID_HANDLE_VALUE;
}
void Attach(HANDLE hPipe)
{
_ASSERTE(m_hMailSlot==INVALID_HANDLE_VALUE);
m_hMailSlot = hPipe;
}
HANDLE Detach()
{
HANDLE hPipe = m_hMailSlot;
m_hMailSlot = INVALID_HANDLE_VALUE;
return hPipe;
}
BOOL Read(LPVOID pData, DWORD dwSize, LPDWORD pdwRead = NULL)
{
_ASSERTE(m_hMailSlot!=INVALID_HANDLE_VALUE);
_ASSERTE(m_fReadSlot);
_ASSERTE(!::IsBadWritePtr(pData, dwSize));
if( pdwRead != NULL ) *pdwRead = 0;
if( dwSize == 0 ) return TRUE;
if( !m_fReadSlot ) return FALSE;
DWORD dwDummy;
if( pdwRead == NULL ) pdwRead = &dwDummy;
return ::ReadFile(m_hMailSlot, pData, dwSize, pdwRead, NULL);
}
BOOL Write(LPCVOID pData, DWORD dwSize, LPDWORD pdwWritten = NULL)
{
_ASSERTE(m_hMailSlot!=INVALID_HANDLE_VALUE);
_ASSERTE(!m_fReadSlot);
_ASSERTE(!::IsBadReadPtr(pData,dwSize));
if( pdwWritten != NULL ) *pdwWritten = 0;
if( dwSize == 0 ) return TRUE;
if( m_fReadSlot ) return FALSE;
DWORD dwDummy;
if( pdwWritten == NULL ) pdwWritten = &dwDummy;
return ::WriteFile(m_hMailSlot, pData, dwSize, pdwWritten, NULL);
}
BOOL GetInfo(LPDWORD lpMessageCount = NULL, LPDWORD lpNextSize = NULL, LPDWORD lpMaxMessageSize = NULL, LPDWORD lpReadTimeout = NULL) const
{
_ASSERTE(m_hMailSlot!=INVALID_HANDLE_VALUE);
_ASSERTE(m_fReadSlot);
// NOTE: Problems with lpNextSize; see Q192276
return ::GetMailslotInfo(m_hMailSlot, lpMaxMessageSize, lpNextSize, lpMessageCount, lpReadTimeout);
}
BOOL SetInfo(DWORD dwTimeOut) const
{
_ASSERTE(m_hMailSlot!=INVALID_HANDLE_VALUE);
_ASSERTE(m_fReadSlot);
return ::SetMailslotInfo(m_hMailSlot, dwTimeOut);
}
DWORD GetPendingMessageCount() const
{
_ASSERTE(m_hMailSlot!=INVALID_HANDLE_VALUE);
_ASSERTE(m_fReadSlot);
DWORD dwCount;
if( ::GetMailslotInfo(m_hMailSlot, NULL, NULL, &dwCount, NULL) == FALSE ) return 0;
return dwCount;
}
operator HANDLE() const { return m_hMailSlot; }
};
/////////////////////////////////////////////////////////////////////////////
// Named Pipes
class CNamedPipe
{
public:
HANDLE m_hPipe;
HANDLE m_hEvent;
bool m_bConnected;
CNamedPipe(HANDLE hPipe = INVALID_HANDLE_VALUE) :
m_hPipe(hPipe),
m_bConnected(false),
m_hEvent(NULL)
{
}
~CNamedPipe()
{
Close();
}
BOOL Create(LPCTSTR pstrName,
DWORD dwOpenMode,
DWORD dwPipeMode,
DWORD dwBufferSize,
DWORD dwTimeOut,
DWORD dwInstances = PIPE_UNLIMITED_INSTANCES,
LPSECURITY_ATTRIBUTES lpSecurityAttributes = NULL)
{
_ASSERTE(m_hPipe==INVALID_HANDLE_VALUE);
_ASSERTE(!::IsBadStringPtr(pstrName,-1));
if( (m_hPipe = ::CreateNamedPipe(
pstrName, // pipe name
dwPipeMode, // pipe mode
dwOpenMode, // open mode
dwInstances, // max. instances
dwBufferSize, // output buffer size
dwBufferSize, // input buffer size
dwTimeOut, // client time-out
lpSecurityAttributes) // no security attribute
) == INVALID_HANDLE_VALUE ) return FALSE;
return TRUE;
}
BOOL Accept()
{
_ASSERTE(m_hPipe!=INVALID_HANDLE_VALUE);
BOOL fConnected = ::ConnectNamedPipe(m_hPipe, NULL) ? TRUE : (::GetLastError() == ERROR_PIPE_CONNECTED);
if( !fConnected ) {
// The client could not connect, so close the pipe.
::CloseHandle(m_hPipe);
m_hPipe = INVALID_HANDLE_VALUE;
}
else {
m_bConnected = true;
}
return fConnected;
}
BOOL Open(LPCTSTR pstrName, DWORD dwAccess = GENERIC_READ|GENERIC_WRITE, LPSECURITY_ATTRIBUTES lpSecurityAttributes = NULL)
{
_ASSERTE(m_hPipe==INVALID_HANDLE_VALUE);
_ASSERTE(!::IsBadStringPtr(pstrName,-1));
if( (m_hPipe = ::CreateFile(pstrName, dwAccess, 0, lpSecurityAttributes, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE ) return FALSE;
return TRUE;
}
void Close()
{
if( m_hEvent != NULL ) {
::CloseHandle(m_hEvent);
m_hEvent = NULL;
}
if( m_bConnected ) {
::FlushFileBuffers(m_hPipe);
::DisconnectNamedPipe(m_hPipe);
m_bConnected = false;
}
if( m_hPipe != INVALID_HANDLE_VALUE ) {
::CloseHandle(m_hPipe);
m_hPipe = INVALID_HANDLE_VALUE;
}
}
BOOL IsNull() const
{
return m_hPipe == INVALID_HANDLE_VALUE;
}
void Attach(HANDLE hPipe)
{
_ASSERTE(m_hPipe==INVALID_HANDLE_VALUE);
m_hPipe = hPipe;
}
HANDLE Detach()
{
HANDLE hPipe = m_hPipe;
m_hPipe = INVALID_HANDLE_VALUE;
return hPipe;
}
BOOL Read(LPVOID pData, DWORD dwSize, LPDWORD pdwRead = NULL, LPOVERLAPPED lpOverlapped = NULL)
{
_ASSERTE(m_hPipe!=INVALID_HANDLE_VALUE);
_ASSERTE(!::IsBadWritePtr(pData, dwSize));
if( pdwRead != NULL ) *pdwRead = 0;
if( dwSize == 0 ) return TRUE;
DWORD dwDummy;
if( pdwRead == NULL ) pdwRead = &dwDummy;
return ::ReadFile(m_hPipe, pData, dwSize, pdwRead, lpOverlapped);
}
BOOL Write(LPCVOID pData, DWORD dwSize, LPDWORD pdwWritten = NULL, LPOVERLAPPED lpOverlapped = NULL)
{
_ASSERTE(m_hPipe!=INVALID_HANDLE_VALUE);
_ASSERTE(!::IsBadReadPtr(pData, dwSize));
if( pdwWritten != NULL ) *pdwWritten = 0;
if( dwSize == 0 ) return TRUE;
DWORD dwDummy;
if( pdwWritten == NULL ) pdwWritten = &dwDummy;
return ::WriteFile(m_hPipe, pData, dwSize, pdwWritten, lpOverlapped);
}
BOOL GetInfo(LPDWORD lpFlags, LPDWORD lpOutBufferSize = NULL, LPDWORD lpInBufferSize = NULL, LPDWORD lpMaxInstances = NULL) const
{
_ASSERTE(m_hPipe!=INVALID_HANDLE_VALUE);
return ::GetNamedPipeInfo(m_hPipe, lpFlags, lpOutBufferSize, lpInBufferSize, lpMaxInstances);
}
BOOL GetHandleState(LPDWORD lpState, LPDWORD lpCurInstances = NULL, LPDWORD lpMaxCollectionCount = NULL, LPDWORD lpCollectDataTimeout = NULL, LPTSTR lpUserName = NULL, DWORD nMaxUserNameSize = 0) const
{
_ASSERTE(m_hPipe!=INVALID_HANDLE_VALUE);
return ::GetNamedPipeHandleState(m_hPipe, lpState, lpCurInstances, lpMaxCollectionCount, lpCollectDataTimeout, lpUserName, nMaxUserNameSize);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -