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