xref: /trunk/main/sal/osl/os2/pipeimpl.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
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