VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/win/localipc-win.cpp@ 35018

Last change on this file since 35018 was 33540, checked in by vboxsync, 14 years ago

*: spelling fixes, thanks Timeless!

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.8 KB
Line 
1/* $Id: localipc-win.cpp 33540 2010-10-28 09:27:05Z vboxsync $ */
2/** @file
3 * IPRT - Local IPC, Windows Implementation Using Named Pipes.
4 */
5
6/*
7 * Copyright (C) 2008 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27/*******************************************************************************
28* Header Files *
29*******************************************************************************/
30/*
31 * We have to force NT 5.0 here because of
32 * ConvertStringSecurityDescriptorToSecurityDescriptor. Note that because of
33 * FILE_FLAG_FIRST_PIPE_INSTANCE this code actually requires W2K SP2+.
34 */
35#ifndef _WIN32_WINNT
36# define _WIN32_WINNT 0x0500 /* for ConvertStringSecurityDescriptorToSecurityDescriptor */
37#elif _WIN32_WINNT < 0x0500
38# undef _WIN32_WINNT
39# define _WIN32_WINNT 0x0500
40#endif
41#include <Windows.h>
42#include <sddl.h>
43
44#include <iprt/localipc.h>
45#include <iprt/thread.h>
46#include <iprt/critsect.h>
47#include <iprt/alloc.h>
48#include <iprt/assert.h>
49#include <iprt/param.h>
50#include <iprt/err.h>
51#include <iprt/string.h>
52#include <iprt/asm.h>
53
54#include "internal/magics.h"
55
56
57/*******************************************************************************
58* Defined Constants And Macros *
59*******************************************************************************/
60/** Pipe prefix string. */
61#define RTLOCALIPC_WIN_PREFIX "\\\\.\\pipe\\IPRT-"
62
63/** DACL for block all network access and local users other than the creator/owner.
64 *
65 * ACE format: (ace_type;ace_flags;rights;object_guid;inherit_object_guid;account_sid)
66 *
67 * Note! FILE_GENERIC_WRITE (SDDL_FILE_WRITE) is evil here because it includes
68 * the FILE_CREATE_PIPE_INSTANCE(=FILE_APPEND_DATA) flag. Thus the hardcoded
69 * value 0x0012019b in the 2nd ACE. It expands to:
70 * 0x00000001 - FILE_READ_DATA
71 * 0x00000008 - FILE_READ_EA
72 * 0x00000080 - FILE_READ_ATTRIBUTES
73 * 0x00020000 - READ_CONTROL
74 * 0x00100000 - SYNCHRONIZE
75 * 0x00000002 - FILE_WRITE_DATA
76 * 0x00000010 - FILE_WRITE_EA
77 * 0x00000100 - FILE_WRITE_ATTRIBUTES
78 * 0x0012019b
79 * or FILE_GENERIC_READ | (FILE_GENERIC_WRITE & ~FILE_CREATE_PIPE_INSTANCE)
80 *
81 * @todo Double check this!
82 * @todo Drop the EA rights too? Since they doesn't mean anything to PIPS according to the docs.
83 * @todo EVERYONE -> AUTHENTICATED USERS or something more appropriate?
84 * @todo Have trouble allowing the owner FILE_CREATE_PIPE_INSTANCE access, so for now I'm hacking
85 * it just to get progress - the service runs as local system.
86 * The CREATOR OWNER and PERSONAL SELF works (the former is only involved in inheriting
87 * it seems, which is why it won't work. The latter I've no idea about. Perhaps the solution
88 * is to go the annoying route of OpenProcessToken, QueryTokenInformation,
89 * ConvertSidToStringSid and then use the result... Suggestions are very welcome
90 */
91#define RTLOCALIPC_WIN_SDDL \
92 SDDL_DACL SDDL_DELIMINATOR \
93 SDDL_ACE_BEGIN SDDL_ACCESS_DENIED ";;" SDDL_GENERIC_ALL ";;;" SDDL_NETWORK SDDL_ACE_END \
94 SDDL_ACE_BEGIN SDDL_ACCESS_ALLOWED ";;" "0x0012019b" ";;;" SDDL_EVERYONE SDDL_ACE_END \
95 SDDL_ACE_BEGIN SDDL_ACCESS_ALLOWED ";;" SDDL_FILE_ALL ";;;" SDDL_LOCAL_SYSTEM SDDL_ACE_END
96
97// SDDL_ACE_BEGIN SDDL_ACCESS_ALLOWED ";;" SDDL_GENERIC_ALL ";;;" SDDL_PERSONAL_SELF SDDL_ACE_END \
98// SDDL_ACE_BEGIN SDDL_ACCESS_ALLOWED ";CIOI;" SDDL_GENERIC_ALL ";;;" SDDL_CREATOR_OWNER SDDL_ACE_END
99// SDDL_ACE_BEGIN SDDL_ACCESS_ALLOWED ";;" "0x0012019b" ";;;" SDDL_EVERYONE SDDL_ACE_END
100// SDDL_ACE_BEGIN SDDL_ACCESS_ALLOWED ";;" SDDL_FILE_ALL ";;;" SDDL_LOCAL_SYSTEM SDDL_ACE_END
101
102
103/*******************************************************************************
104* Structures and Typedefs *
105*******************************************************************************/
106/**
107 * Local IPC service instance, Windows.
108 */
109typedef struct RTLOCALIPCSERVERINT
110{
111 /** The magic (RTLOCALIPCSERVER_MAGIC). */
112 uint32_t u32Magic;
113 /** The creation flags. */
114 uint32_t fFlags;
115 /** Critical section protecting the structure. */
116 RTCRITSECT CritSect;
117 /** The number of references to the instance.
118 * @remarks The reference counting isn't race proof. */
119 uint32_t volatile cRefs;
120 /** Indicates that there is a pending cancel request. */
121 bool volatile fCancelled;
122 /** The name pipe handle. */
123 HANDLE hNmPipe;
124 /** The handle to the event object we're using for overlapped I/O. */
125 HANDLE hEvent;
126 /** The overlapped I/O structure. */
127 OVERLAPPED OverlappedIO;
128 /** The pipe name. */
129 char szName[1];
130} RTLOCALIPCSERVERINT;
131/** Pointer to a local IPC server instance (Windows). */
132typedef RTLOCALIPCSERVERINT *PRTLOCALIPCSERVERINT;
133
134
135/**
136 * Local IPC session instance, Windows.
137 */
138typedef struct RTLOCALIPCSESSIONINT
139{
140 /** The magic (RTLOCALIPCSESSION_MAGIC). */
141 uint32_t u32Magic;
142 /** Critical section protecting the structure. */
143 RTCRITSECT CritSect;
144 /** The number of references to the instance.
145 * @remarks The reference counting isn't race proof. */
146 uint32_t volatile cRefs;
147 /** Indicates that there is a pending cancel request. */
148 bool volatile fCancelled;
149 /** The name pipe handle. */
150 HANDLE hNmPipe;
151 /** The handle to the event object we're using for overlapped I/O. */
152 HANDLE hEvent;
153 /** The overlapped I/O structure. */
154 OVERLAPPED OverlappedIO;
155} RTLOCALIPCSESSIONINT;
156/** Pointer to a local IPC session instance (Windows). */
157typedef RTLOCALIPCSESSIONINT *PRTLOCALIPCSESSIONINT;
158
159
160/*******************************************************************************
161* Internal Functions *
162*******************************************************************************/
163static int rtLocalIpcWinCreateSession(PRTLOCALIPCSESSION phClientSession, HANDLE hNmPipeSession);
164
165
166/**
167 * Creates a named pipe instance.
168 *
169 * This is used by both RTLocalIpcServerCreate and RTLocalIpcServerListen.
170 *
171 * @returns Windows error code, that is NO_ERROR and *phNmPipe on success and some ERROR_* on failure.
172 *
173 * @param phNmPipe Where to store the named pipe handle on success. This
174 * will be set to INVALID_HANDLE_VALUE on failure.
175 * @param pszFullPipeName The full named pipe name.
176 * @param fFirst Set on the first call (from RTLocalIpcServerCreate), otherwise clear.
177 * Governs the FILE_FLAG_FIRST_PIPE_INSTANCE flag.
178 */
179static DWORD rtLocalIpcServerWinCreatePipeInstance(PHANDLE phNmPipe, const char *pszFullPipeName, bool fFirst)
180{
181 *phNmPipe = INVALID_HANDLE_VALUE;
182
183 /*
184 * We'll create a security descriptor from a SDDL that denies
185 * access to network clients (this is local IPC after all), it
186 * makes some further restrictions to prevent non-authenticated
187 * users from screwing around.
188 */
189 DWORD err;
190 PSECURITY_DESCRIPTOR pSecDesc = NULL;
191#if 0 /** @todo dynamically resolve this as it is the only thing that prevents
192 * loading IPRT on NT4. */
193 if (ConvertStringSecurityDescriptorToSecurityDescriptor(RTLOCALIPC_WIN_SDDL,
194 SDDL_REVISION_1,
195 &pSecDesc,
196 NULL))
197#else
198 AssertFatalFailed();
199 SetLastError(-1);
200 if (0)
201#endif
202 {
203 SECURITY_ATTRIBUTES SecAttrs;
204 SecAttrs.nLength = sizeof(SecAttrs);
205 SecAttrs.lpSecurityDescriptor = pSecDesc;
206 SecAttrs.bInheritHandle = FALSE;
207
208 DWORD fOpenMode = PIPE_ACCESS_DUPLEX
209 | PIPE_WAIT
210 | FILE_FLAG_OVERLAPPED;
211 if (fFirst)
212 fOpenMode |= FILE_FLAG_FIRST_PIPE_INSTANCE; /* Note! Requires W2K SP2+. */
213
214 HANDLE hNmPipe = CreateNamedPipe(pszFullPipeName, /* lpName */
215 fOpenMode, /* dwOpenMode */
216 PIPE_TYPE_BYTE, /* dwPipeMode */
217 PIPE_UNLIMITED_INSTANCES, /* nMaxInstances */
218 PAGE_SIZE, /* nOutBufferSize (advisory) */
219 PAGE_SIZE, /* nInBufferSize (ditto) */
220 30*1000, /* nDefaultTimeOut = 30 sec */
221 &SecAttrs); /* lpSecurityAttributes */
222 err = GetLastError();
223 LocalFree(pSecDesc);
224 if (hNmPipe != INVALID_HANDLE_VALUE)
225 {
226 *phNmPipe = hNmPipe;
227 return NO_ERROR;
228 }
229 }
230 else
231 err = GetLastError();
232
233 AssertReturn(err != NO_ERROR, ERROR_GEN_FAILURE);
234 return err;
235}
236
237
238RTDECL(int) RTLocalIpcServerCreate(PRTLOCALIPCSERVER phServer, const char *pszName, uint32_t fFlags)
239{
240 /*
241 * Basic parameter validation.
242 */
243 AssertPtrReturn(phServer, VERR_INVALID_POINTER);
244 AssertPtrReturn(pszName, VERR_INVALID_POINTER);
245 AssertReturn(*pszName, VERR_INVALID_PARAMETER);
246 AssertReturn(!(fFlags & ~(RTLOCALIPC_FLAGS_VALID_MASK)), VERR_INVALID_PARAMETER);
247
248 AssertReturn(fFlags & RTLOCALIPC_FLAGS_MULTI_SESSION, VERR_NOT_IMPLEMENTED); /** @todo implement !RTLOCALIPC_FLAGS_MULTI_SESSION */
249
250 /*
251 * Allocate and initialize the instance data.
252 */
253 size_t cchName = strlen(pszName);
254 size_t cch = RT_OFFSETOF(RTLOCALIPCSERVERINT, szName[cchName + sizeof(RTLOCALIPC_WIN_PREFIX)]);
255 PRTLOCALIPCSERVERINT pThis = (PRTLOCALIPCSERVERINT)RTMemAlloc(cch);
256 if (!pThis)
257 return VERR_NO_MEMORY;
258 pThis->u32Magic = RTLOCALIPCSERVER_MAGIC;
259 pThis->cRefs = 1; /* the one we return */
260 pThis->fCancelled = false;
261 memcpy(pThis->szName, RTLOCALIPC_WIN_PREFIX, sizeof(RTLOCALIPC_WIN_PREFIX) - 1);
262 memcpy(&pThis->szName[sizeof(RTLOCALIPC_WIN_PREFIX) - 1], pszName, cchName + 1);
263 int rc = RTCritSectInit(&pThis->CritSect);
264 if (RT_SUCCESS(rc))
265 {
266 DWORD err = NO_ERROR;
267 pThis->hEvent = CreateEvent(NULL /*lpEventAttributes*/, TRUE /*bManualReset*/, FALSE /*bInitialState*/, NULL /*lpName*/);
268 if (pThis->hEvent != NULL)
269 {
270 memset(&pThis->OverlappedIO, 0, sizeof(pThis->OverlappedIO));
271 pThis->OverlappedIO.Internal = STATUS_PENDING;
272 pThis->OverlappedIO.hEvent = pThis->hEvent;
273
274 err = rtLocalIpcServerWinCreatePipeInstance(&pThis->hNmPipe, pThis->szName, true /* fFirst */);
275 if (err == NO_ERROR)
276 {
277 *phServer = pThis;
278 return VINF_SUCCESS;
279 }
280 }
281 else
282 err = GetLastError();
283 rc = RTErrConvertFromWin32(err);
284 }
285 RTMemFree(pThis);
286 return rc;
287}
288
289
290/**
291 * Call when the reference count reaches 0.
292 * Caller owns the critsect.
293 * @param pThis The instance to destroy.
294 */
295static void rtLocalIpcServerWinDestroy(PRTLOCALIPCSERVERINT pThis)
296{
297 BOOL fRc = CloseHandle(pThis->hNmPipe);
298 AssertMsg(fRc, ("%d\n", GetLastError())); NOREF(fRc);
299 pThis->hNmPipe = INVALID_HANDLE_VALUE;
300
301 fRc = CloseHandle(pThis->hEvent);
302 AssertMsg(fRc, ("%d\n", GetLastError())); NOREF(fRc);
303 pThis->hEvent = NULL;
304
305 RTCritSectLeave(&pThis->CritSect);
306 RTCritSectDelete(&pThis->CritSect);
307
308 RTMemFree(pThis);
309}
310
311
312RTDECL(int) RTLocalIpcServerDestroy(RTLOCALIPCSERVER hServer)
313{
314 /*
315 * Validate input.
316 */
317 if (hServer == NIL_RTLOCALIPCSERVER)
318 return VINF_SUCCESS;
319 PRTLOCALIPCSERVERINT pThis = (PRTLOCALIPCSERVERINT)hServer;
320 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
321 AssertReturn(pThis->u32Magic == RTLOCALIPCSERVER_MAGIC, VERR_INVALID_MAGIC);
322
323 /*
324 * Cancel any thread currently busy using the server,
325 * leaving the cleanup to it.
326 */
327 RTCritSectEnter(&pThis->CritSect);
328 ASMAtomicUoWriteU32(&pThis->u32Magic, ~RTLOCALIPCSERVER_MAGIC);
329 ASMAtomicUoWriteBool(&pThis->fCancelled, true);
330 pThis->cRefs--;
331
332 if (pThis->cRefs > 0)
333 {
334 BOOL fRc = SetEvent(pThis->hEvent);
335 AssertMsg(fRc, ("%d\n", GetLastError())); NOREF(fRc);
336
337 RTCritSectLeave(&pThis->CritSect);
338 }
339 else
340 rtLocalIpcServerWinDestroy(pThis);
341
342 return VINF_SUCCESS;
343}
344
345
346RTDECL(int) RTLocalIpcServerListen(RTLOCALIPCSERVER hServer, PRTLOCALIPCSESSION phClientSession)
347{
348 /*
349 * Validate input.
350 */
351 PRTLOCALIPCSERVERINT pThis = (PRTLOCALIPCSERVERINT)hServer;
352 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
353 AssertReturn(pThis->u32Magic == RTLOCALIPCSERVER_MAGIC, VERR_INVALID_MAGIC);
354
355 /*
356 * Enter the critsect before inspecting the object further.
357 */
358 int rc;
359 RTCritSectEnter(&pThis->CritSect);
360 if (pThis->fCancelled)
361 {
362 pThis->fCancelled = false;
363 rc = VERR_CANCELLED;
364 RTCritSectLeave(&pThis->CritSect);
365 }
366 else
367 {
368 pThis->cRefs++;
369 ResetEvent(pThis->hEvent);
370 RTCritSectLeave(&pThis->CritSect);
371
372 /*
373 * Try connect a client. We need to use overlapped I/O here because
374 * of the cancellation a by RTLocalIpcServerCancel and RTLocalIpcServerDestroy.
375 */
376 SetLastError(NO_ERROR);
377 BOOL fRc = ConnectNamedPipe(pThis->hNmPipe, &pThis->OverlappedIO);
378 DWORD err = fRc ? NO_ERROR : GetLastError();
379 if ( !fRc
380 && err == ERROR_IO_PENDING)
381 {
382 WaitForSingleObject(pThis->hEvent, INFINITE);
383 DWORD dwIgnored;
384 fRc = GetOverlappedResult(pThis->hNmPipe, &pThis->OverlappedIO, &dwIgnored, FALSE /* bWait*/);
385 err = fRc ? NO_ERROR : GetLastError();
386 }
387
388 RTCritSectEnter(&pThis->CritSect);
389 if ( !pThis->fCancelled
390 && pThis->u32Magic == RTLOCALIPCSERVER_MAGIC)
391 {
392 /*
393 * Still alive, some error or an actual client.
394 *
395 * If it's the latter we'll have to create a new pipe instance that
396 * replaces the current one for the server. The current pipe instance
397 * will be assigned to the client session.
398 */
399 if ( fRc
400 || err == ERROR_PIPE_CONNECTED)
401 {
402 HANDLE hNmPipe;
403 DWORD err = rtLocalIpcServerWinCreatePipeInstance(&hNmPipe, pThis->szName, false /* fFirst */);
404 if (err == NO_ERROR)
405 {
406 HANDLE hNmPipeSession = pThis->hNmPipe; /* consumed */
407 pThis->hNmPipe = hNmPipe;
408 rc = rtLocalIpcWinCreateSession(phClientSession, hNmPipeSession);
409 }
410 else
411 {
412 /*
413 * We failed to create a new instance for the server, disconnect
414 * the client and fail. Don't try service the client here.
415 */
416 rc = RTErrConvertFromWin32(err);
417 fRc = DisconnectNamedPipe(pThis->hNmPipe);
418 AssertMsg(fRc, ("%d\n", GetLastError()));
419 }
420 }
421 else
422 rc = RTErrConvertFromWin32(err);
423 }
424 else
425 {
426 /*
427 * Cancelled or destroyed.
428 *
429 * Cancel the overlapped io if it didn't complete (must be done
430 * in the this thread) or disconnect the client.
431 */
432 if ( fRc
433 || err == ERROR_PIPE_CONNECTED)
434 fRc = DisconnectNamedPipe(pThis->hNmPipe);
435 else if (err == ERROR_IO_PENDING)
436 fRc = CancelIo(pThis->hNmPipe);
437 else
438 fRc = TRUE;
439 AssertMsg(fRc, ("%d\n", GetLastError()));
440 rc = VERR_CANCELLED;
441 }
442
443 pThis->cRefs--;
444 if (pThis->cRefs)
445 RTCritSectLeave(&pThis->CritSect);
446 else
447 rtLocalIpcServerWinDestroy(pThis);
448 }
449
450 return rc;
451}
452
453
454RTDECL(int) RTLocalIpcServerCancel(RTLOCALIPCSERVER hServer)
455{
456 /*
457 * Validate input.
458 */
459 PRTLOCALIPCSERVERINT pThis = (PRTLOCALIPCSERVERINT)hServer;
460 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
461 AssertReturn(pThis->u32Magic == RTLOCALIPCSERVER_MAGIC, VERR_INVALID_MAGIC);
462
463 /*
464 * Enter the critical section, then set the cancellation flag
465 * and signal the event (to wake up anyone in/at WaitForSingleObject).
466 */
467 RTCritSectEnter(&pThis->CritSect);
468
469 ASMAtomicUoWriteBool(&pThis->fCancelled, true);
470 BOOL fRc = SetEvent(pThis->hEvent);
471 AssertMsg(fRc, ("%d\n", GetLastError())); NOREF(fRc);
472
473 RTCritSectLeave(&pThis->CritSect);
474
475 return VINF_SUCCESS;
476}
477
478
479/**
480 * Create a session instance.
481 *
482 * @returns IPRT status code.
483 *
484 * @param phClientSession Where to store the session handle on success.
485 * @param hNmPipeSession The named pipe handle. This will be consumed by this session, meaning on failure
486 * to create the session it will be closed.
487 */
488static int rtLocalIpcWinCreateSession(PRTLOCALIPCSESSION phClientSession, HANDLE hNmPipeSession)
489{
490 int rc;
491
492 /*
493 * Allocate and initialize the session instance data.
494 */
495 PRTLOCALIPCSESSIONINT pThis = (PRTLOCALIPCSESSIONINT)RTMemAlloc(sizeof(*pThis));
496 if (pThis)
497 {
498 pThis->u32Magic = RTLOCALIPCSESSION_MAGIC;
499 pThis->cRefs = 1; /* our ref */
500 pThis->fCancelled = false;
501 pThis->hNmPipe = hNmPipeSession;
502
503 rc = RTCritSectInit(&pThis->CritSect);
504 if (RT_SUCCESS(rc))
505 {
506 pThis->hEvent = CreateEvent(NULL /*lpEventAttributes*/, TRUE /*bManualReset*/, FALSE /*bInitialState*/, NULL /*lpName*/);
507 if (pThis->hEvent != NULL)
508 {
509 memset(&pThis->OverlappedIO, 0, sizeof(pThis->OverlappedIO));
510 pThis->OverlappedIO.Internal = STATUS_PENDING;
511 pThis->OverlappedIO.hEvent = pThis->hEvent;
512
513 *phClientSession = pThis;
514 return VINF_SUCCESS;
515 }
516
517 /* bail out */
518 rc = RTErrConvertFromWin32(GetLastError());
519 RTCritSectDelete(&pThis->CritSect);
520 }
521 RTMemFree(pThis);
522 }
523 else
524 rc = VERR_NO_MEMORY;
525
526 BOOL fRc = CloseHandle(hNmPipeSession);
527 AssertMsg(fRc, ("%d\n", GetLastError())); NOREF(fRc);
528 return rc;
529}
530
531
532RTDECL(int) RTLocalIpcSessionConnect(PRTLOCALIPCSESSION phSession, const char *pszName, uint32_t fFlags)
533{
534 return VINF_SUCCESS;
535}
536
537
538/**
539 * Call when the reference count reaches 0.
540 * Caller owns the critsect.
541 * @param pThis The instance to destroy.
542 */
543static void rtLocalIpcSessionWinDestroy(PRTLOCALIPCSESSIONINT pThis)
544{
545 BOOL fRc = CloseHandle(pThis->hNmPipe);
546 AssertMsg(fRc, ("%d\n", GetLastError())); NOREF(fRc);
547 pThis->hNmPipe = INVALID_HANDLE_VALUE;
548
549 fRc = CloseHandle(pThis->hEvent);
550 AssertMsg(fRc, ("%d\n", GetLastError())); NOREF(fRc);
551 pThis->hEvent = NULL;
552
553 RTCritSectLeave(&pThis->CritSect);
554 RTCritSectDelete(&pThis->CritSect);
555
556 RTMemFree(pThis);
557}
558
559
560RTDECL(int) RTLocalIpcSessionClose(RTLOCALIPCSESSION hSession)
561{
562 /*
563 * Validate input.
564 */
565 if (hSession == NIL_RTLOCALIPCSESSION)
566 return VINF_SUCCESS;
567 PRTLOCALIPCSESSIONINT pThis = (RTLOCALIPCSESSION)hSession;
568 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
569 AssertReturn(pThis->u32Magic != RTLOCALIPCSESSION_MAGIC, VERR_INVALID_MAGIC);
570
571 /*
572 * Cancel any thread currently busy using the session,
573 * leaving the cleanup to it.
574 */
575 RTCritSectEnter(&pThis->CritSect);
576 ASMAtomicUoWriteU32(&pThis->u32Magic, ~RTLOCALIPCSESSION_MAGIC);
577 ASMAtomicUoWriteBool(&pThis->fCancelled, true);
578 pThis->cRefs--;
579
580 if (pThis->cRefs > 0)
581 {
582 BOOL fRc = SetEvent(pThis->hEvent);
583 AssertMsg(fRc, ("%d\n", GetLastError())); NOREF(fRc);
584
585 RTCritSectLeave(&pThis->CritSect);
586 }
587 else
588 rtLocalIpcSessionWinDestroy(pThis);
589
590 return VINF_SUCCESS;
591}
592
593
594RTDECL(int) RTLocalIpcSessionRead(RTLOCALIPCSESSION hSession, void *pvBuffer, size_t cbBuffer, size_t *pcbRead)
595{
596 return VINF_SUCCESS;
597}
598
599
600RTDECL(int) RTLocalIpcSessionWrite(RTLOCALIPCSESSION hSession, const void *pvBuffer, size_t cbBuffer)
601{
602 return VINF_SUCCESS;
603}
604
605
606RTDECL(int) RTLocalIpcSessionFlush(RTLOCALIPCSESSION hSession)
607{
608 return VINF_SUCCESS;
609}
610
611
612RTDECL(int) RTLocalIpcSessionWaitForData(RTLOCALIPCSESSION hSession, uint32_t cMillies)
613{
614 RTThreadSleep(1000);
615 return VINF_SUCCESS;
616}
617
618
619RTDECL(int) RTLocalIpcSessionCancel(RTLOCALIPCSESSION hSession)
620{
621 return VINF_SUCCESS;
622}
623
624
625RTDECL(int) RTLocalIpcSessionQueryProcess(RTLOCALIPCSESSION hSession, PRTPROCESS pProcess)
626{
627 return VERR_NOT_SUPPORTED;
628}
629
630
631RTDECL(int) RTLocalIpcSessionQueryUserId(RTLOCALIPCSESSION hSession, PRTUID pUid)
632{
633 return VERR_NOT_SUPPORTED;
634}
635
636
637RTDECL(int) RTLocalIpcSessionQueryGroupId(RTLOCALIPCSESSION hSession, PRTUID pUid)
638{
639 return VERR_NOT_SUPPORTED;
640}
641
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette