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