14 const TCHAR PIPE_NAME_PREFIX_MAPPING
[] = TEXT("PIPE_FILE_MAPPING_");
15 const TCHAR PIPE_NAME_PREFIX_SYNCHRONIZE
[] = TEXT("PIPE_SYNCHRONIZE_MUTEX_");
16 const TCHAR PIPE_NAME_PREFIX_CONNECTION
[] = TEXT("PIPE_CONNECTION_SEMAPHORE_");
18 const DWORD PIPE_BUFFER_SIZE
= 4096;
21 //============================================================================
23 //============================================================================
32 //============================================================================
34 //============================================================================
38 #define ClientPipe ClientPipeW
39 #define ServerPipe ServerPipeW
42 #define ClientPipe ClientPipeA
43 #define ServerPipe ServerPipeA
49 HANDLE m_hReadPipe
; // Handle to use for reading
50 HANDLE m_hWritePipe
; // Handle to use for writing
52 Pipe( HANDLE hReadPipe
, HANDLE hWritePipe
);
54 static HANDLE
CreatePipeDataMutex( LPCTSTR lpName
, BOOL bInitialOwner
);
55 static HANDLE
CreatePipeDataMapping( LPCTSTR lpName
);
56 static HANDLE
OpenPipeDataMapping( LPCTSTR lpName
);
57 static HANDLE
CreatePipeConnectionSemaphore( LPCTSTR lpName
, LONG lInitialCount
, LONG lMaximumcount
);
61 const Pipe
& operator = ( const Pipe
& );
65 virtual bool Write( LPCVOID lpBuffer
, DWORD dwBytesToWrite
, LPDWORD lpBytesWritten
, bool bWait
= true );
66 virtual bool Read( LPVOID lpBuffer
, DWORD dwBytesToRead
, LPDWORD lpBytesRead
, bool bWait
= true );
68 virtual Pipe
*AcceptConnection()
70 SetLastError( ERROR_INVALID_HANDLE
);
74 void * operator new( size_t nBytes
)
76 return HeapAlloc( GetProcessHeap(), 0, nBytes
);
79 void operator delete( void *ptr
)
81 HeapFree( GetProcessHeap(), 0, ptr
);
86 return (FALSE
!= HeapValidate( GetProcessHeap(), 0, this ));
91 //============================================================================
93 //============================================================================
95 class ClientPipe
: public Pipe
98 ClientPipe( HANDLE hReadPipe
, HANDLE hWritePipe
);
100 static ClientPipe
* Create( LPCTSTR lpName
);
103 //============================================================================
105 //============================================================================
107 class ServerPipe
: public Pipe
111 HANDLE m_hSynchronize
;
114 ServerPipe( LPCTSTR lpName
, HANDLE hMapping
, HANDLE hSynchronize
, HANDLE hReadPipe
, HANDLE hWritePipe
);
116 virtual ~ServerPipe();
118 static ServerPipe
*Create( LPCTSTR lpName
);
120 virtual Pipe
*AcceptConnection();
123 //----------------------------------------------------------------------------
125 //----------------------------------------------------------------------------
127 HANDLE
Pipe::CreatePipeDataMapping( LPCTSTR lpName
)
129 HANDLE hMapping
= NULL
;
130 LPTSTR lpMappingName
= (LPTSTR
)alloca( _tcslen(lpName
) * sizeof(TCHAR
) + sizeof(PIPE_NAME_PREFIX_MAPPING
) );
134 _tcscpy( lpMappingName
, PIPE_NAME_PREFIX_MAPPING
);
135 _tcscat( lpMappingName
, lpName
);
137 LPTSTR lpMappingFileName
= (LPTSTR
)alloca( MAX_PATH
* sizeof(TCHAR
) );
139 if ( lpMappingFileName
)
141 DWORD nChars
= GetTempPath( MAX_PATH
, lpMappingFileName
);
143 if ( MAX_PATH
+ _tcslen(lpName
) < nChars
+ 1 )
145 lpMappingFileName
= (LPTSTR
)alloca( (nChars
+ 1 + _tcslen(lpName
)) * sizeof(TCHAR
) );
146 if ( lpMappingFileName
)
147 nChars
= GetTempPath( nChars
, lpMappingFileName
);
151 SetLastError( ERROR_NOT_ENOUGH_MEMORY
);
157 _tcscat( lpMappingFileName
, lpMappingName
);
159 HANDLE hFile
= CreateFile(
161 GENERIC_READ
| GENERIC_WRITE
,
162 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
165 FILE_ATTRIBUTE_TEMPORARY
| FILE_FLAG_DELETE_ON_CLOSE
,
168 if ( IsValidHandle(hFile
) )
170 hMapping
= CreateFileMapping(
172 (LPSECURITY_ATTRIBUTES
)NULL
,
178 CloseHandle( hFile
);
183 SetLastError( ERROR_NOT_ENOUGH_MEMORY
);
189 //----------------------------------------------------------------------------
191 //----------------------------------------------------------------------------
193 HANDLE
Pipe::OpenPipeDataMapping( LPCTSTR lpName
)
195 HANDLE hMapping
= NULL
;
196 LPTSTR lpMappingName
= (LPTSTR
)alloca( _tcslen(lpName
) * sizeof(TCHAR
) + sizeof(PIPE_NAME_PREFIX_MAPPING
) );
200 _tcscpy( lpMappingName
, PIPE_NAME_PREFIX_MAPPING
);
201 _tcscat( lpMappingName
, lpName
);
203 hMapping
= OpenFileMapping( FILE_MAP_ALL_ACCESS
, FALSE
, lpMappingName
);
209 //----------------------------------------------------------------------------
211 //----------------------------------------------------------------------------
213 HANDLE
Pipe::CreatePipeDataMutex( LPCTSTR lpName
, BOOL bInitialOwner
)
215 HANDLE hMutex
= NULL
;
216 LPTSTR lpMutexName
= (LPTSTR
)alloca( _tcslen(lpName
) * sizeof(TCHAR
) + sizeof(PIPE_NAME_PREFIX_SYNCHRONIZE
) );
220 _tcscpy( lpMutexName
, PIPE_NAME_PREFIX_SYNCHRONIZE
);
221 _tcscat( lpMutexName
, lpName
);
223 hMutex
= CreateMutex( NULL
, bInitialOwner
, lpMutexName
);
229 //----------------------------------------------------------------------------
231 //----------------------------------------------------------------------------
233 HANDLE
Pipe::CreatePipeConnectionSemaphore( LPCTSTR lpName
, LONG lInitialCount
, LONG lMaximumCount
)
235 HANDLE hSemaphore
= NULL
;
236 LPTSTR lpSemaphoreName
= (LPTSTR
)alloca( _tcslen(lpName
) * sizeof(TCHAR
) + sizeof(PIPE_NAME_PREFIX_CONNECTION
) );
238 if ( lpSemaphoreName
)
240 _tcscpy( lpSemaphoreName
, PIPE_NAME_PREFIX_CONNECTION
);
241 _tcscat( lpSemaphoreName
, lpName
);
243 hSemaphore
= CreateSemaphore( NULL
, lInitialCount
, lMaximumCount
, lpSemaphoreName
);
250 //----------------------------------------------------------------------------
252 //----------------------------------------------------------------------------
254 Pipe::Pipe( const Pipe
& rPipe
) :
255 m_hReadPipe( INVALID_HANDLE_VALUE
),
256 m_hWritePipe( INVALID_HANDLE_VALUE
)
265 DUPLICATE_SAME_ACCESS
);
274 DUPLICATE_SAME_ACCESS
);
277 //----------------------------------------------------------------------------
278 // Pipe assignment operator
279 //----------------------------------------------------------------------------
281 const Pipe
& Pipe::operator = ( const Pipe
& rPipe
)
292 DUPLICATE_SAME_ACCESS
);
301 DUPLICATE_SAME_ACCESS
);
306 //----------------------------------------------------------------------------
308 //----------------------------------------------------------------------------
310 Pipe::Pipe( HANDLE hReadPipe
, HANDLE hWritePipe
) :
311 m_hReadPipe( INVALID_HANDLE_VALUE
),
312 m_hWritePipe( INVALID_HANDLE_VALUE
)
321 DUPLICATE_SAME_ACCESS
);
330 DUPLICATE_SAME_ACCESS
);
333 //----------------------------------------------------------------------------
335 //----------------------------------------------------------------------------
342 //----------------------------------------------------------------------------
344 //----------------------------------------------------------------------------
348 bool fSuccess
= false; // Assume failure
350 if ( IsValidHandle(m_hReadPipe
) )
352 CloseHandle( m_hReadPipe
);
353 m_hReadPipe
= INVALID_HANDLE_VALUE
;
356 if ( IsValidHandle(m_hWritePipe
) )
358 CloseHandle( m_hWritePipe
);
359 m_hWritePipe
= INVALID_HANDLE_VALUE
;
365 //----------------------------------------------------------------------------
367 //----------------------------------------------------------------------------
369 bool Pipe::Write( LPCVOID lpBuffer
, DWORD dwBytesToWrite
, LPDWORD lpBytesWritten
, bool bWait
)
371 DWORD dwBytesAvailable
= 0;
372 BOOL fSuccess
= TRUE
;
375 fSuccess
= PeekNamedPipe( m_hReadPipe
, NULL
, 0, NULL
, &dwBytesAvailable
, NULL
);
379 if ( !bWait
&& dwBytesToWrite
> PIPE_BUFFER_SIZE
- dwBytesAvailable
)
380 dwBytesToWrite
= PIPE_BUFFER_SIZE
- dwBytesAvailable
;
382 return !!WriteFile( m_hWritePipe
, lpBuffer
, dwBytesToWrite
, lpBytesWritten
, NULL
);
388 //----------------------------------------------------------------------------
390 //----------------------------------------------------------------------------
392 bool Pipe::Read( LPVOID lpBuffer
, DWORD dwBytesToRead
, LPDWORD lpBytesRead
, bool bWait
)
394 DWORD dwBytesAvailable
= 0;
395 BOOL fSuccess
= TRUE
;
398 fSuccess
= PeekNamedPipe( m_hReadPipe
, NULL
, 0, NULL
, &dwBytesAvailable
, NULL
);
402 if ( bWait
|| dwBytesAvailable
)
403 return !!ReadFile( m_hReadPipe
, lpBuffer
, dwBytesToRead
, lpBytesRead
, NULL
);
416 //----------------------------------------------------------------------------
418 //----------------------------------------------------------------------------
420 ClientPipe::ClientPipe( HANDLE hReadPipe
, HANDLE hWritePipe
) : Pipe( hReadPipe
, hWritePipe
)
424 //----------------------------------------------------------------------------
425 // Client pipe creation
426 //----------------------------------------------------------------------------
428 ClientPipe
*ClientPipe::Create( LPCTSTR lpName
)
430 ClientPipe
*pPipe
= NULL
; // Assume failure
432 HANDLE hMapping
= OpenPipeDataMapping( lpName
);
434 if ( IsValidHandle(hMapping
) )
436 PipeData
*pData
= (PipeData
*)MapViewOfFile( hMapping
, FILE_MAP_ALL_ACCESS
, 0, 0, 0 );
440 HANDLE hSourceProcess
= OpenProcess( PROCESS_DUP_HANDLE
, FALSE
, pData
->dwProcessId
);
442 if ( IsValidHandle(hSourceProcess
) )
445 HANDLE hReadPipe
= INVALID_HANDLE_VALUE
, hWritePipe
= INVALID_HANDLE_VALUE
;
447 fSuccess
= DuplicateHandle(
454 DUPLICATE_SAME_ACCESS
);
456 fSuccess
= fSuccess
&& DuplicateHandle(
463 DUPLICATE_SAME_ACCESS
);
466 pPipe
= new ClientPipe( hReadPipe
, hWritePipe
);
468 if ( IsValidHandle(hWritePipe
) )
469 CloseHandle( hWritePipe
);
471 if ( IsValidHandle(hReadPipe
) )
472 CloseHandle( hReadPipe
);
474 HANDLE hConnectionRequest
= CreatePipeConnectionSemaphore( lpName
, 0, 1 );
476 ReleaseSemaphore( hConnectionRequest
, 1, NULL
);
478 CloseHandle( hConnectionRequest
);
480 CloseHandle( hSourceProcess
);
483 UnmapViewOfFile( pData
);
486 CloseHandle( hMapping
);
494 //----------------------------------------------------------------------------
496 //----------------------------------------------------------------------------
498 ServerPipe::ServerPipe( LPCTSTR lpName
, HANDLE hMapping
, HANDLE hSynchronize
, HANDLE hReadPipe
, HANDLE hWritePipe
) : Pipe( hReadPipe
, hWritePipe
),
500 m_hSynchronize( NULL
),
510 DUPLICATE_SAME_ACCESS
);
519 DUPLICATE_SAME_ACCESS
521 m_lpName
= new TCHAR
[_tcslen(lpName
) + 1];
523 _tcscpy( m_lpName
, lpName
);
526 //----------------------------------------------------------------------------
528 //----------------------------------------------------------------------------
530 ServerPipe::~ServerPipe()
532 if ( IsValidHandle(m_hMapping
) )
533 CloseHandle( m_hMapping
);
538 //----------------------------------------------------------------------------
539 // ServerPipe AcceptConnection
540 //----------------------------------------------------------------------------
542 Pipe
*ServerPipe::AcceptConnection()
544 Pipe
*pPipe
= NULL
; // Assume failure;
546 HANDLE hConnectionRequest
= CreatePipeConnectionSemaphore( m_lpName
, 0, 1 );
548 if ( WAIT_OBJECT_0
== WaitForSingleObject( hConnectionRequest
, INFINITE
) )
550 pPipe
= new Pipe( *this );
553 // Create new inbound Pipe
555 HANDLE hClientWritePipe
= NULL
, hServerReadPipe
= NULL
;
557 BOOL fSuccess
= CreatePipe( &hServerReadPipe
, &hClientWritePipe
, NULL
, PIPE_BUFFER_SIZE
);
562 // Create outbound pipe
564 HANDLE hClientReadPipe
= NULL
, hServerWritePipe
= NULL
;
566 if ( CreatePipe( &hClientReadPipe
, &hServerWritePipe
, NULL
, PIPE_BUFFER_SIZE
) )
568 m_hReadPipe
= hServerReadPipe
;
569 m_hWritePipe
= hServerWritePipe
;
571 PipeData
*pData
= (PipeData
*)MapViewOfFile( m_hMapping
, FILE_MAP_ALL_ACCESS
, 0, 0, sizeof(PipeData
) );
573 HANDLE hSynchronize
= CreatePipeDataMutex( m_lpName
, TRUE
);
575 CloseHandle( pData
->hReadPipe
);
576 CloseHandle( pData
->hWritePipe
);
578 pData
->hReadPipe
= hClientReadPipe
;
579 pData
->hWritePipe
= hClientWritePipe
;
581 ReleaseMutex( hSynchronize
);
583 CloseHandle( hSynchronize
);
588 CloseHandle( hClientWritePipe
);
589 CloseHandle( hServerWritePipe
);
593 ReleaseMutex( hConnectionRequest
);
596 CloseHandle( hConnectionRequest
);
601 //----------------------------------------------------------------------------
603 //----------------------------------------------------------------------------
605 ServerPipe
*ServerPipe::Create( LPCTSTR lpName
)
607 ServerPipe
*pPipe
= NULL
;
609 HANDLE hMapping
= CreatePipeDataMapping( lpName
);
611 if ( IsValidHandle(hMapping
) )
613 if ( ERROR_FILE_EXISTS
!= GetLastError() )
615 HANDLE hSynchronize
= CreatePipeDataMutex( lpName
, FALSE
);
617 WaitForSingleObject( hSynchronize
, INFINITE
);
619 PipeData
*pData
= (PipeData
*)MapViewOfFile( hMapping
, FILE_MAP_ALL_ACCESS
, 0, 0, 0 );
624 // Initialize pipe data
626 pData
->dwProcessId
= 0;
627 pData
->hReadPipe
= NULL
;
628 pData
->hWritePipe
= NULL
;
630 // Create inbound pipe
632 HANDLE hServerReadPipe
= NULL
, hClientWritePipe
= NULL
;
634 BOOL fSuccess
= CreatePipe( &hServerReadPipe
, &hClientWritePipe
, NULL
, PIPE_BUFFER_SIZE
);
638 // Create outbound pipe
640 HANDLE hServerWritePipe
= NULL
, hClientReadPipe
= NULL
;
642 fSuccess
= CreatePipe( &hClientReadPipe
, &hServerWritePipe
, NULL
, PIPE_BUFFER_SIZE
);
646 pData
->dwProcessId
= GetCurrentProcessId();
647 pData
->hReadPipe
= hClientReadPipe
;
648 pData
->hWritePipe
= hClientWritePipe
;
649 pPipe
= new ServerPipe( lpName
, hMapping
, hSynchronize
, hServerReadPipe
, hServerWritePipe
);
651 CloseHandle( hServerWritePipe
);
652 CloseHandle( hServerReadPipe
);
656 CloseHandle( hServerReadPipe
);
657 CloseHandle( hClientWritePipe
);
661 UnmapViewOfFile( pData
);
664 ReleaseMutex( hSynchronize
);
665 CloseHandle( hSynchronize
);
668 CloseHandle( hMapping
);
675 //----------------------------------------------------------------------------
677 //----------------------------------------------------------------------------
679 const TCHAR LOCAL_PIPE_PREFIX
[] = TEXT("\\\\.\\PIPE\\" );
681 extern "C" HANDLE WINAPI
CreateSimplePipe( LPCTSTR lpName
)
683 int nPrefixLen
= _tcslen( LOCAL_PIPE_PREFIX
);
684 if ( 0 == _tcsnicmp( lpName
, LOCAL_PIPE_PREFIX
, nPrefixLen
) )
685 lpName
+= nPrefixLen
;
686 return (HANDLE
)ServerPipe::Create( lpName
);
689 extern "C" HANDLE WINAPI
OpenSimplePipe( LPCTSTR lpName
)
691 int nPrefixLen
= _tcslen( LOCAL_PIPE_PREFIX
);
692 if ( 0 == _tcsnicmp( lpName
, LOCAL_PIPE_PREFIX
, nPrefixLen
) )
693 lpName
+= nPrefixLen
;
694 return (HANDLE
)ClientPipe::Create( lpName
);
697 extern "C" HANDLE WINAPI
AcceptSimplePipeConnection( HANDLE hPipe
)
699 Pipe
*pPipe
= (Pipe
*)hPipe
;
702 return (HANDLE
)pPipe
->AcceptConnection();
705 SetLastError( ERROR_INVALID_HANDLE
);
710 extern "C" BOOL WINAPI
WaitForSimplePipe( LPCTSTR
/*lpName*/, DWORD
/*dwTimeOut*/ )
715 extern "C" BOOL WINAPI
WriteSimplePipe( HANDLE hPipe
, LPCVOID lpBuffer
, DWORD dwBytesToWrite
, LPDWORD lpBytesWritten
, BOOL bWait
)
717 Pipe
*pPipe
= (Pipe
*)hPipe
;
720 return pPipe
->Write( lpBuffer
, dwBytesToWrite
, lpBytesWritten
, bWait
);
723 SetLastError( ERROR_INVALID_HANDLE
);
728 extern "C" BOOL WINAPI
ReadSimplePipe( HANDLE hPipe
, LPVOID lpBuffer
, DWORD dwBytesToRead
, LPDWORD lpBytesRead
, BOOL bWait
)
730 Pipe
*pPipe
= (Pipe
*)hPipe
;
733 return pPipe
->Read( lpBuffer
, dwBytesToRead
, lpBytesRead
, bWait
);
736 SetLastError( ERROR_INVALID_HANDLE
);
741 extern "C" BOOL WINAPI
CloseSimplePipe( HANDLE hPipe
)
743 Pipe
*pPipe
= (Pipe
*)hPipe
;
752 SetLastError( ERROR_INVALID_HANDLE
);