xref: /aoo41x/main/sal/osl/w32/pipe.c (revision 647f063d)
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