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