| /************************************************************** |
| * |
| * 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. |
| * |
| *************************************************************/ |
| |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sal.hxx" |
| # 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; |
| } |
| } |