/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/

#	include "pipeimpl.h"

#ifndef _INC_MALLOC
#	include <malloc.h>
#endif

#ifndef _INC_TCHAR
#	ifdef UNICODE
#		define _UNICODE
#	endif
#	include <tchar.h>
#endif

const TCHAR PIPE_NAME_PREFIX_MAPPING[] = TEXT("PIPE_FILE_MAPPING_");
const TCHAR PIPE_NAME_PREFIX_SYNCHRONIZE[] = TEXT("PIPE_SYNCHRONIZE_MUTEX_");
const TCHAR PIPE_NAME_PREFIX_CONNECTION[] = TEXT("PIPE_CONNECTION_SEMAPHORE_");

const DWORD PIPE_BUFFER_SIZE = 4096;


//============================================================================
//	PipeData
//============================================================================

struct PipeData
{
	DWORD	dwProcessId;
	HANDLE	hReadPipe;
	HANDLE	hWritePipe;
};

//============================================================================
//	Pipe
//============================================================================

#ifdef UNICODE
#define Pipe		PipeW
#define ClientPipe	ClientPipeW
#define ServerPipe	ServerPipeW
#else
#define Pipe		PipeA
#define ClientPipe	ClientPipeA
#define ServerPipe	ServerPipeA
#endif

class Pipe
{
protected:
	HANDLE	m_hReadPipe;	// Handle to use for reading
	HANDLE	m_hWritePipe;	// Handle to use for writing

	Pipe( HANDLE hReadPipe, HANDLE hWritePipe );

	static HANDLE CreatePipeDataMutex( LPCTSTR lpName, BOOL bInitialOwner );
	static HANDLE CreatePipeDataMapping( LPCTSTR lpName );
	static HANDLE OpenPipeDataMapping( LPCTSTR lpName );
	static HANDLE CreatePipeConnectionSemaphore( LPCTSTR lpName, LONG lInitialCount, LONG lMaximumcount );

public:
	Pipe( const Pipe& );
	const Pipe& operator = ( const Pipe& );
	virtual ~Pipe();

	virtual bool Close();
	virtual bool Write( LPCVOID lpBuffer, DWORD dwBytesToWrite, LPDWORD lpBytesWritten, bool bWait = true );
	virtual bool Read( LPVOID lpBuffer, DWORD dwBytesToRead, LPDWORD lpBytesRead, bool bWait = true );

	virtual Pipe *AcceptConnection()
	{
		SetLastError( ERROR_INVALID_HANDLE );
		return NULL;
	}

	void * operator new( size_t nBytes )
	{
		return HeapAlloc( GetProcessHeap(), 0, nBytes );
	}

	void operator delete( void *ptr )
	{
		HeapFree( GetProcessHeap(), 0, ptr );
	}

	bool is() const
	{
		return (FALSE != HeapValidate( GetProcessHeap(), 0, this ));
	}

};

//============================================================================
//	ClientPipe
//============================================================================

class ClientPipe : public Pipe
{
protected:
	ClientPipe( HANDLE hReadPipe, HANDLE hWritePipe );
public:
	static ClientPipe* Create( LPCTSTR lpName );
};

//============================================================================
//	ServerPipe
//============================================================================

class ServerPipe : public Pipe
{
protected:
	HANDLE	m_hMapping;
	HANDLE	m_hSynchronize;
	LPTSTR	m_lpName;

	ServerPipe( LPCTSTR lpName, HANDLE hMapping, HANDLE hSynchronize, HANDLE hReadPipe, HANDLE hWritePipe );
public:
	virtual ~ServerPipe();

	static ServerPipe *Create( LPCTSTR lpName );

	virtual Pipe *AcceptConnection();
};

//----------------------------------------------------------------------------
//	
//----------------------------------------------------------------------------

