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