1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir #include "system.h" 29*cdf0e10cSrcweir 30*cdf0e10cSrcweir #include "pipeimpl.h" 31*cdf0e10cSrcweir 32*cdf0e10cSrcweir #include <osl/pipe.h> 33*cdf0e10cSrcweir #include <osl/diagnose.h> 34*cdf0e10cSrcweir #include <osl/thread.h> 35*cdf0e10cSrcweir #include <osl/mutex.h> 36*cdf0e10cSrcweir #include <osl/semaphor.h> 37*cdf0e10cSrcweir #include <osl/conditn.h> 38*cdf0e10cSrcweir #include <osl/interlck.h> 39*cdf0e10cSrcweir #include <osl/process.h> 40*cdf0e10cSrcweir 41*cdf0e10cSrcweir #include <rtl/alloc.h> 42*cdf0e10cSrcweir #include <rtl/memory.h> 43*cdf0e10cSrcweir 44*cdf0e10cSrcweir #define PIPESYSTEM "\\\\.\\pipe\\" 45*cdf0e10cSrcweir #define PIPEPREFIX "OSL_PIPE_" 46*cdf0e10cSrcweir 47*cdf0e10cSrcweir typedef struct 48*cdf0e10cSrcweir { 49*cdf0e10cSrcweir sal_uInt32 m_Size; 50*cdf0e10cSrcweir sal_uInt32 m_ReadPos; 51*cdf0e10cSrcweir sal_uInt32 m_WritePos; 52*cdf0e10cSrcweir BYTE m_Data[1]; 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir } oslPipeBuffer; 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir /*****************************************************************************/ 57*cdf0e10cSrcweir /* oslPipeImpl */ 58*cdf0e10cSrcweir /*****************************************************************************/ 59*cdf0e10cSrcweir 60*cdf0e10cSrcweir struct oslPipeImpl { 61*cdf0e10cSrcweir oslInterlockedCount m_Reference; 62*cdf0e10cSrcweir HANDLE m_File; 63*cdf0e10cSrcweir HANDLE m_NamedObject; 64*cdf0e10cSrcweir PSECURITY_ATTRIBUTES m_Security; 65*cdf0e10cSrcweir HANDLE m_ReadEvent; 66*cdf0e10cSrcweir HANDLE m_WriteEvent; 67*cdf0e10cSrcweir HANDLE m_AcceptEvent; 68*cdf0e10cSrcweir rtl_uString* m_Name; 69*cdf0e10cSrcweir oslPipeError m_Error; 70*cdf0e10cSrcweir sal_Bool m_bClosed; 71*cdf0e10cSrcweir }; 72*cdf0e10cSrcweir 73*cdf0e10cSrcweir 74*cdf0e10cSrcweir /*****************************************************************************/ 75*cdf0e10cSrcweir /* osl_create/destroy-PipeImpl */ 76*cdf0e10cSrcweir /*****************************************************************************/ 77*cdf0e10cSrcweir 78*cdf0e10cSrcweir static oslInterlockedCount nPipes = 0; 79*cdf0e10cSrcweir 80*cdf0e10cSrcweir oslPipe __osl_createPipeImpl(void) 81*cdf0e10cSrcweir { 82*cdf0e10cSrcweir oslPipe pPipe; 83*cdf0e10cSrcweir 84*cdf0e10cSrcweir pPipe = (oslPipe) rtl_allocateZeroMemory(sizeof(struct oslPipeImpl)); 85*cdf0e10cSrcweir 86*cdf0e10cSrcweir pPipe->m_bClosed = sal_False; 87*cdf0e10cSrcweir pPipe->m_Reference = 0; 88*cdf0e10cSrcweir pPipe->m_Name = NULL; 89*cdf0e10cSrcweir pPipe->m_File = INVALID_HANDLE_VALUE; 90*cdf0e10cSrcweir pPipe->m_NamedObject = INVALID_HANDLE_VALUE; 91*cdf0e10cSrcweir 92*cdf0e10cSrcweir pPipe->m_ReadEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 93*cdf0e10cSrcweir pPipe->m_WriteEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 94*cdf0e10cSrcweir pPipe->m_AcceptEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 95*cdf0e10cSrcweir 96*cdf0e10cSrcweir return pPipe; 97*cdf0e10cSrcweir } 98*cdf0e10cSrcweir 99*cdf0e10cSrcweir void __osl_destroyPipeImpl(oslPipe pPipe) 100*cdf0e10cSrcweir { 101*cdf0e10cSrcweir if (pPipe != NULL) 102*cdf0e10cSrcweir { 103*cdf0e10cSrcweir if ( pPipe->m_NamedObject != INVALID_HANDLE_VALUE && pPipe->m_NamedObject != NULL ) 104*cdf0e10cSrcweir CloseHandle( pPipe->m_NamedObject ); 105*cdf0e10cSrcweir 106*cdf0e10cSrcweir if (pPipe->m_Security != NULL) 107*cdf0e10cSrcweir { 108*cdf0e10cSrcweir rtl_freeMemory(pPipe->m_Security->lpSecurityDescriptor); 109*cdf0e10cSrcweir rtl_freeMemory(pPipe->m_Security); 110*cdf0e10cSrcweir } 111*cdf0e10cSrcweir 112*cdf0e10cSrcweir CloseHandle(pPipe->m_ReadEvent); 113*cdf0e10cSrcweir CloseHandle(pPipe->m_WriteEvent); 114*cdf0e10cSrcweir CloseHandle(pPipe->m_AcceptEvent); 115*cdf0e10cSrcweir 116*cdf0e10cSrcweir if (pPipe->m_Name) 117*cdf0e10cSrcweir rtl_uString_release(pPipe->m_Name); 118*cdf0e10cSrcweir 119*cdf0e10cSrcweir rtl_freeMemory(pPipe); 120*cdf0e10cSrcweir } 121*cdf0e10cSrcweir } 122*cdf0e10cSrcweir 123*cdf0e10cSrcweir 124*cdf0e10cSrcweir 125*cdf0e10cSrcweir /*****************************************************************************/ 126*cdf0e10cSrcweir /* osl_createPipe */ 127*cdf0e10cSrcweir /*****************************************************************************/ 128*cdf0e10cSrcweir oslPipe SAL_CALL osl_createPipe(rtl_uString *strPipeName, oslPipeOptions Options, 129*cdf0e10cSrcweir oslSecurity Security) 130*cdf0e10cSrcweir { 131*cdf0e10cSrcweir rtl_uString* name = NULL; 132*cdf0e10cSrcweir rtl_uString* path = NULL; 133*cdf0e10cSrcweir rtl_uString* temp = NULL; 134*cdf0e10cSrcweir oslPipe pPipe; 135*cdf0e10cSrcweir 136*cdf0e10cSrcweir PSECURITY_ATTRIBUTES pSecAttr = NULL; 137*cdf0e10cSrcweir 138*cdf0e10cSrcweir rtl_uString_newFromAscii(&path, PIPESYSTEM); 139*cdf0e10cSrcweir rtl_uString_newFromAscii(&name, PIPEPREFIX); 140*cdf0e10cSrcweir 141*cdf0e10cSrcweir if ( /*IS_NT &&*/ Security) 142*cdf0e10cSrcweir { 143*cdf0e10cSrcweir rtl_uString *Ident = NULL; 144*cdf0e10cSrcweir rtl_uString *Delim = NULL; 145*cdf0e10cSrcweir 146*cdf0e10cSrcweir OSL_VERIFY(osl_getUserIdent(Security, &Ident)); 147*cdf0e10cSrcweir rtl_uString_newFromAscii(&Delim, "_"); 148*cdf0e10cSrcweir 149*cdf0e10cSrcweir rtl_uString_newConcat(&temp, name, Ident); 150*cdf0e10cSrcweir rtl_uString_newConcat(&name, temp, Delim); 151*cdf0e10cSrcweir 152*cdf0e10cSrcweir rtl_uString_release(Ident); 153*cdf0e10cSrcweir rtl_uString_release(Delim); 154*cdf0e10cSrcweir } 155*cdf0e10cSrcweir else 156*cdf0e10cSrcweir { 157*cdf0e10cSrcweir if (Options & osl_Pipe_CREATE) 158*cdf0e10cSrcweir { 159*cdf0e10cSrcweir PSECURITY_DESCRIPTOR pSecDesc; 160*cdf0e10cSrcweir 161*cdf0e10cSrcweir pSecDesc = (PSECURITY_DESCRIPTOR) rtl_allocateMemory(SECURITY_DESCRIPTOR_MIN_LENGTH); 162*cdf0e10cSrcweir 163*cdf0e10cSrcweir /* add a NULL disc. ACL to the security descriptor */ 164*cdf0e10cSrcweir OSL_VERIFY(InitializeSecurityDescriptor(pSecDesc, SECURITY_DESCRIPTOR_REVISION)); 165*cdf0e10cSrcweir OSL_VERIFY(SetSecurityDescriptorDacl(pSecDesc, TRUE, (PACL) NULL, FALSE)); 166*cdf0e10cSrcweir 167*cdf0e10cSrcweir pSecAttr = rtl_allocateMemory(sizeof(SECURITY_ATTRIBUTES)); 168*cdf0e10cSrcweir pSecAttr->nLength = sizeof(SECURITY_ATTRIBUTES); 169*cdf0e10cSrcweir pSecAttr->lpSecurityDescriptor = pSecDesc; 170*cdf0e10cSrcweir pSecAttr->bInheritHandle = TRUE; 171*cdf0e10cSrcweir } 172*cdf0e10cSrcweir } 173*cdf0e10cSrcweir 174*cdf0e10cSrcweir rtl_uString_assign(&temp, name); 175*cdf0e10cSrcweir rtl_uString_newConcat(&name, temp, strPipeName); 176*cdf0e10cSrcweir 177*cdf0e10cSrcweir /* alloc memory */ 178*cdf0e10cSrcweir pPipe= __osl_createPipeImpl(); 179*cdf0e10cSrcweir osl_incrementInterlockedCount(&(pPipe->m_Reference)); 180*cdf0e10cSrcweir 181*cdf0e10cSrcweir /* build system pipe name */ 182*cdf0e10cSrcweir rtl_uString_assign(&temp, path); 183*cdf0e10cSrcweir rtl_uString_newConcat(&path, temp, name); 184*cdf0e10cSrcweir rtl_uString_release(temp); 185*cdf0e10cSrcweir temp = NULL; 186*cdf0e10cSrcweir 187*cdf0e10cSrcweir if (Options & osl_Pipe_CREATE) 188*cdf0e10cSrcweir { 189*cdf0e10cSrcweir SetLastError( ERROR_SUCCESS ); 190*cdf0e10cSrcweir 191*cdf0e10cSrcweir if ( IS_NT ) 192*cdf0e10cSrcweir pPipe->m_NamedObject = CreateMutexW( NULL, FALSE, name->buffer ); 193*cdf0e10cSrcweir else 194*cdf0e10cSrcweir { 195*cdf0e10cSrcweir LPSTR pszTempBuffer = NULL; 196*cdf0e10cSrcweir int nCharsNeeded; 197*cdf0e10cSrcweir 198*cdf0e10cSrcweir nCharsNeeded = WideCharToMultiByte( CP_ACP, 0, name->buffer, name->length, NULL, 0, NULL, NULL ); 199*cdf0e10cSrcweir pszTempBuffer = alloca( nCharsNeeded * sizeof(CHAR) ); 200*cdf0e10cSrcweir nCharsNeeded = WideCharToMultiByte( CP_ACP, 0, name->buffer, name->length, pszTempBuffer, nCharsNeeded, NULL, NULL ); 201*cdf0e10cSrcweir pszTempBuffer[nCharsNeeded-1] = 0; 202*cdf0e10cSrcweir 203*cdf0e10cSrcweir pPipe->m_NamedObject = CreateMutexA( NULL, FALSE, pszTempBuffer ); 204*cdf0e10cSrcweir } 205*cdf0e10cSrcweir 206*cdf0e10cSrcweir if ( pPipe->m_NamedObject != INVALID_HANDLE_VALUE && pPipe->m_NamedObject != NULL ) 207*cdf0e10cSrcweir { 208*cdf0e10cSrcweir if ( GetLastError() != ERROR_ALREADY_EXISTS ) 209*cdf0e10cSrcweir { 210*cdf0e10cSrcweir pPipe->m_Security = pSecAttr; 211*cdf0e10cSrcweir rtl_uString_assign(&pPipe->m_Name, name); 212*cdf0e10cSrcweir 213*cdf0e10cSrcweir if (IS_NT) 214*cdf0e10cSrcweir { 215*cdf0e10cSrcweir /* try to open system pipe */ 216*cdf0e10cSrcweir pPipe->m_File = CreateNamedPipeW( 217*cdf0e10cSrcweir path->buffer, 218*cdf0e10cSrcweir PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 219*cdf0e10cSrcweir PIPE_WAIT | PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, 220*cdf0e10cSrcweir PIPE_UNLIMITED_INSTANCES, 221*cdf0e10cSrcweir 4096, 4096, 222*cdf0e10cSrcweir NMPWAIT_WAIT_FOREVER, 223*cdf0e10cSrcweir pPipe->m_Security); 224*cdf0e10cSrcweir 225*cdf0e10cSrcweir if (pPipe->m_File != INVALID_HANDLE_VALUE) 226*cdf0e10cSrcweir { 227*cdf0e10cSrcweir rtl_uString_release( name ); 228*cdf0e10cSrcweir rtl_uString_release( path ); 229*cdf0e10cSrcweir 230*cdf0e10cSrcweir return pPipe; 231*cdf0e10cSrcweir } 232*cdf0e10cSrcweir } 233*cdf0e10cSrcweir else /* Win 9x */ 234*cdf0e10cSrcweir { 235*cdf0e10cSrcweir LPSTR pszTempBuffer = NULL; 236*cdf0e10cSrcweir int nCharsNeeded; 237*cdf0e10cSrcweir 238*cdf0e10cSrcweir nCharsNeeded = WideCharToMultiByte( CP_ACP, 0, path->buffer, path->length, NULL, 0, NULL, NULL ); 239*cdf0e10cSrcweir pszTempBuffer = alloca( nCharsNeeded * sizeof(CHAR) ); 240*cdf0e10cSrcweir nCharsNeeded = WideCharToMultiByte( CP_ACP, 0, path->buffer, path->length, pszTempBuffer, nCharsNeeded, NULL, NULL ); 241*cdf0e10cSrcweir pszTempBuffer[nCharsNeeded-1] = 0; 242*cdf0e10cSrcweir 243*cdf0e10cSrcweir pPipe->m_File = CreateSimplePipe( pszTempBuffer ); 244*cdf0e10cSrcweir 245*cdf0e10cSrcweir if ( IsValidHandle(pPipe->m_File) ) 246*cdf0e10cSrcweir { 247*cdf0e10cSrcweir rtl_uString_release( name ); 248*cdf0e10cSrcweir rtl_uString_release( path ); 249*cdf0e10cSrcweir 250*cdf0e10cSrcweir return pPipe; 251*cdf0e10cSrcweir } 252*cdf0e10cSrcweir } 253*cdf0e10cSrcweir } 254*cdf0e10cSrcweir else 255*cdf0e10cSrcweir { 256*cdf0e10cSrcweir CloseHandle( pPipe->m_NamedObject ); 257*cdf0e10cSrcweir pPipe->m_NamedObject = INVALID_HANDLE_VALUE; 258*cdf0e10cSrcweir } 259*cdf0e10cSrcweir } 260*cdf0e10cSrcweir } 261*cdf0e10cSrcweir else 262*cdf0e10cSrcweir { 263*cdf0e10cSrcweir if (IS_NT) 264*cdf0e10cSrcweir { 265*cdf0e10cSrcweir BOOL fPipeAvailable; 266*cdf0e10cSrcweir 267*cdf0e10cSrcweir do 268*cdf0e10cSrcweir { 269*cdf0e10cSrcweir /* free instance should be available first */ 270*cdf0e10cSrcweir fPipeAvailable = WaitNamedPipeW(path->buffer, NMPWAIT_WAIT_FOREVER); 271*cdf0e10cSrcweir 272*cdf0e10cSrcweir /* first try to open system pipe */ 273*cdf0e10cSrcweir if ( fPipeAvailable ) 274*cdf0e10cSrcweir { 275*cdf0e10cSrcweir pPipe->m_File = CreateFileW( 276*cdf0e10cSrcweir path->buffer, 277*cdf0e10cSrcweir GENERIC_READ|GENERIC_WRITE, 278*cdf0e10cSrcweir FILE_SHARE_READ | FILE_SHARE_WRITE, 279*cdf0e10cSrcweir NULL, 280*cdf0e10cSrcweir OPEN_EXISTING, 281*cdf0e10cSrcweir FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 282*cdf0e10cSrcweir NULL); 283*cdf0e10cSrcweir 284*cdf0e10cSrcweir if ( pPipe->m_File != INVALID_HANDLE_VALUE ) 285*cdf0e10cSrcweir { 286*cdf0e10cSrcweir // We got it ! 287*cdf0e10cSrcweir rtl_uString_release( name ); 288*cdf0e10cSrcweir rtl_uString_release( path ); 289*cdf0e10cSrcweir 290*cdf0e10cSrcweir return (pPipe); 291*cdf0e10cSrcweir } 292*cdf0e10cSrcweir else 293*cdf0e10cSrcweir { 294*cdf0e10cSrcweir // Pipe instance maybe catched by another client -> try again 295*cdf0e10cSrcweir } 296*cdf0e10cSrcweir } 297*cdf0e10cSrcweir } while ( fPipeAvailable ); 298*cdf0e10cSrcweir } 299*cdf0e10cSrcweir else /* Win 9x */ 300*cdf0e10cSrcweir { 301*cdf0e10cSrcweir LPSTR pszTempBuffer = NULL; 302*cdf0e10cSrcweir int nCharsNeeded; 303*cdf0e10cSrcweir 304*cdf0e10cSrcweir nCharsNeeded = WideCharToMultiByte( CP_ACP, 0, path->buffer, path->length, NULL, 0, NULL, NULL ); 305*cdf0e10cSrcweir pszTempBuffer = alloca( nCharsNeeded * sizeof(CHAR) ); 306*cdf0e10cSrcweir nCharsNeeded = WideCharToMultiByte( CP_ACP, 0, path->buffer, path->length, pszTempBuffer, nCharsNeeded, NULL, NULL ); 307*cdf0e10cSrcweir pszTempBuffer[nCharsNeeded-1] = 0; 308*cdf0e10cSrcweir 309*cdf0e10cSrcweir pPipe->m_File = OpenSimplePipe( pszTempBuffer ); 310*cdf0e10cSrcweir 311*cdf0e10cSrcweir if ( IsValidHandle(pPipe->m_File) ) 312*cdf0e10cSrcweir { 313*cdf0e10cSrcweir // We got it ! 314*cdf0e10cSrcweir rtl_uString_release( name ); 315*cdf0e10cSrcweir rtl_uString_release( path ); 316*cdf0e10cSrcweir 317*cdf0e10cSrcweir return (pPipe); 318*cdf0e10cSrcweir } 319*cdf0e10cSrcweir } 320*cdf0e10cSrcweir } 321*cdf0e10cSrcweir 322*cdf0e10cSrcweir /* if we reach here something went wrong */ 323*cdf0e10cSrcweir __osl_destroyPipeImpl(pPipe); 324*cdf0e10cSrcweir 325*cdf0e10cSrcweir return NULL; 326*cdf0e10cSrcweir } 327*cdf0e10cSrcweir 328*cdf0e10cSrcweir void SAL_CALL osl_acquirePipe( oslPipe pPipe ) 329*cdf0e10cSrcweir { 330*cdf0e10cSrcweir osl_incrementInterlockedCount( &(pPipe->m_Reference) ); 331*cdf0e10cSrcweir } 332*cdf0e10cSrcweir 333*cdf0e10cSrcweir void SAL_CALL osl_releasePipe( oslPipe pPipe ) 334*cdf0e10cSrcweir { 335*cdf0e10cSrcweir // OSL_ASSERT( pPipe ); 336*cdf0e10cSrcweir 337*cdf0e10cSrcweir if( 0 == pPipe ) 338*cdf0e10cSrcweir return; 339*cdf0e10cSrcweir 340*cdf0e10cSrcweir if( 0 == osl_decrementInterlockedCount( &(pPipe->m_Reference) ) ) 341*cdf0e10cSrcweir { 342*cdf0e10cSrcweir if( ! pPipe->m_bClosed ) 343*cdf0e10cSrcweir osl_closePipe( pPipe ); 344*cdf0e10cSrcweir 345*cdf0e10cSrcweir __osl_destroyPipeImpl( pPipe ); 346*cdf0e10cSrcweir } 347*cdf0e10cSrcweir } 348*cdf0e10cSrcweir 349*cdf0e10cSrcweir void SAL_CALL osl_closePipe( oslPipe pPipe ) 350*cdf0e10cSrcweir { 351*cdf0e10cSrcweir if( pPipe && ! pPipe->m_bClosed ) 352*cdf0e10cSrcweir { 353*cdf0e10cSrcweir pPipe->m_bClosed = sal_True; 354*cdf0e10cSrcweir if (IS_NT) 355*cdf0e10cSrcweir { 356*cdf0e10cSrcweir /* if we have a system pipe close it */ 357*cdf0e10cSrcweir if (pPipe->m_File != INVALID_HANDLE_VALUE) 358*cdf0e10cSrcweir { 359*cdf0e10cSrcweir /* FlushFileBuffers(pPipe->m_File); */ 360*cdf0e10cSrcweir DisconnectNamedPipe(pPipe->m_File); 361*cdf0e10cSrcweir CloseHandle(pPipe->m_File); 362*cdf0e10cSrcweir } 363*cdf0e10cSrcweir } 364*cdf0e10cSrcweir else 365*cdf0e10cSrcweir { 366*cdf0e10cSrcweir CloseSimplePipe( pPipe->m_File ); 367*cdf0e10cSrcweir } 368*cdf0e10cSrcweir 369*cdf0e10cSrcweir } 370*cdf0e10cSrcweir } 371*cdf0e10cSrcweir 372*cdf0e10cSrcweir /*****************************************************************************/ 373*cdf0e10cSrcweir /* osl_acceptPipe */ 374*cdf0e10cSrcweir /*****************************************************************************/ 375*cdf0e10cSrcweir oslPipe SAL_CALL osl_acceptPipe(oslPipe pPipe) 376*cdf0e10cSrcweir { 377*cdf0e10cSrcweir oslPipe pAcceptedPipe = NULL; 378*cdf0e10cSrcweir 379*cdf0e10cSrcweir HANDLE Event; 380*cdf0e10cSrcweir OVERLAPPED os; 381*cdf0e10cSrcweir 382*cdf0e10cSrcweir OSL_ASSERT(pPipe); 383*cdf0e10cSrcweir 384*cdf0e10cSrcweir if (IS_NT) 385*cdf0e10cSrcweir { 386*cdf0e10cSrcweir DWORD nBytesTransfered; 387*cdf0e10cSrcweir rtl_uString* path = NULL; 388*cdf0e10cSrcweir rtl_uString* temp = NULL; 389*cdf0e10cSrcweir 390*cdf0e10cSrcweir OSL_ASSERT (pPipe->m_File != INVALID_HANDLE_VALUE); 391*cdf0e10cSrcweir 392*cdf0e10cSrcweir Event = pPipe->m_AcceptEvent; 393*cdf0e10cSrcweir rtl_zeroMemory(&os, sizeof(OVERLAPPED)); 394*cdf0e10cSrcweir os.hEvent = pPipe->m_AcceptEvent; 395*cdf0e10cSrcweir ResetEvent(pPipe->m_AcceptEvent); 396*cdf0e10cSrcweir 397*cdf0e10cSrcweir if ( !ConnectNamedPipe(pPipe->m_File, &os)) 398*cdf0e10cSrcweir { 399*cdf0e10cSrcweir switch ( GetLastError() ) 400*cdf0e10cSrcweir { 401*cdf0e10cSrcweir case ERROR_PIPE_CONNECTED: // Client already connected to pipe 402*cdf0e10cSrcweir case ERROR_NO_DATA: // Client was connected but has already closed pipe end 403*cdf0e10cSrcweir // should only appear in nonblocking mode but in fact does 404*cdf0e10cSrcweir // in blocking asynchronous mode. 405*cdf0e10cSrcweir break; 406*cdf0e10cSrcweir case ERROR_PIPE_LISTENING: // Only for nonblocking mode but see ERROR_NO_DATA 407*cdf0e10cSrcweir case ERROR_IO_PENDING: // This is normal if not client is connected yet 408*cdf0e10cSrcweir case ERROR_MORE_DATA: // Should not happen 409*cdf0e10cSrcweir // blocking call to accept 410*cdf0e10cSrcweir if( !GetOverlappedResult( pPipe->m_File, &os, &nBytesTransfered, TRUE ) ) 411*cdf0e10cSrcweir { 412*cdf0e10cSrcweir // Possible error could be that between ConnectNamedPipe and GetOverlappedResult a connect 413*cdf0e10cSrcweir // took place. 414*cdf0e10cSrcweir 415*cdf0e10cSrcweir switch ( GetLastError() ) 416*cdf0e10cSrcweir { 417*cdf0e10cSrcweir case ERROR_PIPE_CONNECTED: // Pipe was already connected 418*cdf0e10cSrcweir case ERROR_NO_DATA: // Pipe was connected but client has already closed -> ver fast client ;-) 419*cdf0e10cSrcweir break; // Everything's fine !!! 420*cdf0e10cSrcweir default: 421*cdf0e10cSrcweir // Something went wrong 422*cdf0e10cSrcweir return 0; 423*cdf0e10cSrcweir } 424*cdf0e10cSrcweir } 425*cdf0e10cSrcweir break; 426*cdf0e10cSrcweir default: // All other error say that somethings going wrong. 427*cdf0e10cSrcweir return 0; 428*cdf0e10cSrcweir } 429*cdf0e10cSrcweir } 430*cdf0e10cSrcweir 431*cdf0e10cSrcweir 432*cdf0e10cSrcweir pAcceptedPipe = __osl_createPipeImpl(); 433*cdf0e10cSrcweir OSL_ASSERT(pAcceptedPipe); 434*cdf0e10cSrcweir 435*cdf0e10cSrcweir osl_incrementInterlockedCount(&(pAcceptedPipe->m_Reference)); 436*cdf0e10cSrcweir rtl_uString_assign(&pAcceptedPipe->m_Name, pPipe->m_Name); 437*cdf0e10cSrcweir pAcceptedPipe->m_File = pPipe->m_File; 438*cdf0e10cSrcweir 439*cdf0e10cSrcweir rtl_uString_newFromAscii(&temp, PIPESYSTEM); 440*cdf0e10cSrcweir rtl_uString_newConcat(&path, temp, pPipe->m_Name); 441*cdf0e10cSrcweir rtl_uString_release(temp); 442*cdf0e10cSrcweir 443*cdf0e10cSrcweir // prepare for next accept 444*cdf0e10cSrcweir pPipe->m_File = 445*cdf0e10cSrcweir CreateNamedPipeW(path->buffer, 446*cdf0e10cSrcweir PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 447*cdf0e10cSrcweir PIPE_WAIT | PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, 448*cdf0e10cSrcweir PIPE_UNLIMITED_INSTANCES, 449*cdf0e10cSrcweir 4096, 4096, 450*cdf0e10cSrcweir NMPWAIT_WAIT_FOREVER, 451*cdf0e10cSrcweir pAcceptedPipe->m_Security); 452*cdf0e10cSrcweir rtl_uString_release( path ); 453*cdf0e10cSrcweir } 454*cdf0e10cSrcweir else /* Win9x */ 455*cdf0e10cSrcweir { 456*cdf0e10cSrcweir pAcceptedPipe = __osl_createPipeImpl(); 457*cdf0e10cSrcweir OSL_ASSERT(pAcceptedPipe); 458*cdf0e10cSrcweir 459*cdf0e10cSrcweir osl_incrementInterlockedCount(&(pAcceptedPipe->m_Reference)); 460*cdf0e10cSrcweir rtl_uString_assign(&pAcceptedPipe->m_Name, pPipe->m_Name); 461*cdf0e10cSrcweir pAcceptedPipe->m_File = pPipe->m_File; 462*cdf0e10cSrcweir 463*cdf0e10cSrcweir pAcceptedPipe->m_File = AcceptSimplePipeConnection( pPipe->m_File ); 464*cdf0e10cSrcweir } 465*cdf0e10cSrcweir 466*cdf0e10cSrcweir return pAcceptedPipe; 467*cdf0e10cSrcweir } 468*cdf0e10cSrcweir 469*cdf0e10cSrcweir /*****************************************************************************/ 470*cdf0e10cSrcweir /* osl_receivePipe */ 471*cdf0e10cSrcweir /*****************************************************************************/ 472*cdf0e10cSrcweir sal_Int32 SAL_CALL osl_receivePipe(oslPipe pPipe, 473*cdf0e10cSrcweir void* pBuffer, 474*cdf0e10cSrcweir sal_Int32 BytesToRead) 475*cdf0e10cSrcweir { 476*cdf0e10cSrcweir DWORD nBytes; 477*cdf0e10cSrcweir 478*cdf0e10cSrcweir OSL_ASSERT(pPipe); 479*cdf0e10cSrcweir 480*cdf0e10cSrcweir /* if we have a system pipe use it */ 481*cdf0e10cSrcweir if ( IS_NT /*pPipe->m_File != INVALID_HANDLE_VALUE*/) 482*cdf0e10cSrcweir { 483*cdf0e10cSrcweir OVERLAPPED os; 484*cdf0e10cSrcweir rtl_zeroMemory(&os,sizeof(OVERLAPPED)); 485*cdf0e10cSrcweir os.hEvent = pPipe->m_ReadEvent; 486*cdf0e10cSrcweir 487*cdf0e10cSrcweir ResetEvent(pPipe->m_ReadEvent); 488*cdf0e10cSrcweir 489*cdf0e10cSrcweir if (! ReadFile(pPipe->m_File, pBuffer, BytesToRead, &nBytes, &os) && 490*cdf0e10cSrcweir ((GetLastError() != ERROR_IO_PENDING) || 491*cdf0e10cSrcweir ! GetOverlappedResult(pPipe->m_File, &os, &nBytes, TRUE))) 492*cdf0e10cSrcweir { 493*cdf0e10cSrcweir DWORD lastError = GetLastError(); 494*cdf0e10cSrcweir 495*cdf0e10cSrcweir if (lastError == ERROR_MORE_DATA) 496*cdf0e10cSrcweir nBytes = BytesToRead; 497*cdf0e10cSrcweir else 498*cdf0e10cSrcweir { 499*cdf0e10cSrcweir if (lastError == ERROR_PIPE_NOT_CONNECTED) 500*cdf0e10cSrcweir nBytes = 0; 501*cdf0e10cSrcweir else 502*cdf0e10cSrcweir nBytes = (DWORD) -1; 503*cdf0e10cSrcweir 504*cdf0e10cSrcweir pPipe->m_Error = osl_Pipe_E_ConnectionAbort; 505*cdf0e10cSrcweir } 506*cdf0e10cSrcweir } 507*cdf0e10cSrcweir } 508*cdf0e10cSrcweir else 509*cdf0e10cSrcweir { 510*cdf0e10cSrcweir BOOL fSuccess = ReadSimplePipe( pPipe->m_File, pBuffer, BytesToRead, &nBytes, TRUE ); 511*cdf0e10cSrcweir 512*cdf0e10cSrcweir if ( !fSuccess ) 513*cdf0e10cSrcweir { 514*cdf0e10cSrcweir nBytes = 0; 515*cdf0e10cSrcweir pPipe->m_Error = osl_Pipe_E_ConnectionAbort; 516*cdf0e10cSrcweir } 517*cdf0e10cSrcweir 518*cdf0e10cSrcweir } 519*cdf0e10cSrcweir 520*cdf0e10cSrcweir return (nBytes); 521*cdf0e10cSrcweir } 522*cdf0e10cSrcweir 523*cdf0e10cSrcweir /*****************************************************************************/ 524*cdf0e10cSrcweir /* osl_sendPipe */ 525*cdf0e10cSrcweir /*****************************************************************************/ 526*cdf0e10cSrcweir sal_Int32 SAL_CALL osl_sendPipe(oslPipe pPipe, 527*cdf0e10cSrcweir const void* pBuffer, 528*cdf0e10cSrcweir sal_Int32 BytesToSend) 529*cdf0e10cSrcweir { 530*cdf0e10cSrcweir DWORD nBytes; 531*cdf0e10cSrcweir OSL_ASSERT(pPipe); 532*cdf0e10cSrcweir 533*cdf0e10cSrcweir if (IS_NT/*pPipe->m_File != INVALID_HANDLE_VALUE*/) 534*cdf0e10cSrcweir { 535*cdf0e10cSrcweir OVERLAPPED os; 536*cdf0e10cSrcweir rtl_zeroMemory(&os, sizeof(OVERLAPPED)); 537*cdf0e10cSrcweir os.hEvent = pPipe->m_WriteEvent; 538*cdf0e10cSrcweir ResetEvent(pPipe->m_WriteEvent); 539*cdf0e10cSrcweir 540*cdf0e10cSrcweir if (! WriteFile(pPipe->m_File, pBuffer, BytesToSend, &nBytes, &os) && 541*cdf0e10cSrcweir ((GetLastError() != ERROR_IO_PENDING) || 542*cdf0e10cSrcweir ! GetOverlappedResult(pPipe->m_File, &os, &nBytes, TRUE))) 543*cdf0e10cSrcweir { 544*cdf0e10cSrcweir if (GetLastError() == ERROR_PIPE_NOT_CONNECTED) 545*cdf0e10cSrcweir nBytes = 0; 546*cdf0e10cSrcweir else 547*cdf0e10cSrcweir nBytes = (DWORD) -1; 548*cdf0e10cSrcweir 549*cdf0e10cSrcweir pPipe->m_Error = osl_Pipe_E_ConnectionAbort; 550*cdf0e10cSrcweir } 551*cdf0e10cSrcweir } 552*cdf0e10cSrcweir else 553*cdf0e10cSrcweir { 554*cdf0e10cSrcweir BOOL fSuccess = WriteSimplePipe( pPipe->m_File, pBuffer, BytesToSend, &nBytes, TRUE ); 555*cdf0e10cSrcweir 556*cdf0e10cSrcweir if ( !fSuccess ) 557*cdf0e10cSrcweir { 558*cdf0e10cSrcweir nBytes = 0; 559*cdf0e10cSrcweir pPipe->m_Error = osl_Pipe_E_ConnectionAbort; 560*cdf0e10cSrcweir } 561*cdf0e10cSrcweir } 562*cdf0e10cSrcweir 563*cdf0e10cSrcweir return (nBytes); 564*cdf0e10cSrcweir } 565*cdf0e10cSrcweir 566*cdf0e10cSrcweir sal_Int32 SAL_CALL osl_writePipe( oslPipe pPipe, const void *pBuffer , sal_Int32 n ) 567*cdf0e10cSrcweir { 568*cdf0e10cSrcweir /* loop until all desired bytes were send or an error occured */ 569*cdf0e10cSrcweir sal_Int32 BytesSend= 0; 570*cdf0e10cSrcweir sal_Int32 BytesToSend= n; 571*cdf0e10cSrcweir 572*cdf0e10cSrcweir OSL_ASSERT(pPipe); 573*cdf0e10cSrcweir while (BytesToSend > 0) 574*cdf0e10cSrcweir { 575*cdf0e10cSrcweir sal_Int32 RetVal; 576*cdf0e10cSrcweir 577*cdf0e10cSrcweir RetVal= osl_sendPipe(pPipe, pBuffer, BytesToSend); 578*cdf0e10cSrcweir 579*cdf0e10cSrcweir /* error occured? */ 580*cdf0e10cSrcweir if(RetVal <= 0) 581*cdf0e10cSrcweir { 582*cdf0e10cSrcweir break; 583*cdf0e10cSrcweir } 584*cdf0e10cSrcweir 585*cdf0e10cSrcweir BytesToSend -= RetVal; 586*cdf0e10cSrcweir BytesSend += RetVal; 587*cdf0e10cSrcweir pBuffer= (sal_Char*)pBuffer + RetVal; 588*cdf0e10cSrcweir } 589*cdf0e10cSrcweir 590*cdf0e10cSrcweir return BytesSend; 591*cdf0e10cSrcweir } 592*cdf0e10cSrcweir 593*cdf0e10cSrcweir sal_Int32 SAL_CALL osl_readPipe( oslPipe pPipe, void *pBuffer , sal_Int32 n ) 594*cdf0e10cSrcweir { 595*cdf0e10cSrcweir /* loop until all desired bytes were read or an error occured */ 596*cdf0e10cSrcweir sal_Int32 BytesRead= 0; 597*cdf0e10cSrcweir sal_Int32 BytesToRead= n; 598*cdf0e10cSrcweir 599*cdf0e10cSrcweir OSL_ASSERT( pPipe ); 600*cdf0e10cSrcweir while (BytesToRead > 0) 601*cdf0e10cSrcweir { 602*cdf0e10cSrcweir sal_Int32 RetVal; 603*cdf0e10cSrcweir RetVal= osl_receivePipe(pPipe, pBuffer, BytesToRead); 604*cdf0e10cSrcweir 605*cdf0e10cSrcweir /* error occured? */ 606*cdf0e10cSrcweir if(RetVal <= 0) 607*cdf0e10cSrcweir { 608*cdf0e10cSrcweir break; 609*cdf0e10cSrcweir } 610*cdf0e10cSrcweir 611*cdf0e10cSrcweir BytesToRead -= RetVal; 612*cdf0e10cSrcweir BytesRead += RetVal; 613*cdf0e10cSrcweir pBuffer= (sal_Char*)pBuffer + RetVal; 614*cdf0e10cSrcweir } 615*cdf0e10cSrcweir return BytesRead; 616*cdf0e10cSrcweir } 617*cdf0e10cSrcweir 618*cdf0e10cSrcweir 619*cdf0e10cSrcweir /*****************************************************************************/ 620*cdf0e10cSrcweir /* osl_getLastPipeError */ 621*cdf0e10cSrcweir /*****************************************************************************/ 622*cdf0e10cSrcweir oslPipeError SAL_CALL osl_getLastPipeError(oslPipe pPipe) 623*cdf0e10cSrcweir { 624*cdf0e10cSrcweir oslPipeError Error; 625*cdf0e10cSrcweir 626*cdf0e10cSrcweir if (pPipe != NULL) 627*cdf0e10cSrcweir { 628*cdf0e10cSrcweir Error = pPipe->m_Error; 629*cdf0e10cSrcweir pPipe->m_Error = osl_Pipe_E_None; 630*cdf0e10cSrcweir } 631*cdf0e10cSrcweir else 632*cdf0e10cSrcweir Error = osl_Pipe_E_NotFound; 633*cdf0e10cSrcweir 634*cdf0e10cSrcweir return (Error); 635*cdf0e10cSrcweir } 636*cdf0e10cSrcweir 637