HANDLE	Pipe::CreatePipeDataMapping( LPCTSTR lpName )
{
	HANDLE	hMapping = NULL;
	LPTSTR	lpMappingName = (LPTSTR)alloca( _tcslen(lpName) * sizeof(TCHAR) + sizeof(PIPE_NAME_PREFIX_MAPPING) );

	if ( lpMappingName )
	{
		_tcscpy( lpMappingName, PIPE_NAME_PREFIX_MAPPING );
		_tcscat( lpMappingName, lpName );

		LPTSTR	lpMappingFileName = (LPTSTR)alloca( MAX_PATH * sizeof(TCHAR) );

		if ( lpMappingFileName )
		{
			DWORD	nChars = GetTempPath( MAX_PATH, lpMappingFileName );

			if ( MAX_PATH + _tcslen(lpName) < nChars + 1 )
			{
				lpMappingFileName = (LPTSTR)alloca( (nChars + 1 + _tcslen(lpName)) * sizeof(TCHAR) );
				if ( lpMappingFileName )
					nChars = GetTempPath( nChars, lpMappingFileName );
				else
				{
					nChars = 0;
					SetLastError( ERROR_NOT_ENOUGH_MEMORY );
				}
			}

			if ( nChars )
			{
				_tcscat( lpMappingFileName, lpMappingName );

				HANDLE hFile = CreateFile( 
					lpMappingFileName, 
					GENERIC_READ | GENERIC_WRITE, 
					FILE_SHARE_READ | FILE_SHARE_WRITE, 
					NULL, 
					OPEN_ALWAYS, 
					FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, 
					NULL );

				if ( IsValidHandle(hFile) )
				{
					hMapping = CreateFileMapping(
						(HANDLE)hFile,
						(LPSECURITY_ATTRIBUTES)NULL,
						PAGE_READWRITE,
						0,
						sizeof(PipeData),
						lpMappingName );

					CloseHandle( hFile );
				}
			}
		}
		else
			SetLastError( ERROR_NOT_ENOUGH_MEMORY );
	}

	return hMapping;
}

//----------------------------------------------------------------------------
//	
//----------------------------------------------------------------------------

HANDLE	Pipe::OpenPipeDataMapping( LPCTSTR lpName )
{
	HANDLE	hMapping = NULL;
	LPTSTR	lpMappingName = (LPTSTR)alloca( _tcslen(lpName) * sizeof(TCHAR) + sizeof(PIPE_NAME_PREFIX_MAPPING) );

	if ( lpMappingName )
	{
		_tcscpy( lpMappingName, PIPE_NAME_PREFIX_MAPPING );
		_tcscat( lpMappingName, lpName );

		hMapping = OpenFileMapping( FILE_MAP_ALL_ACCESS, FALSE, lpMappingName );
	}

	return hMapping;
}

//----------------------------------------------------------------------------
//	
//----------------------------------------------------------------------------

HANDLE	Pipe::CreatePipeDataMutex( LPCTSTR lpName, BOOL bInitialOwner )
{
	HANDLE	hMutex = NULL;
	LPTSTR	lpMutexName = (LPTSTR)alloca( _tcslen(lpName) * sizeof(TCHAR) + sizeof(PIPE_NAME_PREFIX_SYNCHRONIZE) );

	if ( lpMutexName )
	{
		_tcscpy( lpMutexName, PIPE_NAME_PREFIX_SYNCHRONIZE );
		_tcscat( lpMutexName, lpName );

		hMutex = CreateMutex( NULL, bInitialOwner, lpMutexName );
	}

	return hMutex;
}

//----------------------------------------------------------------------------
//	
//----------------------------------------------------------------------------

HANDLE Pipe::CreatePipeConnectionSemaphore( LPCTSTR lpName, LONG lInitialCount, LONG lMaximumCount )
{
	HANDLE	hSemaphore = NULL;
	LPTSTR	lpSemaphoreName = (LPTSTR)alloca( _tcslen(lpName) * sizeof(TCHAR) + sizeof(PIPE_NAME_PREFIX_CONNECTION) );

	if ( lpSemaphoreName )
	{
		_tcscpy( lpSemaphoreName, PIPE_NAME_PREFIX_CONNECTION );
		_tcscat( lpSemaphoreName, lpName );

		hSemaphore = CreateSemaphore( NULL, lInitialCount, lMaximumCount, lpSemaphoreName );
	}

	return hSemaphore;
}


