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