www.pudn.com > p2p_namedpipes_demo.zip > NamedPipe.cpp


// NamedPipe.cpp: implementation of the CNamedPipe class. 
// 
// Author:    Emil Gustafsson (e@ntier.se),  
//            NTier Solutions (www.ntier.se) 
// Created:   2000-01-25 
// Copyright: This code may be reused and/or editied in any project 
//            as long as this original note (Author and Copyright) 
//            remains in the source files. 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "NamedPipe.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
CNamedPipe::CNamedPipe() 
{ 
	string m_szPipeName = ""; 
	string m_szPipeHost = "."; 
	string m_szFullPipeName = "\\\\.\\PIPE\\"; 
 
	HANDLE m_hOutPipe = NULL; 
	HANDLE m_hInPipe  = NULL; 
	HANDLE m_hListner = NULL; 
} 
 
CNamedPipe::~CNamedPipe() 
{ 
	if (m_hOutPipe != NULL && m_hOutPipe != INVALID_HANDLE_VALUE) 
		CloseHandle(m_hOutPipe); 
	if (m_hInPipe != NULL && m_hInPipe != INVALID_HANDLE_VALUE) 
		CloseHandle(m_hInPipe); 
 
	DWORD dwTemp; 
	if (GetExitCodeThread(m_hListner,&dwTemp)) 
	{ 
		if (dwTemp == STILL_ACTIVE) 
			TerminateThread(m_hListner,3); 
	} 
	if (m_hListner != NULL && m_hListner != INVALID_HANDLE_VALUE) 
		CloseHandle(m_hListner); 
} 
 
bool CNamedPipe::Initialize(bool bAsServer,  
							string szStopListnenCmd, 
							void (WINAPI *fCallBack)(string buf)) 
{ 
	m_bIsServer = bAsServer; 
	if (fCallBack == NULL) 
		return false; 
	if (bAsServer) 
	{ // This instance is a server, hence create the pipes. 
		m_hInPipe = CreateNamedPipe( 
			GetRealPipeName(true).c_str(), 
			PIPE_ACCESS_INBOUND, 
			PIPE_WAIT, 
			1, 
			PIPE_BUF_SIZE, 
			PIPE_BUF_SIZE, 
			PIPE_TIMEOUT, 
			NULL); 
		if (m_hInPipe == NULL || m_hInPipe == INVALID_HANDLE_VALUE) 
			return false; 
 
		m_hOutPipe = CreateNamedPipe( 
			GetRealPipeName(false).c_str(), 
			PIPE_ACCESS_OUTBOUND, 
			PIPE_WAIT, 
			1, 
			PIPE_BUF_SIZE, 
			PIPE_BUF_SIZE, 
			PIPE_TIMEOUT, 
			NULL); 
		if (m_hOutPipe == NULL || m_hOutPipe == INVALID_HANDLE_VALUE) 
			return false; 
	} 
	else 
	{ // obviously a client, just open existing pipes. 
		m_hInPipe = CreateFile( 
			GetRealPipeName(false).c_str(), 
			GENERIC_READ, 
			0, //i.e. No Share 
			NULL, 
			OPEN_EXISTING, 
			FILE_ATTRIBUTE_NORMAL, 
			NULL); 
		if (m_hInPipe == NULL || m_hInPipe == INVALID_HANDLE_VALUE) 
			return false; 
 
		m_hOutPipe = CreateFile( 
			GetRealPipeName(true).c_str(), 
			GENERIC_WRITE, 
			0, //i.e. No Share 
			NULL, 
			OPEN_EXISTING, 
			FILE_ATTRIBUTE_NORMAL, 
			NULL); 
		if (m_hOutPipe == NULL || m_hOutPipe == INVALID_HANDLE_VALUE) 
			return false; 
	} 
	ListnerParam* pLP = new ListnerParam; 
	pLP->funcCallBack = fCallBack; 
	pLP->hPipe = m_hInPipe; 
	pLP->szStopCmd = szStopListnenCmd; 
	m_hListner = CreateThread( 
		NULL, 
		0, 
		&ListnerProc, 
		(LPVOID)pLP, 
		0, 
		&m_dwListnerThreadId); 
	if (m_hListner == NULL || m_hListner == INVALID_HANDLE_VALUE) 
			return false; 
 
	return true; 
} 
 
/*static*/ 
DWORD WINAPI CNamedPipe::ListnerProc(LPVOID lpParameter) 
{ 
	ListnerParam* pLP = (ListnerParam*)lpParameter; 
	if (pLP == NULL) 
		return 1; 
 
	DWORD dwRetVal = 0; 
	for (bool bContinue = true; bContinue && dwRetVal == 0; Sleep(0)) 
	{ 
		char buf[PIPE_BUF_SIZE]; 
		DWORD dwRead; 
		BOOL bOK = ReadFile(pLP->hPipe,buf,PIPE_BUF_SIZE,&dwRead,NULL); 
		if (dwRead == 0) 
			continue; 
		if (!bOK) 
			dwRetVal = 2; 
		string szMsg = buf; 
		if (szMsg == pLP->szStopCmd) 
			bContinue = false; 
		pLP->funcCallBack(szMsg); 
	} 
	delete pLP; 
	return dwRetVal; 
} 
 
void CNamedPipe::SetPipeName(string szName, string szHost/* = "."*/) 
{ 
	m_szPipeName = szName; 
	m_szPipeHost = szHost; 
	m_szFullPipeName = "\\\\"; 
	m_szFullPipeName += m_szPipeHost; 
	m_szFullPipeName += "\\PIPE\\"; 
	m_szFullPipeName += m_szPipeName; 
} 
 
string CNamedPipe::GetRealPipeName(bool bIsServerInPipe) 
{ 
	string szRetVal = m_szFullPipeName; 
	szRetVal += bIsServerInPipe?"_IN":"_OUT"; 
	return szRetVal; 
} 
 
bool CNamedPipe::Send(string szMsg) 
{ 
	DWORD dwSent; 
	BOOL bOK = WriteFile(m_hOutPipe,szMsg.c_str(),szMsg.length()+1,&dwSent,NULL); 
	if (!bOK || (szMsg.length()+1) != dwSent) 
		return false; 
	return true; 
}