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