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