xref: /AOO41X/main/sal/osl/w32/process.cxx (revision 1ad19ac01b79d3e328cca88bbc0715af3693e14f)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #define UNICODE
25 #include "system.h"
26 #ifdef _MSC_VER
27 #pragma warning(push,1) /* disable warnings within system headers */
28 #endif
29 #include <shellapi.h>
30 #ifdef _MSC_VER
31 #pragma warning(pop)
32 #endif
33 
34 #include <osl/diagnose.h>
35 #include <osl/security.h>
36 #include <osl/nlsupport.h>
37 #include <osl/mutex.h>
38 #include <osl/thread.h>
39 
40 #include "procimpl.h"
41 #include "sockimpl.h"
42 #include "file_url.h"
43 #include "path_helper.hxx"
44 #include <rtl/ustrbuf.h>
45 #include <rtl/alloc.h>
46 
47 /***************************************************************************
48  * Process.
49  ***************************************************************************/
50 
osl_terminateProcess(oslProcess Process)51 oslProcessError SAL_CALL osl_terminateProcess(oslProcess Process)
52 {
53     if (Process == NULL)
54         return osl_Process_E_Unknown;
55 
56     if (TerminateProcess(((oslProcessImpl*)Process)->m_hProcess, 0))
57         return osl_Process_E_None;
58 
59 
60     return osl_Process_E_Unknown;
61 }
62 
63 /***************************************************************************/
64 
osl_getProcess(oslProcessIdentifier Ident)65 oslProcess SAL_CALL osl_getProcess(oslProcessIdentifier Ident)
66 {
67     oslProcessImpl* pProcImpl;
68     HANDLE hProcess = OpenProcess(
69         STANDARD_RIGHTS_REQUIRED | PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE, (DWORD)Ident);
70 
71     if (hProcess)
72     {
73         pProcImpl = reinterpret_cast< oslProcessImpl*>( rtl_allocateMemory(sizeof(oslProcessImpl)) );
74         pProcImpl->m_hProcess  = hProcess;
75         pProcImpl->m_IdProcess = Ident;
76     }
77     else
78         pProcImpl = NULL;
79 
80     return (pProcImpl);
81 }
82 
83 /***************************************************************************/
84 
osl_freeProcessHandle(oslProcess Process)85 void SAL_CALL osl_freeProcessHandle(oslProcess Process)
86 {
87     if (Process != NULL)
88     {
89         CloseHandle(((oslProcessImpl*)Process)->m_hProcess);
90 
91         rtl_freeMemory((oslProcessImpl*)Process);
92     }
93 }
94 
95 /***************************************************************************/
96 
osl_getProcessInfo(oslProcess Process,oslProcessData Fields,oslProcessInfo * pInfo)97 oslProcessError SAL_CALL osl_getProcessInfo(oslProcess Process, oslProcessData Fields,
98                                    oslProcessInfo* pInfo)
99 {
100     HANDLE hProcess;
101     DWORD  IdProcess;
102 
103     if (Process == NULL)
104     {
105         hProcess  = GetCurrentProcess();
106         IdProcess = GetCurrentProcessId();
107     }
108     else
109     {
110         hProcess  = ((oslProcessImpl*)Process)->m_hProcess;
111         IdProcess = ((oslProcessImpl*)Process)->m_IdProcess;
112     }
113 
114     if (! pInfo || (pInfo->Size != sizeof(oslProcessInfo)))
115         return osl_Process_E_Unknown;
116 
117     pInfo->Fields = 0;
118 
119     if (Fields & osl_Process_IDENTIFIER)
120     {
121         pInfo->Ident  = IdProcess;
122         pInfo->Fields |= osl_Process_IDENTIFIER;
123     }
124 
125     if (Fields & osl_Process_EXITCODE)
126     {
127         if (GetExitCodeProcess(hProcess, &(pInfo->Code)) && (pInfo->Code != STILL_ACTIVE))
128             pInfo->Fields |= osl_Process_EXITCODE;
129     }
130 
131     if (Fields & osl_Process_HEAPUSAGE)
132     {
133         void*   lpAddress=0;
134         MEMORY_BASIC_INFORMATION Info;
135 
136         pInfo->HeapUsage = 0;
137 
138         do
139         {
140             if (VirtualQueryEx(hProcess, lpAddress, &Info, sizeof(Info)) == 0)
141                 break;
142 
143             if ((Info.State == MEM_COMMIT) && (Info.Type == MEM_PRIVATE))
144                 pInfo->HeapUsage += Info.RegionSize;
145 
146             lpAddress = (LPBYTE)lpAddress + Info.RegionSize;
147         }
148         while (lpAddress < (void *)0x80000000); // 2GB address space
149 
150         pInfo->Fields |= osl_Process_HEAPUSAGE;
151     }
152 
153     if (Fields & osl_Process_CPUTIMES)
154     {
155         FILETIME CreationTime, ExitTime, KernelTime, UserTime;
156 
157         if (GetProcessTimes(hProcess, &CreationTime, &ExitTime,
158                                       &KernelTime, &UserTime))
159         {
160             __int64 Value;
161 
162             Value = *((__int64 *)&UserTime);
163             pInfo->UserTime.Seconds   = (unsigned long) (Value / 10000000L);
164             pInfo->UserTime.Nanosec   = (unsigned long)((Value % 10000000L) * 100);
165 
166             Value = *((__int64 *)&KernelTime);
167             pInfo->SystemTime.Seconds = (unsigned long) (Value / 10000000L);
168             pInfo->SystemTime.Nanosec = (unsigned long)((Value % 10000000L) * 100);
169 
170             pInfo->Fields |= osl_Process_CPUTIMES;
171         }
172     }
173 
174     return (pInfo->Fields == Fields) ? osl_Process_E_None : osl_Process_E_Unknown;
175 }
176 
177 /***************************************************************************/
178 
osl_joinProcess(oslProcess Process)179 oslProcessError SAL_CALL osl_joinProcess(oslProcess Process)
180 {
181     return osl_joinProcessWithTimeout(Process, NULL);
182 }
183 
184 /***************************************************************************/
185 
osl_joinProcessWithTimeout(oslProcess Process,const TimeValue * pTimeout)186 oslProcessError SAL_CALL osl_joinProcessWithTimeout(oslProcess Process, const TimeValue* pTimeout)
187 {
188     DWORD           timeout   = INFINITE;
189     oslProcessError osl_error = osl_Process_E_None;
190     DWORD           ret;
191 
192     if (NULL == Process)
193         return osl_Process_E_Unknown;
194 
195     if (pTimeout)
196         timeout = pTimeout->Seconds * 1000 + pTimeout->Nanosec / 1000000L;
197 
198     ret = WaitForSingleObject(((oslProcessImpl*)Process)->m_hProcess, timeout);
199 
200     if (WAIT_FAILED == ret)
201         osl_error = osl_Process_E_Unknown;
202     else if (WAIT_TIMEOUT == ret)
203         osl_error = osl_Process_E_TimedOut;
204 
205     return osl_error;
206 }
207 
208 /***************************************************************************
209  * osl_bootstrap_getExecutableFile_Impl().
210  *
211  * @internal
212  * @see rtl_bootstrap
213  * @see #i37371#
214  *
215  ***************************************************************************/
216 
osl_bootstrap_getExecutableFile_Impl(rtl_uString ** ppFileURL)217 extern "C" oslProcessError SAL_CALL osl_bootstrap_getExecutableFile_Impl (
218     rtl_uString ** ppFileURL
219 ) SAL_THROW_EXTERN_C()
220 {
221     oslProcessError result = osl_Process_E_NotFound;
222 
223     ::osl::LongPathBuffer< sal_Unicode > aBuffer( MAX_LONG_PATH );
224     DWORD buflen = 0;
225 
226     if ((buflen = GetModuleFileNameW (0, ::osl::mingw_reinterpret_cast<LPWSTR>(aBuffer), aBuffer.getBufSizeInSymbols())) > 0)
227     {
228         rtl_uString * pAbsPath = 0;
229         rtl_uString_newFromStr_WithLength (&(pAbsPath), aBuffer, buflen);
230         if (pAbsPath)
231         {
232             /* Convert from path to url. */
233             if (osl_getFileURLFromSystemPath (pAbsPath, ppFileURL) == osl_File_E_None)
234             {
235                 /* Success. */
236                 result = osl_Process_E_None;
237             }
238             rtl_uString_release (pAbsPath);
239         }
240     }
241 
242     return (result);
243 }
244 
245 /***************************************************************************
246  * Command Line Arguments.
247  ***************************************************************************/
248 
249 struct CommandArgs_Impl
250 {
251     sal_uInt32     m_nCount;
252     rtl_uString ** m_ppArgs;
253 };
254 
255 static struct CommandArgs_Impl g_command_args =
256 {
257     0,
258     0
259 };
260 
261 #ifdef _MSC_VER
262 #pragma warning( push )
263 #pragma warning( disable: 4100 )
264 #endif
osl_createCommandArgs_Impl(int argc,char ** argv)265 static rtl_uString ** osl_createCommandArgs_Impl (int argc, char ** argv)
266 {
267     rtl_uString ** ppArgs =
268         (rtl_uString**)rtl_allocateZeroMemory (argc * sizeof(rtl_uString*));
269     if (ppArgs != 0)
270     {
271         int i;
272         int nArgs;
273         LPWSTR *wargv = CommandLineToArgvW( GetCommandLineW(), &nArgs );
274         OSL_ASSERT( nArgs == argc );
275         for (i = 0; i < nArgs; i++)
276         {
277             /* Convert to unicode */
278             rtl_uString_newFromStr( &(ppArgs[i]), reinterpret_cast<const sal_Unicode*>(wargv[i]) );
279         }
280         if (ppArgs[0] != 0)
281         {
282             /* Ensure absolute path */
283             ::osl::LongPathBuffer< sal_Unicode > aBuffer( MAX_LONG_PATH );
284             DWORD dwResult = 0;
285 
286             dwResult = SearchPath (
287                 0, reinterpret_cast<LPCWSTR>(ppArgs[0]->buffer), L".exe", aBuffer.getBufSizeInSymbols(), ::osl::mingw_reinterpret_cast<LPWSTR>(aBuffer), 0);
288             if ((0 < dwResult) && (dwResult < aBuffer.getBufSizeInSymbols()))
289             {
290                 /* Replace argv[0] with it's absolute path */
291                 rtl_uString_newFromStr_WithLength(
292                     &(ppArgs[0]), aBuffer, dwResult);
293             }
294         }
295         if (ppArgs[0] != 0)
296         {
297             /* Convert to FileURL, see @ osl_getExecutableFile() */
298             rtl_uString * pResult = 0;
299             osl_getFileURLFromSystemPath (ppArgs[0], &pResult);
300             if (pResult != 0)
301             {
302                 rtl_uString_assign (&(ppArgs[0]), pResult);
303                 rtl_uString_release (pResult);
304             }
305         }
306     }
307     return (ppArgs);
308 
309 }
310 #ifdef _MSC_VER
311 #pragma warning( pop )
312 #endif
313 
314 /***************************************************************************/
315 
osl_getExecutableFile(rtl_uString ** ppustrFile)316 oslProcessError SAL_CALL osl_getExecutableFile( rtl_uString **ppustrFile )
317 {
318     oslProcessError result = osl_Process_E_NotFound;
319 
320     osl_acquireMutex (*osl_getGlobalMutex());
321     OSL_ASSERT(g_command_args.m_nCount > 0);
322     if (g_command_args.m_nCount > 0)
323     {
324         /* CommandArgs set. Obtain arv[0]. */
325         rtl_uString_assign (ppustrFile, g_command_args.m_ppArgs[0]);
326         result = osl_Process_E_None;
327     }
328     osl_releaseMutex (*osl_getGlobalMutex());
329 
330     return (result);
331 }
332 
333 /***************************************************************************/
334 
osl_getCommandArgCount(void)335 sal_uInt32 SAL_CALL osl_getCommandArgCount(void)
336 {
337     sal_uInt32 result = 0;
338 
339     osl_acquireMutex (*osl_getGlobalMutex());
340     OSL_ASSERT(g_command_args.m_nCount > 0);
341     if (g_command_args.m_nCount > 0)
342     {
343         /* We're not counting argv[0] here. */
344         result = g_command_args.m_nCount - 1;
345     }
346     osl_releaseMutex (*osl_getGlobalMutex());
347 
348     return (result);
349 }
350 
351 /***************************************************************************/
352 
osl_getCommandArg(sal_uInt32 nArg,rtl_uString ** strCommandArg)353 oslProcessError SAL_CALL osl_getCommandArg( sal_uInt32 nArg, rtl_uString **strCommandArg)
354 {
355     oslProcessError result = osl_Process_E_NotFound;
356 
357     osl_acquireMutex (*osl_getGlobalMutex());
358     OSL_ASSERT(g_command_args.m_nCount > 0);
359     if (g_command_args.m_nCount > (nArg + 1))
360     {
361         /* We're not counting argv[0] here. */
362         rtl_uString_assign (strCommandArg, g_command_args.m_ppArgs[nArg + 1]);
363         result = osl_Process_E_None;
364     }
365     osl_releaseMutex (*osl_getGlobalMutex());
366 
367     return (result);
368 }
369 
370 /***************************************************************************/
371 
osl_setCommandArgs(int argc,char ** argv)372 void SAL_CALL osl_setCommandArgs (int argc, char ** argv)
373 {
374     OSL_ASSERT(argc > 0);
375     osl_acquireMutex (*osl_getGlobalMutex());
376     if (g_command_args.m_nCount == 0)
377     {
378         rtl_uString** ppArgs = osl_createCommandArgs_Impl (argc, argv);
379         if (ppArgs != 0)
380         {
381             g_command_args.m_nCount = argc;
382             g_command_args.m_ppArgs = ppArgs;
383         }
384     }
385     osl_releaseMutex (*osl_getGlobalMutex());
386 }
387 
388 /***************************************************************************
389  * Environment
390  ***************************************************************************/
391 #define ENV_BUFFER_SIZE (32*1024-1)
392 
osl_getEnvironment(rtl_uString * ustrVar,rtl_uString ** ustrValue)393 oslProcessError SAL_CALL osl_getEnvironment(rtl_uString *ustrVar, rtl_uString **ustrValue)
394 {
395     WCHAR buff[ENV_BUFFER_SIZE];
396 
397     if (GetEnvironmentVariableW(reinterpret_cast<LPCWSTR>(ustrVar->buffer), buff, ENV_BUFFER_SIZE) > 0)
398     {
399         rtl_uString_newFromStr(ustrValue, reinterpret_cast<const sal_Unicode*>(buff));
400         return osl_Process_E_None;
401     }
402     return osl_Process_E_Unknown;
403 }
404 
osl_setEnvironment(rtl_uString * ustrVar,rtl_uString * ustrValue)405 oslProcessError SAL_CALL osl_setEnvironment(rtl_uString *ustrVar, rtl_uString *ustrValue)
406 {
407     // set Windows environment variable
408     LPCWSTR lpName = reinterpret_cast<LPCWSTR>(ustrVar->buffer);
409     LPCWSTR lpValue = reinterpret_cast<LPCWSTR>(ustrValue->buffer);
410     if( !SetEnvironmentVariableW( lpName, lpValue))
411         return osl_Process_E_Unknown;
412 
413     // also set the variable in the crt environment
414     _wputenv_s( lpName, lpValue);
415     return osl_Process_E_None;
416 }
417 
osl_clearEnvironment(rtl_uString * ustrVar)418 oslProcessError SAL_CALL osl_clearEnvironment(rtl_uString *ustrVar)
419 {
420     // delete the variable from the current process environment
421     // by setting SetEnvironmentVariable's second parameter to NULL
422     LPCWSTR lpName = reinterpret_cast<LPCWSTR>(ustrVar->buffer);
423     if( !SetEnvironmentVariableW( lpName, NULL))
424         return osl_Process_E_Unknown;
425 
426     // also remove the variable from the crt environment
427     wchar_t aEmptyName = 0;
428     _wputenv_s( lpName, &aEmptyName);
429     return osl_Process_E_None;
430 }
431 
432 /***************************************************************************
433  * Current Working Directory.
434  ***************************************************************************/
435 
436 extern "C" oslMutex g_CurrentDirectoryMutex;
437 
osl_getProcessWorkingDir(rtl_uString ** pustrWorkingDir)438 oslProcessError SAL_CALL osl_getProcessWorkingDir( rtl_uString **pustrWorkingDir )
439 {
440     ::osl::LongPathBuffer< sal_Unicode > aBuffer( MAX_LONG_PATH );
441     DWORD   dwLen = 0;
442 
443 
444     osl_acquireMutex( g_CurrentDirectoryMutex );
445     dwLen = GetCurrentDirectory( aBuffer.getBufSizeInSymbols(), ::osl::mingw_reinterpret_cast<LPWSTR>(aBuffer) );
446     osl_releaseMutex( g_CurrentDirectoryMutex );
447 
448     if ( dwLen && dwLen < aBuffer.getBufSizeInSymbols() )
449     {
450         oslFileError    eError;
451         rtl_uString     *ustrTemp = NULL;;
452 
453         rtl_uString_newFromStr_WithLength( &ustrTemp, aBuffer, dwLen );
454         eError = osl_getFileURLFromSystemPath( ustrTemp, pustrWorkingDir );
455 
456         rtl_uString_release( ustrTemp );
457 
458         if ( osl_File_E_None != eError )
459             return osl_Process_E_Unknown;
460         else
461             return osl_Process_E_None;
462     }
463     else
464         return osl_Process_E_Unknown;
465 }
466 
467 /***************************************************************************
468  * Process Locale.
469  ***************************************************************************/
470 
471 extern "C" void _imp_getProcessLocale( rtl_Locale ** ppLocale );
472 
473 static rtl_Locale * g_theProcessLocale = NULL;
474 
475 /***************************************************************************/
476 
osl_getProcessLocale(rtl_Locale ** ppLocale)477 oslProcessError SAL_CALL osl_getProcessLocale( rtl_Locale ** ppLocale )
478 {
479     osl_acquireMutex( *osl_getGlobalMutex() );
480 
481     /* determine the users default locale */
482     if( NULL == g_theProcessLocale )
483         _imp_getProcessLocale( &g_theProcessLocale );
484 
485     /* or return the cached value */
486     *ppLocale = g_theProcessLocale;
487 
488     osl_releaseMutex( *osl_getGlobalMutex() );
489     return osl_Process_E_None;
490 }
491 
492 /***************************************************************************/
493 
osl_setProcessLocale(rtl_Locale * pLocale)494 oslProcessError SAL_CALL osl_setProcessLocale( rtl_Locale * pLocale )
495 {
496     osl_acquireMutex( *osl_getGlobalMutex() );
497 
498     /* check if locale is supported */
499     if( RTL_TEXTENCODING_DONTKNOW == osl_getTextEncodingFromLocale( pLocale ) )
500         return osl_Process_E_Unknown;
501 
502     /* just remember the locale here */
503     g_theProcessLocale = pLocale;
504 
505     osl_releaseMutex( *osl_getGlobalMutex() );
506     return osl_Process_E_None;
507 }
508 
509 /************************************************
510  * Portal send/receive interface implementation
511  ************************************************/
512 
ReadPipe(oslPipe hPipe,void * pBuffer,sal_Int32 BytesToRead,sal_Int32 * nBytes)513 static sal_Bool ReadPipe(oslPipe hPipe,
514                 void* pBuffer,
515                 sal_Int32 BytesToRead,
516                 sal_Int32* nBytes)
517 {
518         *nBytes = osl_receivePipe(hPipe, pBuffer, BytesToRead);
519         OSL_TRACE("tried to recieve %d, recieved %d.\n",
520                         BytesToRead, *nBytes);
521         return (sal_Bool)((*nBytes >= 0) && (osl_getLastPipeError(hPipe) == osl_Pipe_E_None));
522 }
523 
WritePipe(oslPipe hPipe,void * pBuffer,sal_Int32 BytesToSend,sal_Int32 * nBytes)524 static sal_Bool WritePipe(oslPipe hPipe,
525                 void* pBuffer,
526                 sal_Int32 BytesToSend,
527                 sal_Int32* nBytes)
528 {
529         *nBytes = osl_sendPipe(hPipe, pBuffer, BytesToSend);
530         OSL_TRACE("tried to send %d, sent %d\n",
531                         BytesToSend, *nBytes);
532         return (sal_Bool)((*nBytes == BytesToSend) && (osl_getLastPipeError(hPipe) == osl_Pipe_E_None));
533 }
534 
osl_sendResourcePipe(oslPipe hPipe,oslSocket pSocket)535 sal_Bool SAL_CALL osl_sendResourcePipe(oslPipe hPipe, oslSocket pSocket)
536 {
537     sal_Bool bRet = sal_False;
538     sal_Int32 bytes = 0;
539 
540     /*  duplicate handle on this other side ->
541         receive remote process
542         duplicate handle and send it */
543     DWORD remoteProcessID = 0;
544     HANDLE fd = (HANDLE)pSocket->m_Socket;
545     oslDescriptorType code = osl_Process_TypeSocket;
546 
547     OSL_TRACE("osl_sendResourcePipe: enter...");
548 
549     if (ReadPipe(hPipe, &remoteProcessID, sizeof(remoteProcessID), &bytes))
550     {
551         HANDLE hRemoteProc = OpenProcess(PROCESS_DUP_HANDLE,
552                                          FALSE,
553                                          remoteProcessID);
554 
555         if (hRemoteProc != (HANDLE)NULL)
556         {
557             HANDLE newFd;
558 
559             if (DuplicateHandle(GetCurrentProcess(),
560                                 fd,
561                                 hRemoteProc,
562                                 &newFd,
563                                 0, FALSE, DUPLICATE_SAME_ACCESS))
564             {
565                 if (
566                     WritePipe(hPipe, &code, sizeof(code), &bytes) &&
567                     WritePipe(hPipe, &newFd, sizeof(fd), &bytes)
568                     )
569                     bRet = sal_True;
570             }
571 
572             CloseHandle(hRemoteProc);
573         }
574     }
575 
576     if (bRet)
577     {
578         sal_Int32 commitCode;
579         OSL_TRACE("osl_sendResourcePipe: handle sent successfully, verify...\n");
580 
581         if (
582             !ReadPipe(hPipe, &commitCode, sizeof(commitCode), &bytes) ||
583             (commitCode <= 0)
584             )
585             bRet = sal_False;
586     }
587 
588     OSL_TRACE("osl_sendResourcePipe: exit... %d\n", bRet);
589     return(bRet);
590 }
591 
592 
osl_receiveResourcePipe(oslPipe hPipe)593 oslSocket SAL_CALL osl_receiveResourcePipe(oslPipe hPipe)
594 {
595     sal_Bool bRet = sal_False;
596     sal_Int32 bytes = 0;
597     sal_Int32 commitCode;
598     oslSocket pSocket = NULL;
599 
600     /* duplicate handle on the other side ->
601        send my process id receive duplicated handle */
602     HANDLE fd = INVALID_HANDLE_VALUE;
603     DWORD myProcessID = GetCurrentProcessId();
604     oslDescriptorType code = osl_Process_TypeNone;
605 
606     OSL_TRACE("osl_receiveResourcePipe: enter...\n");
607 
608     if (
609         WritePipe(hPipe, &myProcessID, sizeof(myProcessID), &bytes) &&
610         ReadPipe(hPipe, &code, sizeof(code), &bytes) &&
611                 ReadPipe(hPipe, &fd, sizeof(fd), &bytes)
612         )
613     {
614         if (code == osl_Process_TypeSocket)
615         {
616             pSocket = __osl_createSocketImpl((SOCKET)fd);
617             bRet = sal_True;
618         }
619         else
620         {
621             OSL_TRACE("osl_receiveResourcePipe: UKNOWN\n");
622             bRet = sal_False;
623         }
624         }
625 
626     if (bRet)
627         commitCode = 1;
628     else
629         commitCode = 0;
630 
631     WritePipe(hPipe, &commitCode, sizeof(commitCode), &bytes);
632 
633     OSL_TRACE("osl_receiveResourcePipe: exit... %d, %p\n", bRet, pSocket);
634 
635     return pSocket;
636 }
637