//----------------------------------------------------------------------------
//	Pipe copy ctor
//----------------------------------------------------------------------------

Pipe::Pipe( const Pipe& rPipe ) :
m_hReadPipe( INVALID_HANDLE_VALUE ),
m_hWritePipe( INVALID_HANDLE_VALUE )
{
	DuplicateHandle( 
		GetCurrentProcess(),
		rPipe.m_hReadPipe,
		GetCurrentProcess(),
		&m_hReadPipe,
		0,
		FALSE,
		DUPLICATE_SAME_ACCESS );

	DuplicateHandle( 
		GetCurrentProcess(),
		rPipe.m_hWritePipe,
		GetCurrentProcess(),
		&m_hWritePipe,
		0,
		FALSE,
		DUPLICATE_SAME_ACCESS );
}

//----------------------------------------------------------------------------
//	Pipe assignment operator
//----------------------------------------------------------------------------

const Pipe& Pipe::operator = ( const Pipe& rPipe )
{
	Close();

	DuplicateHandle( 
		GetCurrentProcess(),
		rPipe.m_hReadPipe,
		GetCurrentProcess(),
		&m_hReadPipe,
		0,
		FALSE,
		DUPLICATE_SAME_ACCESS );

	DuplicateHandle( 
		GetCurrentProcess(),
		rPipe.m_hWritePipe,
		GetCurrentProcess(),
		&m_hWritePipe,
		0,
		FALSE,
		DUPLICATE_SAME_ACCESS );
	
	return *this;
}

//----------------------------------------------------------------------------
//	Pipe ctor
//----------------------------------------------------------------------------

Pipe::Pipe( HANDLE hReadPipe, HANDLE hWritePipe ) :
m_hReadPipe( INVALID_HANDLE_VALUE ),
m_hWritePipe( INVALID_HANDLE_VALUE )
{
	DuplicateHandle( 
		GetCurrentProcess(),
		hReadPipe,
		GetCurrentProcess(),
		&m_hReadPipe,
		0,
		FALSE,
		DUPLICATE_SAME_ACCESS );

	DuplicateHandle( 
		GetCurrentProcess(),
		hWritePipe,
		GetCurrentProcess(),
		&m_hWritePipe,
		0,
		FALSE,
		DUPLICATE_SAME_ACCESS );
}

//----------------------------------------------------------------------------
//	Pipe dtor
//----------------------------------------------------------------------------

Pipe::~Pipe()
{
	Close();
}

//----------------------------------------------------------------------------
//	Pipe Close
//----------------------------------------------------------------------------

bool Pipe::Close()
{
	bool	fSuccess = false;	// Assume failure

	if ( IsValidHandle(m_hReadPipe) )
	{
		CloseHandle( m_hReadPipe );
		m_hReadPipe = INVALID_HANDLE_VALUE;
	}

	if ( IsValidHandle(m_hWritePipe) )
	{
		CloseHandle( m_hWritePipe );
		m_hWritePipe = INVALID_HANDLE_VALUE;
	}

	return fSuccess;
}

//----------------------------------------------------------------------------
//	Pipe Write
//----------------------------------------------------------------------------

bool Pipe::Write( LPCVOID lpBuffer, DWORD dwBytesToWrite, LPDWORD lpBytesWritten, bool bWait )
{
	DWORD	dwBytesAvailable = 0;
	BOOL	fSuccess = TRUE;

	if ( !bWait )
		fSuccess = PeekNamedPipe( m_hReadPipe, NULL, 0, NULL, &dwBytesAvailable, NULL );

	if ( fSuccess )
	{
		if ( !bWait && dwBytesToWrite > PIPE_BUFFER_SIZE - dwBytesAvailable )
			dwBytesToWrite = PIPE_BUFFER_SIZE - dwBytesAvailable ;

		return !!WriteFile( m_hWritePipe, lpBuffer, dwBytesToWrite, lpBytesWritten, NULL );
	}

	return false;
}

