1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir 29*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 30*cdf0e10cSrcweir #include "precompiled_sal.hxx" 31*cdf0e10cSrcweir # include "pipeimpl.h" 32*cdf0e10cSrcweir 33*cdf0e10cSrcweir #ifndef _INC_MALLOC 34*cdf0e10cSrcweir # include <malloc.h> 35*cdf0e10cSrcweir #endif 36*cdf0e10cSrcweir 37*cdf0e10cSrcweir #ifndef _INC_TCHAR 38*cdf0e10cSrcweir # ifdef UNICODE 39*cdf0e10cSrcweir # define _UNICODE 40*cdf0e10cSrcweir # endif 41*cdf0e10cSrcweir # include <tchar.h> 42*cdf0e10cSrcweir #endif 43*cdf0e10cSrcweir 44*cdf0e10cSrcweir const TCHAR PIPE_NAME_PREFIX_MAPPING[] = TEXT("PIPE_FILE_MAPPING_"); 45*cdf0e10cSrcweir const TCHAR PIPE_NAME_PREFIX_SYNCHRONIZE[] = TEXT("PIPE_SYNCHRONIZE_MUTEX_"); 46*cdf0e10cSrcweir const TCHAR PIPE_NAME_PREFIX_CONNECTION[] = TEXT("PIPE_CONNECTION_SEMAPHORE_"); 47*cdf0e10cSrcweir 48*cdf0e10cSrcweir const DWORD PIPE_BUFFER_SIZE = 4096; 49*cdf0e10cSrcweir 50*cdf0e10cSrcweir 51*cdf0e10cSrcweir //============================================================================ 52*cdf0e10cSrcweir // PipeData 53*cdf0e10cSrcweir //============================================================================ 54*cdf0e10cSrcweir 55*cdf0e10cSrcweir struct PipeData 56*cdf0e10cSrcweir { 57*cdf0e10cSrcweir DWORD dwProcessId; 58*cdf0e10cSrcweir HANDLE hReadPipe; 59*cdf0e10cSrcweir HANDLE hWritePipe; 60*cdf0e10cSrcweir }; 61*cdf0e10cSrcweir 62*cdf0e10cSrcweir //============================================================================ 63*cdf0e10cSrcweir // Pipe 64*cdf0e10cSrcweir //============================================================================ 65*cdf0e10cSrcweir 66*cdf0e10cSrcweir #ifdef UNICODE 67*cdf0e10cSrcweir #define Pipe PipeW 68*cdf0e10cSrcweir #define ClientPipe ClientPipeW 69*cdf0e10cSrcweir #define ServerPipe ServerPipeW 70*cdf0e10cSrcweir #else 71*cdf0e10cSrcweir #define Pipe PipeA 72*cdf0e10cSrcweir #define ClientPipe ClientPipeA 73*cdf0e10cSrcweir #define ServerPipe ServerPipeA 74*cdf0e10cSrcweir #endif 75*cdf0e10cSrcweir 76*cdf0e10cSrcweir class Pipe 77*cdf0e10cSrcweir { 78*cdf0e10cSrcweir protected: 79*cdf0e10cSrcweir HANDLE m_hReadPipe; // Handle to use for reading 80*cdf0e10cSrcweir HANDLE m_hWritePipe; // Handle to use for writing 81*cdf0e10cSrcweir 82*cdf0e10cSrcweir Pipe( HANDLE hReadPipe, HANDLE hWritePipe ); 83*cdf0e10cSrcweir 84*cdf0e10cSrcweir static HANDLE CreatePipeDataMutex( LPCTSTR lpName, BOOL bInitialOwner ); 85*cdf0e10cSrcweir static HANDLE CreatePipeDataMapping( LPCTSTR lpName ); 86*cdf0e10cSrcweir static HANDLE OpenPipeDataMapping( LPCTSTR lpName ); 87*cdf0e10cSrcweir static HANDLE CreatePipeConnectionSemaphore( LPCTSTR lpName, LONG lInitialCount, LONG lMaximumcount ); 88*cdf0e10cSrcweir 89*cdf0e10cSrcweir public: 90*cdf0e10cSrcweir Pipe( const Pipe& ); 91*cdf0e10cSrcweir const Pipe& operator = ( const Pipe& ); 92*cdf0e10cSrcweir virtual ~Pipe(); 93*cdf0e10cSrcweir 94*cdf0e10cSrcweir virtual bool Close(); 95*cdf0e10cSrcweir virtual bool Write( LPCVOID lpBuffer, DWORD dwBytesToWrite, LPDWORD lpBytesWritten, bool bWait = true ); 96*cdf0e10cSrcweir virtual bool Read( LPVOID lpBuffer, DWORD dwBytesToRead, LPDWORD lpBytesRead, bool bWait = true ); 97*cdf0e10cSrcweir 98*cdf0e10cSrcweir virtual Pipe *AcceptConnection() 99*cdf0e10cSrcweir { 100*cdf0e10cSrcweir SetLastError( ERROR_INVALID_HANDLE ); 101*cdf0e10cSrcweir return NULL; 102*cdf0e10cSrcweir } 103*cdf0e10cSrcweir 104*cdf0e10cSrcweir void * operator new( size_t nBytes ) 105*cdf0e10cSrcweir { 106*cdf0e10cSrcweir return HeapAlloc( GetProcessHeap(), 0, nBytes ); 107*cdf0e10cSrcweir } 108*cdf0e10cSrcweir 109*cdf0e10cSrcweir void operator delete( void *ptr ) 110*cdf0e10cSrcweir { 111*cdf0e10cSrcweir HeapFree( GetProcessHeap(), 0, ptr ); 112*cdf0e10cSrcweir } 113*cdf0e10cSrcweir 114*cdf0e10cSrcweir bool is() const 115*cdf0e10cSrcweir { 116*cdf0e10cSrcweir return (FALSE != HeapValidate( GetProcessHeap(), 0, this )); 117*cdf0e10cSrcweir } 118*cdf0e10cSrcweir 119*cdf0e10cSrcweir }; 120*cdf0e10cSrcweir 121*cdf0e10cSrcweir //============================================================================ 122*cdf0e10cSrcweir // ClientPipe 123*cdf0e10cSrcweir //============================================================================ 124*cdf0e10cSrcweir 125*cdf0e10cSrcweir class ClientPipe : public Pipe 126*cdf0e10cSrcweir { 127*cdf0e10cSrcweir protected: 128*cdf0e10cSrcweir ClientPipe( HANDLE hReadPipe, HANDLE hWritePipe ); 129*cdf0e10cSrcweir public: 130*cdf0e10cSrcweir static ClientPipe* Create( LPCTSTR lpName ); 131*cdf0e10cSrcweir }; 132*cdf0e10cSrcweir 133*cdf0e10cSrcweir //============================================================================ 134*cdf0e10cSrcweir // ServerPipe 135*cdf0e10cSrcweir //============================================================================ 136*cdf0e10cSrcweir 137*cdf0e10cSrcweir class ServerPipe : public Pipe 138*cdf0e10cSrcweir { 139*cdf0e10cSrcweir protected: 140*cdf0e10cSrcweir HANDLE m_hMapping; 141*cdf0e10cSrcweir HANDLE m_hSynchronize; 142*cdf0e10cSrcweir LPTSTR m_lpName; 143*cdf0e10cSrcweir 144*cdf0e10cSrcweir ServerPipe( LPCTSTR lpName, HANDLE hMapping, HANDLE hSynchronize, HANDLE hReadPipe, HANDLE hWritePipe ); 145*cdf0e10cSrcweir public: 146*cdf0e10cSrcweir virtual ~ServerPipe(); 147*cdf0e10cSrcweir 148*cdf0e10cSrcweir static ServerPipe *Create( LPCTSTR lpName ); 149*cdf0e10cSrcweir 150*cdf0e10cSrcweir virtual Pipe *AcceptConnection(); 151*cdf0e10cSrcweir }; 152*cdf0e10cSrcweir 153*cdf0e10cSrcweir //---------------------------------------------------------------------------- 154*cdf0e10cSrcweir // 155*cdf0e10cSrcweir //---------------------------------------------------------------------------- 156*cdf0e10cSrcweir 157*cdf0e10cSrcweir HANDLE Pipe::CreatePipeDataMapping( LPCTSTR lpName ) 158*cdf0e10cSrcweir { 159*cdf0e10cSrcweir HANDLE hMapping = NULL; 160*cdf0e10cSrcweir LPTSTR lpMappingName = (LPTSTR)alloca( _tcslen(lpName) * sizeof(TCHAR) + sizeof(PIPE_NAME_PREFIX_MAPPING) ); 161*cdf0e10cSrcweir 162*cdf0e10cSrcweir if ( lpMappingName ) 163*cdf0e10cSrcweir { 164*cdf0e10cSrcweir _tcscpy( lpMappingName, PIPE_NAME_PREFIX_MAPPING ); 165*cdf0e10cSrcweir _tcscat( lpMappingName, lpName ); 166*cdf0e10cSrcweir 167*cdf0e10cSrcweir LPTSTR lpMappingFileName = (LPTSTR)alloca( MAX_PATH * sizeof(TCHAR) ); 168*cdf0e10cSrcweir 169*cdf0e10cSrcweir if ( lpMappingFileName ) 170*cdf0e10cSrcweir { 171*cdf0e10cSrcweir DWORD nChars = GetTempPath( MAX_PATH, lpMappingFileName ); 172*cdf0e10cSrcweir 173*cdf0e10cSrcweir if ( MAX_PATH + _tcslen(lpName) < nChars + 1 ) 174*cdf0e10cSrcweir { 175*cdf0e10cSrcweir lpMappingFileName = (LPTSTR)alloca( (nChars + 1 + _tcslen(lpName)) * sizeof(TCHAR) ); 176*cdf0e10cSrcweir if ( lpMappingFileName ) 177*cdf0e10cSrcweir nChars = GetTempPath( nChars, lpMappingFileName ); 178*cdf0e10cSrcweir else 179*cdf0e10cSrcweir { 180*cdf0e10cSrcweir nChars = 0; 181*cdf0e10cSrcweir SetLastError( ERROR_NOT_ENOUGH_MEMORY ); 182*cdf0e10cSrcweir } 183*cdf0e10cSrcweir } 184*cdf0e10cSrcweir 185*cdf0e10cSrcweir if ( nChars ) 186*cdf0e10cSrcweir { 187*cdf0e10cSrcweir _tcscat( lpMappingFileName, lpMappingName ); 188*cdf0e10cSrcweir 189*cdf0e10cSrcweir HANDLE hFile = CreateFile( 190*cdf0e10cSrcweir lpMappingFileName, 191*cdf0e10cSrcweir GENERIC_READ | GENERIC_WRITE, 192*cdf0e10cSrcweir FILE_SHARE_READ | FILE_SHARE_WRITE, 193*cdf0e10cSrcweir NULL, 194*cdf0e10cSrcweir OPEN_ALWAYS, 195*cdf0e10cSrcweir FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, 196*cdf0e10cSrcweir NULL ); 197*cdf0e10cSrcweir 198*cdf0e10cSrcweir if ( IsValidHandle(hFile) ) 199*cdf0e10cSrcweir { 200*cdf0e10cSrcweir hMapping = CreateFileMapping( 201*cdf0e10cSrcweir (HANDLE)hFile, 202*cdf0e10cSrcweir (LPSECURITY_ATTRIBUTES)NULL, 203*cdf0e10cSrcweir PAGE_READWRITE, 204*cdf0e10cSrcweir 0, 205*cdf0e10cSrcweir sizeof(PipeData), 206*cdf0e10cSrcweir lpMappingName ); 207*cdf0e10cSrcweir 208*cdf0e10cSrcweir CloseHandle( hFile ); 209*cdf0e10cSrcweir } 210*cdf0e10cSrcweir } 211*cdf0e10cSrcweir } 212*cdf0e10cSrcweir else 213*cdf0e10cSrcweir SetLastError( ERROR_NOT_ENOUGH_MEMORY ); 214*cdf0e10cSrcweir } 215*cdf0e10cSrcweir 216*cdf0e10cSrcweir return hMapping; 217*cdf0e10cSrcweir } 218*cdf0e10cSrcweir 219*cdf0e10cSrcweir //---------------------------------------------------------------------------- 220*cdf0e10cSrcweir // 221*cdf0e10cSrcweir //---------------------------------------------------------------------------- 222*cdf0e10cSrcweir 223*cdf0e10cSrcweir HANDLE Pipe::OpenPipeDataMapping( LPCTSTR lpName ) 224*cdf0e10cSrcweir { 225*cdf0e10cSrcweir HANDLE hMapping = NULL; 226*cdf0e10cSrcweir LPTSTR lpMappingName = (LPTSTR)alloca( _tcslen(lpName) * sizeof(TCHAR) + sizeof(PIPE_NAME_PREFIX_MAPPING) ); 227*cdf0e10cSrcweir 228*cdf0e10cSrcweir if ( lpMappingName ) 229*cdf0e10cSrcweir { 230*cdf0e10cSrcweir _tcscpy( lpMappingName, PIPE_NAME_PREFIX_MAPPING ); 231*cdf0e10cSrcweir _tcscat( lpMappingName, lpName ); 232*cdf0e10cSrcweir 233*cdf0e10cSrcweir hMapping = OpenFileMapping( FILE_MAP_ALL_ACCESS, FALSE, lpMappingName ); 234*cdf0e10cSrcweir } 235*cdf0e10cSrcweir 236*cdf0e10cSrcweir return hMapping; 237*cdf0e10cSrcweir } 238*cdf0e10cSrcweir 239*cdf0e10cSrcweir //---------------------------------------------------------------------------- 240*cdf0e10cSrcweir // 241*cdf0e10cSrcweir //---------------------------------------------------------------------------- 242*cdf0e10cSrcweir 243*cdf0e10cSrcweir HANDLE Pipe::CreatePipeDataMutex( LPCTSTR lpName, BOOL bInitialOwner ) 244*cdf0e10cSrcweir { 245*cdf0e10cSrcweir HANDLE hMutex = NULL; 246*cdf0e10cSrcweir LPTSTR lpMutexName = (LPTSTR)alloca( _tcslen(lpName) * sizeof(TCHAR) + sizeof(PIPE_NAME_PREFIX_SYNCHRONIZE) ); 247*cdf0e10cSrcweir 248*cdf0e10cSrcweir if ( lpMutexName ) 249*cdf0e10cSrcweir { 250*cdf0e10cSrcweir _tcscpy( lpMutexName, PIPE_NAME_PREFIX_SYNCHRONIZE ); 251*cdf0e10cSrcweir _tcscat( lpMutexName, lpName ); 252*cdf0e10cSrcweir 253*cdf0e10cSrcweir hMutex = CreateMutex( NULL, bInitialOwner, lpMutexName ); 254*cdf0e10cSrcweir } 255*cdf0e10cSrcweir 256*cdf0e10cSrcweir return hMutex; 257*cdf0e10cSrcweir } 258*cdf0e10cSrcweir 259*cdf0e10cSrcweir //---------------------------------------------------------------------------- 260*cdf0e10cSrcweir // 261*cdf0e10cSrcweir //---------------------------------------------------------------------------- 262*cdf0e10cSrcweir 263*cdf0e10cSrcweir HANDLE Pipe::CreatePipeConnectionSemaphore( LPCTSTR lpName, LONG lInitialCount, LONG lMaximumCount ) 264*cdf0e10cSrcweir { 265*cdf0e10cSrcweir HANDLE hSemaphore = NULL; 266*cdf0e10cSrcweir LPTSTR lpSemaphoreName = (LPTSTR)alloca( _tcslen(lpName) * sizeof(TCHAR) + sizeof(PIPE_NAME_PREFIX_CONNECTION) ); 267*cdf0e10cSrcweir 268*cdf0e10cSrcweir if ( lpSemaphoreName ) 269*cdf0e10cSrcweir { 270*cdf0e10cSrcweir _tcscpy( lpSemaphoreName, PIPE_NAME_PREFIX_CONNECTION ); 271*cdf0e10cSrcweir _tcscat( lpSemaphoreName, lpName ); 272*cdf0e10cSrcweir 273*cdf0e10cSrcweir hSemaphore = CreateSemaphore( NULL, lInitialCount, lMaximumCount, lpSemaphoreName ); 274*cdf0e10cSrcweir } 275*cdf0e10cSrcweir 276*cdf0e10cSrcweir return hSemaphore; 277*cdf0e10cSrcweir } 278*cdf0e10cSrcweir 279*cdf0e10cSrcweir 280*cdf0e10cSrcweir //---------------------------------------------------------------------------- 281*cdf0e10cSrcweir // Pipe copy ctor 282*cdf0e10cSrcweir //---------------------------------------------------------------------------- 283*cdf0e10cSrcweir 284*cdf0e10cSrcweir Pipe::Pipe( const Pipe& rPipe ) : 285*cdf0e10cSrcweir m_hReadPipe( INVALID_HANDLE_VALUE ), 286*cdf0e10cSrcweir m_hWritePipe( INVALID_HANDLE_VALUE ) 287*cdf0e10cSrcweir { 288*cdf0e10cSrcweir DuplicateHandle( 289*cdf0e10cSrcweir GetCurrentProcess(), 290*cdf0e10cSrcweir rPipe.m_hReadPipe, 291*cdf0e10cSrcweir GetCurrentProcess(), 292*cdf0e10cSrcweir &m_hReadPipe, 293*cdf0e10cSrcweir 0, 294*cdf0e10cSrcweir FALSE, 295*cdf0e10cSrcweir DUPLICATE_SAME_ACCESS ); 296*cdf0e10cSrcweir 297*cdf0e10cSrcweir DuplicateHandle( 298*cdf0e10cSrcweir GetCurrentProcess(), 299*cdf0e10cSrcweir rPipe.m_hWritePipe, 300*cdf0e10cSrcweir GetCurrentProcess(), 301*cdf0e10cSrcweir &m_hWritePipe, 302*cdf0e10cSrcweir 0, 303*cdf0e10cSrcweir FALSE, 304*cdf0e10cSrcweir DUPLICATE_SAME_ACCESS ); 305*cdf0e10cSrcweir } 306*cdf0e10cSrcweir 307*cdf0e10cSrcweir //---------------------------------------------------------------------------- 308*cdf0e10cSrcweir // Pipe assignment operator 309*cdf0e10cSrcweir //---------------------------------------------------------------------------- 310*cdf0e10cSrcweir 311*cdf0e10cSrcweir const Pipe& Pipe::operator = ( const Pipe& rPipe ) 312*cdf0e10cSrcweir { 313*cdf0e10cSrcweir Close(); 314*cdf0e10cSrcweir 315*cdf0e10cSrcweir DuplicateHandle( 316*cdf0e10cSrcweir GetCurrentProcess(), 317*cdf0e10cSrcweir rPipe.m_hReadPipe, 318*cdf0e10cSrcweir GetCurrentProcess(), 319*cdf0e10cSrcweir &m_hReadPipe, 320*cdf0e10cSrcweir 0, 321*cdf0e10cSrcweir FALSE, 322*cdf0e10cSrcweir DUPLICATE_SAME_ACCESS ); 323*cdf0e10cSrcweir 324*cdf0e10cSrcweir DuplicateHandle( 325*cdf0e10cSrcweir GetCurrentProcess(), 326*cdf0e10cSrcweir rPipe.m_hWritePipe, 327*cdf0e10cSrcweir GetCurrentProcess(), 328*cdf0e10cSrcweir &m_hWritePipe, 329*cdf0e10cSrcweir 0, 330*cdf0e10cSrcweir FALSE, 331*cdf0e10cSrcweir DUPLICATE_SAME_ACCESS ); 332*cdf0e10cSrcweir 333*cdf0e10cSrcweir return *this; 334*cdf0e10cSrcweir } 335*cdf0e10cSrcweir 336*cdf0e10cSrcweir //---------------------------------------------------------------------------- 337*cdf0e10cSrcweir // Pipe ctor 338*cdf0e10cSrcweir //---------------------------------------------------------------------------- 339*cdf0e10cSrcweir 340*cdf0e10cSrcweir Pipe::Pipe( HANDLE hReadPipe, HANDLE hWritePipe ) : 341*cdf0e10cSrcweir m_hReadPipe( INVALID_HANDLE_VALUE ), 342*cdf0e10cSrcweir m_hWritePipe( INVALID_HANDLE_VALUE ) 343*cdf0e10cSrcweir { 344*cdf0e10cSrcweir DuplicateHandle( 345*cdf0e10cSrcweir GetCurrentProcess(), 346*cdf0e10cSrcweir hReadPipe, 347*cdf0e10cSrcweir GetCurrentProcess(), 348*cdf0e10cSrcweir &m_hReadPipe, 349*cdf0e10cSrcweir 0, 350*cdf0e10cSrcweir FALSE, 351*cdf0e10cSrcweir DUPLICATE_SAME_ACCESS ); 352*cdf0e10cSrcweir 353*cdf0e10cSrcweir DuplicateHandle( 354*cdf0e10cSrcweir GetCurrentProcess(), 355*cdf0e10cSrcweir hWritePipe, 356*cdf0e10cSrcweir GetCurrentProcess(), 357*cdf0e10cSrcweir &m_hWritePipe, 358*cdf0e10cSrcweir 0, 359*cdf0e10cSrcweir FALSE, 360*cdf0e10cSrcweir DUPLICATE_SAME_ACCESS ); 361*cdf0e10cSrcweir } 362*cdf0e10cSrcweir 363*cdf0e10cSrcweir //---------------------------------------------------------------------------- 364*cdf0e10cSrcweir // Pipe dtor 365*cdf0e10cSrcweir //---------------------------------------------------------------------------- 366*cdf0e10cSrcweir 367*cdf0e10cSrcweir Pipe::~Pipe() 368*cdf0e10cSrcweir { 369*cdf0e10cSrcweir Close(); 370*cdf0e10cSrcweir } 371*cdf0e10cSrcweir 372*cdf0e10cSrcweir //---------------------------------------------------------------------------- 373*cdf0e10cSrcweir // Pipe Close 374*cdf0e10cSrcweir //---------------------------------------------------------------------------- 375*cdf0e10cSrcweir 376*cdf0e10cSrcweir bool Pipe::Close() 377*cdf0e10cSrcweir { 378*cdf0e10cSrcweir bool fSuccess = false; // Assume failure 379*cdf0e10cSrcweir 380*cdf0e10cSrcweir if ( IsValidHandle(m_hReadPipe) ) 381*cdf0e10cSrcweir { 382*cdf0e10cSrcweir CloseHandle( m_hReadPipe ); 383*cdf0e10cSrcweir m_hReadPipe = INVALID_HANDLE_VALUE; 384*cdf0e10cSrcweir } 385*cdf0e10cSrcweir 386*cdf0e10cSrcweir if ( IsValidHandle(m_hWritePipe) ) 387*cdf0e10cSrcweir { 388*cdf0e10cSrcweir CloseHandle( m_hWritePipe ); 389*cdf0e10cSrcweir m_hWritePipe = INVALID_HANDLE_VALUE; 390*cdf0e10cSrcweir } 391*cdf0e10cSrcweir 392*cdf0e10cSrcweir return fSuccess; 393*cdf0e10cSrcweir } 394*cdf0e10cSrcweir 395*cdf0e10cSrcweir //---------------------------------------------------------------------------- 396*cdf0e10cSrcweir // Pipe Write 397*cdf0e10cSrcweir //---------------------------------------------------------------------------- 398*cdf0e10cSrcweir 399*cdf0e10cSrcweir bool Pipe::Write( LPCVOID lpBuffer, DWORD dwBytesToWrite, LPDWORD lpBytesWritten, bool bWait ) 400*cdf0e10cSrcweir { 401*cdf0e10cSrcweir DWORD dwBytesAvailable = 0; 402*cdf0e10cSrcweir BOOL fSuccess = TRUE; 403*cdf0e10cSrcweir 404*cdf0e10cSrcweir if ( !bWait ) 405*cdf0e10cSrcweir fSuccess = PeekNamedPipe( m_hReadPipe, NULL, 0, NULL, &dwBytesAvailable, NULL ); 406*cdf0e10cSrcweir 407*cdf0e10cSrcweir if ( fSuccess ) 408*cdf0e10cSrcweir { 409*cdf0e10cSrcweir if ( !bWait && dwBytesToWrite > PIPE_BUFFER_SIZE - dwBytesAvailable ) 410*cdf0e10cSrcweir dwBytesToWrite = PIPE_BUFFER_SIZE - dwBytesAvailable ; 411*cdf0e10cSrcweir 412*cdf0e10cSrcweir return !!WriteFile( m_hWritePipe, lpBuffer, dwBytesToWrite, lpBytesWritten, NULL ); 413*cdf0e10cSrcweir } 414*cdf0e10cSrcweir 415*cdf0e10cSrcweir return false; 416*cdf0e10cSrcweir } 417*cdf0e10cSrcweir 418*cdf0e10cSrcweir //---------------------------------------------------------------------------- 419*cdf0e10cSrcweir // Pipe Read 420*cdf0e10cSrcweir //---------------------------------------------------------------------------- 421*cdf0e10cSrcweir 422*cdf0e10cSrcweir bool Pipe::Read( LPVOID lpBuffer, DWORD dwBytesToRead, LPDWORD lpBytesRead, bool bWait ) 423*cdf0e10cSrcweir { 424*cdf0e10cSrcweir DWORD dwBytesAvailable = 0; 425*cdf0e10cSrcweir BOOL fSuccess = TRUE; 426*cdf0e10cSrcweir 427*cdf0e10cSrcweir if ( !bWait ) 428*cdf0e10cSrcweir fSuccess = PeekNamedPipe( m_hReadPipe, NULL, 0, NULL, &dwBytesAvailable, NULL ); 429*cdf0e10cSrcweir 430*cdf0e10cSrcweir if ( fSuccess ) 431*cdf0e10cSrcweir { 432*cdf0e10cSrcweir if ( bWait || dwBytesAvailable ) 433*cdf0e10cSrcweir return !!ReadFile( m_hReadPipe, lpBuffer, dwBytesToRead, lpBytesRead, NULL ); 434*cdf0e10cSrcweir else 435*cdf0e10cSrcweir { 436*cdf0e10cSrcweir *lpBytesRead = 0; 437*cdf0e10cSrcweir return true; 438*cdf0e10cSrcweir } 439*cdf0e10cSrcweir } 440*cdf0e10cSrcweir 441*cdf0e10cSrcweir return false; 442*cdf0e10cSrcweir } 443*cdf0e10cSrcweir 444*cdf0e10cSrcweir 445*cdf0e10cSrcweir 446*cdf0e10cSrcweir //---------------------------------------------------------------------------- 447*cdf0e10cSrcweir // Client pipe dtor 448*cdf0e10cSrcweir //---------------------------------------------------------------------------- 449*cdf0e10cSrcweir 450*cdf0e10cSrcweir ClientPipe::ClientPipe( HANDLE hReadPipe, HANDLE hWritePipe ) : Pipe( hReadPipe, hWritePipe ) 451*cdf0e10cSrcweir { 452*cdf0e10cSrcweir } 453*cdf0e10cSrcweir 454*cdf0e10cSrcweir //---------------------------------------------------------------------------- 455*cdf0e10cSrcweir // Client pipe creation 456*cdf0e10cSrcweir //---------------------------------------------------------------------------- 457*cdf0e10cSrcweir 458*cdf0e10cSrcweir ClientPipe *ClientPipe::Create( LPCTSTR lpName ) 459*cdf0e10cSrcweir { 460*cdf0e10cSrcweir ClientPipe *pPipe = NULL; // Assume failure 461*cdf0e10cSrcweir 462*cdf0e10cSrcweir HANDLE hMapping = OpenPipeDataMapping( lpName ); 463*cdf0e10cSrcweir 464*cdf0e10cSrcweir if ( IsValidHandle(hMapping) ) 465*cdf0e10cSrcweir { 466*cdf0e10cSrcweir PipeData *pData = (PipeData*)MapViewOfFile( hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0 ); 467*cdf0e10cSrcweir 468*cdf0e10cSrcweir if ( pData ) 469*cdf0e10cSrcweir { 470*cdf0e10cSrcweir HANDLE hSourceProcess = OpenProcess( PROCESS_DUP_HANDLE, FALSE, pData->dwProcessId ); 471*cdf0e10cSrcweir 472*cdf0e10cSrcweir if ( IsValidHandle(hSourceProcess) ) 473*cdf0e10cSrcweir { 474*cdf0e10cSrcweir BOOL fSuccess; 475*cdf0e10cSrcweir HANDLE hReadPipe = INVALID_HANDLE_VALUE, hWritePipe = INVALID_HANDLE_VALUE; 476*cdf0e10cSrcweir 477*cdf0e10cSrcweir fSuccess = DuplicateHandle( 478*cdf0e10cSrcweir hSourceProcess, 479*cdf0e10cSrcweir pData->hReadPipe, 480*cdf0e10cSrcweir GetCurrentProcess(), 481*cdf0e10cSrcweir &hReadPipe, 482*cdf0e10cSrcweir 0, 483*cdf0e10cSrcweir FALSE, 484*cdf0e10cSrcweir DUPLICATE_SAME_ACCESS ); 485*cdf0e10cSrcweir 486*cdf0e10cSrcweir fSuccess = fSuccess && DuplicateHandle( 487*cdf0e10cSrcweir hSourceProcess, 488*cdf0e10cSrcweir pData->hWritePipe, 489*cdf0e10cSrcweir GetCurrentProcess(), 490*cdf0e10cSrcweir &hWritePipe, 491*cdf0e10cSrcweir 0, 492*cdf0e10cSrcweir FALSE, 493*cdf0e10cSrcweir DUPLICATE_SAME_ACCESS ); 494*cdf0e10cSrcweir 495*cdf0e10cSrcweir if ( fSuccess ) 496*cdf0e10cSrcweir pPipe = new ClientPipe( hReadPipe, hWritePipe ); 497*cdf0e10cSrcweir 498*cdf0e10cSrcweir if ( IsValidHandle(hWritePipe) ) 499*cdf0e10cSrcweir CloseHandle( hWritePipe ); 500*cdf0e10cSrcweir 501*cdf0e10cSrcweir if ( IsValidHandle(hReadPipe) ) 502*cdf0e10cSrcweir CloseHandle( hReadPipe ); 503*cdf0e10cSrcweir 504*cdf0e10cSrcweir HANDLE hConnectionRequest = CreatePipeConnectionSemaphore( lpName, 0, 1 ); 505*cdf0e10cSrcweir 506*cdf0e10cSrcweir ReleaseSemaphore( hConnectionRequest, 1, NULL ); 507*cdf0e10cSrcweir 508*cdf0e10cSrcweir CloseHandle( hConnectionRequest ); 509*cdf0e10cSrcweir 510*cdf0e10cSrcweir CloseHandle( hSourceProcess ); 511*cdf0e10cSrcweir } 512*cdf0e10cSrcweir 513*cdf0e10cSrcweir UnmapViewOfFile( pData ); 514*cdf0e10cSrcweir } 515*cdf0e10cSrcweir 516*cdf0e10cSrcweir CloseHandle( hMapping ); 517*cdf0e10cSrcweir } 518*cdf0e10cSrcweir 519*cdf0e10cSrcweir return pPipe; 520*cdf0e10cSrcweir } 521*cdf0e10cSrcweir 522*cdf0e10cSrcweir 523*cdf0e10cSrcweir 524*cdf0e10cSrcweir //---------------------------------------------------------------------------- 525*cdf0e10cSrcweir // ServerPipe ctor 526*cdf0e10cSrcweir //---------------------------------------------------------------------------- 527*cdf0e10cSrcweir 528*cdf0e10cSrcweir ServerPipe::ServerPipe( LPCTSTR lpName, HANDLE hMapping, HANDLE hSynchronize, HANDLE hReadPipe, HANDLE hWritePipe ) : Pipe( hReadPipe, hWritePipe ), 529*cdf0e10cSrcweir m_hMapping( NULL ), 530*cdf0e10cSrcweir m_hSynchronize( NULL ), 531*cdf0e10cSrcweir m_lpName( NULL ) 532*cdf0e10cSrcweir { 533*cdf0e10cSrcweir DuplicateHandle( 534*cdf0e10cSrcweir GetCurrentProcess(), 535*cdf0e10cSrcweir hMapping, 536*cdf0e10cSrcweir GetCurrentProcess(), 537*cdf0e10cSrcweir &m_hMapping, 538*cdf0e10cSrcweir 0, 539*cdf0e10cSrcweir FALSE, 540*cdf0e10cSrcweir DUPLICATE_SAME_ACCESS ); 541*cdf0e10cSrcweir 542*cdf0e10cSrcweir DuplicateHandle( 543*cdf0e10cSrcweir GetCurrentProcess(), 544*cdf0e10cSrcweir hSynchronize, 545*cdf0e10cSrcweir GetCurrentProcess(), 546*cdf0e10cSrcweir &m_hSynchronize, 547*cdf0e10cSrcweir 0, 548*cdf0e10cSrcweir FALSE, 549*cdf0e10cSrcweir DUPLICATE_SAME_ACCESS 550*cdf0e10cSrcweir ); 551*cdf0e10cSrcweir m_lpName = new TCHAR[_tcslen(lpName) + 1]; 552*cdf0e10cSrcweir if ( m_lpName ) 553*cdf0e10cSrcweir _tcscpy( m_lpName, lpName ); 554*cdf0e10cSrcweir } 555*cdf0e10cSrcweir 556*cdf0e10cSrcweir //---------------------------------------------------------------------------- 557*cdf0e10cSrcweir // ServerPipe dtor 558*cdf0e10cSrcweir //---------------------------------------------------------------------------- 559*cdf0e10cSrcweir 560*cdf0e10cSrcweir ServerPipe::~ServerPipe() 561*cdf0e10cSrcweir { 562*cdf0e10cSrcweir if ( IsValidHandle(m_hMapping) ) 563*cdf0e10cSrcweir CloseHandle( m_hMapping ); 564*cdf0e10cSrcweir if ( m_lpName ) 565*cdf0e10cSrcweir delete[]m_lpName; 566*cdf0e10cSrcweir } 567*cdf0e10cSrcweir 568*cdf0e10cSrcweir //---------------------------------------------------------------------------- 569*cdf0e10cSrcweir // ServerPipe AcceptConnection 570*cdf0e10cSrcweir //---------------------------------------------------------------------------- 571*cdf0e10cSrcweir 572*cdf0e10cSrcweir Pipe *ServerPipe::AcceptConnection() 573*cdf0e10cSrcweir { 574*cdf0e10cSrcweir Pipe *pPipe = NULL; // Assume failure; 575*cdf0e10cSrcweir 576*cdf0e10cSrcweir HANDLE hConnectionRequest = CreatePipeConnectionSemaphore( m_lpName, 0, 1 ); 577*cdf0e10cSrcweir 578*cdf0e10cSrcweir if ( WAIT_OBJECT_0 == WaitForSingleObject( hConnectionRequest, INFINITE ) ) 579*cdf0e10cSrcweir { 580*cdf0e10cSrcweir pPipe = new Pipe( *this ); 581*cdf0e10cSrcweir Close(); 582*cdf0e10cSrcweir 583*cdf0e10cSrcweir // Create new inbound Pipe 584*cdf0e10cSrcweir 585*cdf0e10cSrcweir HANDLE hClientWritePipe = NULL, hServerReadPipe = NULL; 586*cdf0e10cSrcweir 587*cdf0e10cSrcweir BOOL fSuccess = CreatePipe( &hServerReadPipe, &hClientWritePipe, NULL, PIPE_BUFFER_SIZE ); 588*cdf0e10cSrcweir 589*cdf0e10cSrcweir 590*cdf0e10cSrcweir if ( fSuccess ) 591*cdf0e10cSrcweir { 592*cdf0e10cSrcweir // Create outbound pipe 593*cdf0e10cSrcweir 594*cdf0e10cSrcweir HANDLE hClientReadPipe = NULL, hServerWritePipe = NULL; 595*cdf0e10cSrcweir 596*cdf0e10cSrcweir if ( CreatePipe( &hClientReadPipe, &hServerWritePipe, NULL, PIPE_BUFFER_SIZE ) ) 597*cdf0e10cSrcweir { 598*cdf0e10cSrcweir m_hReadPipe = hServerReadPipe; 599*cdf0e10cSrcweir m_hWritePipe = hServerWritePipe; 600*cdf0e10cSrcweir 601*cdf0e10cSrcweir PipeData *pData = (PipeData *)MapViewOfFile( m_hMapping, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(PipeData) ); 602*cdf0e10cSrcweir 603*cdf0e10cSrcweir HANDLE hSynchronize = CreatePipeDataMutex( m_lpName, TRUE ); 604*cdf0e10cSrcweir 605*cdf0e10cSrcweir CloseHandle( pData->hReadPipe ); 606*cdf0e10cSrcweir CloseHandle( pData->hWritePipe ); 607*cdf0e10cSrcweir 608*cdf0e10cSrcweir pData->hReadPipe = hClientReadPipe; 609*cdf0e10cSrcweir pData->hWritePipe = hClientWritePipe; 610*cdf0e10cSrcweir 611*cdf0e10cSrcweir ReleaseMutex( hSynchronize ); 612*cdf0e10cSrcweir 613*cdf0e10cSrcweir CloseHandle( hSynchronize ); 614*cdf0e10cSrcweir 615*cdf0e10cSrcweir } 616*cdf0e10cSrcweir else 617*cdf0e10cSrcweir { 618*cdf0e10cSrcweir CloseHandle( hClientWritePipe ); 619*cdf0e10cSrcweir CloseHandle( hServerWritePipe ); 620*cdf0e10cSrcweir } 621*cdf0e10cSrcweir } 622*cdf0e10cSrcweir 623*cdf0e10cSrcweir ReleaseMutex( hConnectionRequest ); 624*cdf0e10cSrcweir } 625*cdf0e10cSrcweir 626*cdf0e10cSrcweir CloseHandle( hConnectionRequest ); 627*cdf0e10cSrcweir 628*cdf0e10cSrcweir return pPipe; 629*cdf0e10cSrcweir } 630*cdf0e10cSrcweir 631*cdf0e10cSrcweir //---------------------------------------------------------------------------- 632*cdf0e10cSrcweir // Pipe creation 633*cdf0e10cSrcweir //---------------------------------------------------------------------------- 634*cdf0e10cSrcweir 635*cdf0e10cSrcweir ServerPipe *ServerPipe::Create( LPCTSTR lpName ) 636*cdf0e10cSrcweir { 637*cdf0e10cSrcweir ServerPipe *pPipe = NULL; 638*cdf0e10cSrcweir 639*cdf0e10cSrcweir HANDLE hMapping = CreatePipeDataMapping( lpName ); 640*cdf0e10cSrcweir 641*cdf0e10cSrcweir if ( IsValidHandle(hMapping) ) 642*cdf0e10cSrcweir { 643*cdf0e10cSrcweir if ( ERROR_FILE_EXISTS != GetLastError() ) 644*cdf0e10cSrcweir { 645*cdf0e10cSrcweir HANDLE hSynchronize = CreatePipeDataMutex( lpName, FALSE); 646*cdf0e10cSrcweir 647*cdf0e10cSrcweir WaitForSingleObject( hSynchronize, INFINITE ); 648*cdf0e10cSrcweir 649*cdf0e10cSrcweir PipeData *pData = (PipeData*)MapViewOfFile( hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0 ); 650*cdf0e10cSrcweir 651*cdf0e10cSrcweir if ( pData ) 652*cdf0e10cSrcweir { 653*cdf0e10cSrcweir 654*cdf0e10cSrcweir // Initialize pipe data 655*cdf0e10cSrcweir 656*cdf0e10cSrcweir pData->dwProcessId = 0; 657*cdf0e10cSrcweir pData->hReadPipe = NULL; 658*cdf0e10cSrcweir pData->hWritePipe = NULL; 659*cdf0e10cSrcweir 660*cdf0e10cSrcweir // Create inbound pipe 661*cdf0e10cSrcweir 662*cdf0e10cSrcweir HANDLE hServerReadPipe = NULL, hClientWritePipe = NULL; 663*cdf0e10cSrcweir 664*cdf0e10cSrcweir BOOL fSuccess = CreatePipe( &hServerReadPipe, &hClientWritePipe, NULL, PIPE_BUFFER_SIZE ); 665*cdf0e10cSrcweir 666*cdf0e10cSrcweir if ( fSuccess ) 667*cdf0e10cSrcweir { 668*cdf0e10cSrcweir // Create outbound pipe 669*cdf0e10cSrcweir 670*cdf0e10cSrcweir HANDLE hServerWritePipe = NULL, hClientReadPipe = NULL; 671*cdf0e10cSrcweir 672*cdf0e10cSrcweir fSuccess = CreatePipe( &hClientReadPipe, &hServerWritePipe, NULL, PIPE_BUFFER_SIZE ); 673*cdf0e10cSrcweir 674*cdf0e10cSrcweir if ( fSuccess ) 675*cdf0e10cSrcweir { 676*cdf0e10cSrcweir pData->dwProcessId = GetCurrentProcessId(); 677*cdf0e10cSrcweir pData->hReadPipe = hClientReadPipe; 678*cdf0e10cSrcweir pData->hWritePipe = hClientWritePipe; 679*cdf0e10cSrcweir pPipe = new ServerPipe( lpName, hMapping, hSynchronize, hServerReadPipe, hServerWritePipe ); 680*cdf0e10cSrcweir 681*cdf0e10cSrcweir CloseHandle( hServerWritePipe ); 682*cdf0e10cSrcweir CloseHandle( hServerReadPipe ); 683*cdf0e10cSrcweir } 684*cdf0e10cSrcweir else 685*cdf0e10cSrcweir { 686*cdf0e10cSrcweir CloseHandle( hServerReadPipe ); 687*cdf0e10cSrcweir CloseHandle( hClientWritePipe ); 688*cdf0e10cSrcweir } 689*cdf0e10cSrcweir } 690*cdf0e10cSrcweir 691*cdf0e10cSrcweir UnmapViewOfFile( pData ); 692*cdf0e10cSrcweir } 693*cdf0e10cSrcweir 694*cdf0e10cSrcweir ReleaseMutex( hSynchronize ); 695*cdf0e10cSrcweir CloseHandle( hSynchronize ); 696*cdf0e10cSrcweir } 697*cdf0e10cSrcweir 698*cdf0e10cSrcweir CloseHandle( hMapping ); 699*cdf0e10cSrcweir } 700*cdf0e10cSrcweir 701*cdf0e10cSrcweir return pPipe; 702*cdf0e10cSrcweir } 703*cdf0e10cSrcweir 704*cdf0e10cSrcweir 705*cdf0e10cSrcweir //---------------------------------------------------------------------------- 706*cdf0e10cSrcweir // C style API 707*cdf0e10cSrcweir //---------------------------------------------------------------------------- 708*cdf0e10cSrcweir 709*cdf0e10cSrcweir const TCHAR LOCAL_PIPE_PREFIX[] = TEXT("\\\\.\\PIPE\\" ); 710*cdf0e10cSrcweir 711*cdf0e10cSrcweir extern "C" HANDLE WINAPI CreateSimplePipe( LPCTSTR lpName ) 712*cdf0e10cSrcweir { 713*cdf0e10cSrcweir int nPrefixLen = _tcslen( LOCAL_PIPE_PREFIX ); 714*cdf0e10cSrcweir if ( 0 == _tcsnicmp( lpName, LOCAL_PIPE_PREFIX, nPrefixLen ) ) 715*cdf0e10cSrcweir lpName += nPrefixLen; 716*cdf0e10cSrcweir return (HANDLE)ServerPipe::Create( lpName ); 717*cdf0e10cSrcweir } 718*cdf0e10cSrcweir 719*cdf0e10cSrcweir extern "C" HANDLE WINAPI OpenSimplePipe( LPCTSTR lpName ) 720*cdf0e10cSrcweir { 721*cdf0e10cSrcweir int nPrefixLen = _tcslen( LOCAL_PIPE_PREFIX ); 722*cdf0e10cSrcweir if ( 0 == _tcsnicmp( lpName, LOCAL_PIPE_PREFIX, nPrefixLen ) ) 723*cdf0e10cSrcweir lpName += nPrefixLen; 724*cdf0e10cSrcweir return (HANDLE)ClientPipe::Create( lpName ); 725*cdf0e10cSrcweir } 726*cdf0e10cSrcweir 727*cdf0e10cSrcweir extern "C" HANDLE WINAPI AcceptSimplePipeConnection( HANDLE hPipe ) 728*cdf0e10cSrcweir { 729*cdf0e10cSrcweir Pipe *pPipe = (Pipe *)hPipe; 730*cdf0e10cSrcweir 731*cdf0e10cSrcweir if ( pPipe->is() ) 732*cdf0e10cSrcweir return (HANDLE)pPipe->AcceptConnection(); 733*cdf0e10cSrcweir else 734*cdf0e10cSrcweir { 735*cdf0e10cSrcweir SetLastError( ERROR_INVALID_HANDLE ); 736*cdf0e10cSrcweir return NULL; 737*cdf0e10cSrcweir } 738*cdf0e10cSrcweir } 739*cdf0e10cSrcweir 740*cdf0e10cSrcweir extern "C" BOOL WINAPI WaitForSimplePipe( LPCTSTR /*lpName*/, DWORD /*dwTimeOut*/ ) 741*cdf0e10cSrcweir { 742*cdf0e10cSrcweir return FALSE; 743*cdf0e10cSrcweir } 744*cdf0e10cSrcweir 745*cdf0e10cSrcweir extern "C" BOOL WINAPI WriteSimplePipe( HANDLE hPipe, LPCVOID lpBuffer, DWORD dwBytesToWrite, LPDWORD lpBytesWritten, BOOL bWait ) 746*cdf0e10cSrcweir { 747*cdf0e10cSrcweir Pipe *pPipe = (Pipe *)hPipe; 748*cdf0e10cSrcweir 749*cdf0e10cSrcweir if ( pPipe->is() ) 750*cdf0e10cSrcweir return pPipe->Write( lpBuffer, dwBytesToWrite, lpBytesWritten, bWait ); 751*cdf0e10cSrcweir else 752*cdf0e10cSrcweir { 753*cdf0e10cSrcweir SetLastError( ERROR_INVALID_HANDLE ); 754*cdf0e10cSrcweir return FALSE; 755*cdf0e10cSrcweir } 756*cdf0e10cSrcweir } 757*cdf0e10cSrcweir 758*cdf0e10cSrcweir extern "C" BOOL WINAPI ReadSimplePipe( HANDLE hPipe, LPVOID lpBuffer, DWORD dwBytesToRead, LPDWORD lpBytesRead, BOOL bWait ) 759*cdf0e10cSrcweir { 760*cdf0e10cSrcweir Pipe *pPipe = (Pipe *)hPipe; 761*cdf0e10cSrcweir 762*cdf0e10cSrcweir if ( pPipe->is() ) 763*cdf0e10cSrcweir return pPipe->Read( lpBuffer, dwBytesToRead, lpBytesRead, bWait ); 764*cdf0e10cSrcweir else 765*cdf0e10cSrcweir { 766*cdf0e10cSrcweir SetLastError( ERROR_INVALID_HANDLE ); 767*cdf0e10cSrcweir return FALSE; 768*cdf0e10cSrcweir } 769*cdf0e10cSrcweir } 770*cdf0e10cSrcweir 771*cdf0e10cSrcweir extern "C" BOOL WINAPI CloseSimplePipe( HANDLE hPipe ) 772*cdf0e10cSrcweir { 773*cdf0e10cSrcweir Pipe *pPipe = (Pipe *)hPipe; 774*cdf0e10cSrcweir 775*cdf0e10cSrcweir if ( pPipe->is() ) 776*cdf0e10cSrcweir { 777*cdf0e10cSrcweir delete pPipe; 778*cdf0e10cSrcweir return TRUE; 779*cdf0e10cSrcweir } 780*cdf0e10cSrcweir else 781*cdf0e10cSrcweir { 782*cdf0e10cSrcweir SetLastError( ERROR_INVALID_HANDLE ); 783*cdf0e10cSrcweir return FALSE; 784*cdf0e10cSrcweir } 785*cdf0e10cSrcweir } 786