xref: /aoo41x/main/sal/osl/w32/pipeimpl.cxx (revision 87d2adbc)
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