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