//----------------------------------------------------------------------------
//	Pipe Read
//----------------------------------------------------------------------------

bool Pipe::Read( LPVOID lpBuffer, DWORD dwBytesToRead, LPDWORD lpBytesRead, bool bWait )
{
	DWORD	dwBytesAvailable = 0;
	BOOL	fSuccess = TRUE;

	if ( !bWait )
		fSuccess = PeekNamedPipe( m_hReadPipe, NULL, 0, NULL, &dwBytesAvailable, NULL );

	if ( fSuccess )
	{
		if ( bWait || dwBytesAvailable )
			return !!ReadFile( m_hReadPipe, lpBuffer, dwBytesToRead, lpBytesRead, NULL );
		else
		{
			*lpBytesRead = 0;
			return true;
		}
	}

	return false;
}



//----------------------------------------------------------------------------
//	Client pipe dtor
//----------------------------------------------------------------------------

ClientPipe::ClientPipe( HANDLE hReadPipe, HANDLE hWritePipe ) : Pipe( hReadPipe, hWritePipe )
{
}

//----------------------------------------------------------------------------
//	Client pipe creation
//----------------------------------------------------------------------------

ClientPipe *ClientPipe::Create( LPCTSTR lpName )
{
	ClientPipe	*pPipe = NULL;	// Assume failure

	HANDLE	hMapping = OpenPipeDataMapping( lpName );

	if ( IsValidHandle(hMapping) )
	{
		PipeData	*pData = (PipeData*)MapViewOfFile( hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0 );

		if ( pData )
		{
			HANDLE	hSourceProcess = OpenProcess( PROCESS_DUP_HANDLE, FALSE, pData->dwProcessId );

			if ( IsValidHandle(hSourceProcess) )
			{
				BOOL fSuccess;
				HANDLE	hReadPipe = INVALID_HANDLE_VALUE, hWritePipe = INVALID_HANDLE_VALUE;
				
				fSuccess = DuplicateHandle( 
					hSourceProcess,
					pData->hReadPipe,
					GetCurrentProcess(),
					&hReadPipe,
					0,
					FALSE,
					DUPLICATE_SAME_ACCESS );

				fSuccess = fSuccess && DuplicateHandle( 
					hSourceProcess,
					pData->hWritePipe,
					GetCurrentProcess(),
					&hWritePipe,
					0,
					FALSE,
					DUPLICATE_SAME_ACCESS );

				if ( fSuccess )
					pPipe = new ClientPipe( hReadPipe, hWritePipe );

				if ( IsValidHandle(hWritePipe) )
					CloseHandle( hWritePipe );

				if ( IsValidHandle(hReadPipe) )
					CloseHandle( hReadPipe );

				HANDLE	hConnectionRequest = CreatePipeConnectionSemaphore( lpName, 0, 1 );

				ReleaseSemaphore( hConnectionRequest, 1, NULL );

				CloseHandle( hConnectionRequest );
				
				CloseHandle( hSourceProcess );
			}

			UnmapViewOfFile( pData );
		}

		CloseHandle( hMapping );
	}

	return pPipe;
}



//----------------------------------------------------------------------------
//	ServerPipe ctor
//----------------------------------------------------------------------------

