VirtualBox

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

Last change on this file since 27509 was 26344, checked in by vboxsync, 15 years ago

Runtime: white space cleanup.

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