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