ServerPipe::ServerPipe( LPCTSTR	lpName, HANDLE hMapping, HANDLE hSynchronize, HANDLE hReadPipe, HANDLE hWritePipe ) : Pipe( hReadPipe, hWritePipe ),
m_hMapping( NULL ),
m_hSynchronize( NULL ),
m_lpName( NULL )
{
	DuplicateHandle( 
		GetCurrentProcess(),
		hMapping,
		GetCurrentProcess(),
		&m_hMapping,
		0,
		FALSE,
		DUPLICATE_SAME_ACCESS );

	DuplicateHandle(
		GetCurrentProcess(),
		hSynchronize,
		GetCurrentProcess(),
		&m_hSynchronize,
		0,
		FALSE,
		DUPLICATE_SAME_ACCESS
		);
	m_lpName = new TCHAR[_tcslen(lpName) + 1];
	if ( m_lpName )
		_tcscpy( m_lpName, lpName );
}

//----------------------------------------------------------------------------
//	ServerPipe dtor
//----------------------------------------------------------------------------

ServerPipe::~ServerPipe()
{
	if ( IsValidHandle(m_hMapping) )
		CloseHandle( m_hMapping );
	if ( m_lpName )
		delete[]m_lpName;
}

//----------------------------------------------------------------------------
//	ServerPipe AcceptConnection
//----------------------------------------------------------------------------

Pipe *ServerPipe::AcceptConnection()
{
	Pipe	*pPipe = NULL;	// Assume failure;

	HANDLE	hConnectionRequest = CreatePipeConnectionSemaphore( m_lpName, 0, 1 );

	if ( WAIT_OBJECT_0 == WaitForSingleObject( hConnectionRequest, INFINITE ) )
	{
		pPipe = new Pipe( *this );
		Close();

		// Create new inbound Pipe

		HANDLE	hClientWritePipe = NULL, hServerReadPipe = NULL;

		BOOL	fSuccess = CreatePipe( &hServerReadPipe, &hClientWritePipe, NULL, PIPE_BUFFER_SIZE );


		if ( fSuccess )
		{
			// Create outbound pipe

			HANDLE	hClientReadPipe = NULL, hServerWritePipe = NULL;

			if ( CreatePipe( &hClientReadPipe, &hServerWritePipe, NULL, PIPE_BUFFER_SIZE ) )
			{
				m_hReadPipe = hServerReadPipe;
				m_hWritePipe = hServerWritePipe;

				PipeData	*pData = (PipeData *)MapViewOfFile( m_hMapping, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(PipeData) );

				HANDLE	hSynchronize = CreatePipeDataMutex( m_lpName, TRUE );

				CloseHandle( pData->hReadPipe );
				CloseHandle( pData->hWritePipe );

				pData->hReadPipe = hClientReadPipe;
				pData->hWritePipe = hClientWritePipe;

				ReleaseMutex( hSynchronize );

				CloseHandle( hSynchronize );

			}
			else
			{
				CloseHandle( hClientWritePipe );
				CloseHandle( hServerWritePipe );	
			}
		}

		ReleaseMutex( hConnectionRequest );
	}

	CloseHandle( hConnectionRequest );

	return pPipe;
}

//----------------------------------------------------------------------------
//	Pipe creation
//----------------------------------------------------------------------------

ServerPipe *ServerPipe::Create( LPCTSTR lpName )
{
	ServerPipe	*pPipe = NULL;

	HANDLE	hMapping = CreatePipeDataMapping( lpName );

	if ( IsValidHandle(hMapping) )
	{
		if ( ERROR_FILE_EXISTS != GetLastError() )
		{
			HANDLE	hSynchronize = CreatePipeDataMutex( lpName, FALSE);
			
			WaitForSingleObject( hSynchronize, INFINITE );

			PipeData	*pData = (PipeData*)MapViewOfFile( hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0 );

			if ( pData )
			{

				// Initialize pipe data

				pData->dwProcessId = 0;
				pData->hReadPipe = NULL;
				pData->hWritePipe = NULL;

				// Create inbound pipe

				HANDLE	hServerReadPipe = NULL, hClientWritePipe = NULL;

				BOOL	fSuccess = CreatePipe( &hServerReadPipe, &hClientWritePipe, NULL, PIPE_BUFFER_SIZE );

				if ( fSuccess )
				{
					// Create outbound pipe

					HANDLE	hServerWritePipe = NULL, hClientReadPipe = NULL;

					fSuccess = CreatePipe( &hClientReadPipe, &hServerWritePipe, NULL, PIPE_BUFFER_SIZE );

					if ( fSuccess )
					{
						pData->dwProcessId = GetCurrentProcessId();
						pData->hReadPipe = hClientReadPipe;
						pData->hWritePipe = hClientWritePipe;
						pPipe = new ServerPipe( lpName, hMapping, hSynchronize, hServerReadPipe, hServerWritePipe );

						CloseHandle( hServerWritePipe );
						CloseHandle( hServerReadPipe );
					}
					else
					{
						CloseHandle( hServerReadPipe );
						CloseHandle( hClientWritePipe );
					}
				}

				UnmapViewOfFile( pData );
			}

			ReleaseMutex( hSynchronize );
			CloseHandle( hSynchronize );
		}

		CloseHandle( hMapping );
	}

	return pPipe;
}


