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