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
10*647f063dSAndrew Rist *
11*647f063dSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*647f063dSAndrew Rist *
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.
19*647f063dSAndrew Rist *
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