//----------------------------------------------------------------------------
//	C style API
//----------------------------------------------------------------------------

const TCHAR	LOCAL_PIPE_PREFIX[] = TEXT("\\\\.\\PIPE\\" );

extern "C" HANDLE WINAPI CreateSimplePipe( LPCTSTR lpName )
{
	int	nPrefixLen = _tcslen( LOCAL_PIPE_PREFIX );
	if ( 0 == _tcsnicmp( lpName, LOCAL_PIPE_PREFIX, nPrefixLen ) )
		lpName += nPrefixLen;
	return (HANDLE)ServerPipe::Create( lpName );
}

extern "C" HANDLE WINAPI OpenSimplePipe( LPCTSTR lpName )
{
	int	nPrefixLen = _tcslen( LOCAL_PIPE_PREFIX );
	if ( 0 == _tcsnicmp( lpName, LOCAL_PIPE_PREFIX, nPrefixLen ) )
		lpName += nPrefixLen;
	return (HANDLE)ClientPipe::Create( lpName );
}

extern "C" HANDLE WINAPI AcceptSimplePipeConnection( HANDLE hPipe )
{
	Pipe	*pPipe = (Pipe *)hPipe;

	if ( pPipe->is() )
		return (HANDLE)pPipe->AcceptConnection();
	else
	{
		SetLastError( ERROR_INVALID_HANDLE );
		return NULL;
	}
}

extern "C" BOOL WINAPI WaitForSimplePipe( LPCTSTR /*lpName*/, DWORD /*dwTimeOut*/ )
{
	return FALSE;
}

extern "C" BOOL WINAPI WriteSimplePipe( HANDLE hPipe, LPCVOID lpBuffer, DWORD dwBytesToWrite, LPDWORD lpBytesWritten, BOOL bWait )
{
	Pipe	*pPipe = (Pipe *)hPipe;

	if ( pPipe->is() )
		return pPipe->Write( lpBuffer, dwBytesToWrite, lpBytesWritten, bWait );
	else
	{
		SetLastError( ERROR_INVALID_HANDLE );
		return FALSE;
	}
}

extern "C" BOOL WINAPI ReadSimplePipe( HANDLE hPipe, LPVOID lpBuffer, DWORD dwBytesToRead, LPDWORD lpBytesRead, BOOL bWait )
{
	Pipe	*pPipe = (Pipe *)hPipe;

	if ( pPipe->is() )
		return pPipe->Read( lpBuffer, dwBytesToRead, lpBytesRead, bWait );
	else
	{
		SetLastError( ERROR_INVALID_HANDLE );
		return FALSE;
	}
}

extern "C" BOOL WINAPI CloseSimplePipe( HANDLE hPipe )
{
	Pipe	*pPipe = (Pipe *)hPipe;

	if ( pPipe->is() )
	{
		delete pPipe;
		return TRUE;
	}
	else
	{
		SetLastError( ERROR_INVALID_HANDLE );
		return FALSE;
	}
}
