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 94 virtual Pipe *AcceptConnection() 95 { 96 SetLastError( ERROR_INVALID_HANDLE ); 97 return NULL; 98 } 99 100 void * operator new( size_t nBytes ) 101 { 102 return HeapAlloc( GetProcessHeap(), 0, nBytes ); 103 } 104 105 void operator delete( void *ptr ) 106 { 107 HeapFree( GetProcessHeap(), 0, ptr ); 108 } 109 110 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 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 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 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 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 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 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 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 363 Pipe::~Pipe() 364 { 365 Close(); 366 } 367 368 //---------------------------------------------------------------------------- 369 // Pipe Close 370 //---------------------------------------------------------------------------- 371 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 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 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 446 ClientPipe::ClientPipe( HANDLE hReadPipe, HANDLE hWritePipe ) : Pipe( hReadPipe, hWritePipe ) 447 { 448 } 449 450 //---------------------------------------------------------------------------- 451 // Client pipe creation 452 //---------------------------------------------------------------------------- 453 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 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 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 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 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 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 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 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 736 extern "C" BOOL WINAPI WaitForSimplePipe( LPCTSTR /*lpName*/, DWORD /*dwTimeOut*/ ) 737 { 738 return FALSE; 739 } 740 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 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 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