5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync/** @file
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync *
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync * VirtualBox API client session token holder (in the client process)
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync/*
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync * Copyright (C) 2006-2013 Oracle Corporation
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync *
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync * available from http://www.virtualbox.org. This file is free software;
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync * you can redistribute it and/or modify it under the terms of the GNU
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync * General Public License (GPL) as published by the Free Software
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync#include <iprt/asm.h>
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync#include <iprt/assert.h>
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync#include <iprt/log.h>
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync#include <iprt/semaphore.h>
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync#include <iprt/process.h>
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync#ifdef VBOX_WITH_SYS_V_IPC_SESSION_WATCHER
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync# include <errno.h>
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync# include <sys/types.h>
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync# include <sys/stat.h>
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync# include <sys/ipc.h>
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync# include <sys/sem.h>
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync#endif
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync#include <VBox/com/defs.h>
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync#include "ClientTokenHolder.h"
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync#include "SessionImpl.h"
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync/** client token holder thread */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsyncstatic DECLCALLBACK(int) ClientTokenHolderThread(RTTHREAD Thread, void *pvUser);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync#endif
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsyncSession::ClientTokenHolder::ClientTokenHolder()
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync{
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync AssertReleaseFailed();
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync}
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsyncSession::ClientTokenHolder::~ClientTokenHolder()
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync{
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync /* release the client token */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync#if defined(RT_OS_WINDOWS)
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync if (mSem && mThreadSem)
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync {
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync /*
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync * tell the thread holding the token to release it;
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync * it will close mSem handle
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync ::SetEvent(mSem);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync /* wait for the thread to finish */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync ::WaitForSingleObject(mThreadSem, INFINITE);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync ::CloseHandle(mThreadSem);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync mThreadSem = NULL;
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync mSem = NULL;
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync mThread = NIL_RTTHREAD;
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync }
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync#elif defined(RT_OS_OS2)
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync if (mThread != NIL_RTTHREAD)
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync {
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync Assert(mSem != NIL_RTSEMEVENT);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync /* tell the thread holding the token to release it */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync int vrc = RTSemEventSignal(mSem);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync AssertRC(vrc == NO_ERROR);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync /* wait for the thread to finish */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync vrc = RTThreadUserWait(mThread, RT_INDEFINITE_WAIT);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync Assert(RT_SUCCESS(vrc) || vrc == VERR_INTERRUPTED);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync mThread = NIL_RTTHREAD;
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync }
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync if (mSem != NIL_RTSEMEVENT)
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync {
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync RTSemEventDestroy(mSem);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync mSem = NIL_RTSEMEVENT;
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync }
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync#elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync if (mSem >= 0)
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync {
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync ::sembuf sop = { 0, 1, SEM_UNDO };
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync ::semop(mSem, &sop, 1);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync mSem = -1;
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync }
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync#elif defined(VBOX_WITH_GENERIC_SESSION_WATCHER)
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync if (!mToken.isNull())
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync {
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync mToken->Abandon();
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync mToken.setNull();
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync }
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync#else
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync# error "Port me!"
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync#endif
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync}
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync#ifndef VBOX_WITH_GENERIC_SESSION_WATCHER
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsyncSession::ClientTokenHolder::ClientTokenHolder(const Utf8Str &strTokenId) :
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync mClientTokenId(strTokenId)
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync#else /* VBOX_WITH_GENERIC_SESSION_WATCHER */
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsyncSession::ClientTokenHolder::ClientTokenHolder(IToken *aToken) :
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync mToken(aToken)
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync#endif /* VBOX_WITH_GENERIC_SESSION_WATCHER */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync{
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync#ifdef CTHSEMTYPE
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync mSem = CTHSEMARG;
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync#endif
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync mThread = NIL_RTTHREAD;
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync#endif
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync#if defined(RT_OS_WINDOWS)
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync mThreadSem = CTHTHREADSEMARG;
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync Bstr bstrTokenId(strTokenId);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync /*
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync * Since there is no guarantee that the constructor and destructor will be
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync * called in the same thread, we need a separate thread to hold the token.
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync mThreadSem = ::CreateEvent(NULL, FALSE, FALSE, NULL);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync AssertMsgReturnVoid(mThreadSem,
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync ("Cannot create an event sem, err=%d", ::GetLastError()));
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync void *data[3];
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync data[0] = (void*)(BSTR)bstrTokenId.raw();
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync data[1] = (void*)mThreadSem;
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync data[2] = 0; /* will get an output from the thread */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync /* create a thread to hold the token until signalled to release it */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync int vrc = RTThreadCreate(&mThread, ClientTokenHolderThread, (void*)data, 0, RTTHREADTYPE_MAIN_WORKER, 0, "IPCHolder");
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync AssertRCReturnVoid(vrc);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync /* wait until thread init is completed */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync DWORD wrc = ::WaitForSingleObject(mThreadSem, INFINITE);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync AssertMsg(wrc == WAIT_OBJECT_0, ("Wait failed, err=%d\n", ::GetLastError()));
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync Assert(data[2]);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync if (wrc == WAIT_OBJECT_0 && data[2])
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync {
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync /* memorize the event sem we should signal in close() */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync mSem = (HANDLE)data[2];
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync }
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync else
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync {
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync ::CloseHandle(mThreadSem);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync mThreadSem = NULL;
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync }
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync#elif defined(RT_OS_OS2)
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync Bstr bstrTokenId(strTokenId);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync /*
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync * Since there is no guarantee that the constructor and destructor will be
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync * called in the same thread, we need a separate thread to hold the token.
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync int vrc = RTSemEventCreate(&mSem);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync AssertRCReturnVoid(vrc);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync void *data[3];
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync data[0] = (void*)bstrTokenId.raw();
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync data[1] = (void*)mSem;
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync data[2] = (void*)false; /* will get the thread result here */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync /* create a thread to hold the token until signalled to release it */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync vrc = RTThreadCreate(&mThread, ClientTokenHolderThread, (void *) data,
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync 0, RTTHREADTYPE_MAIN_WORKER, 0, "IPCHolder");
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync AssertRCReturnVoid(vrc);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync /* wait until thread init is completed */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync vrc = RTThreadUserWait(mThread, RT_INDEFINITE_WAIT);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync AssertReturnVoid(RT_SUCCESS(vrc) || vrc == VERR_INTERRUPTED);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync /* the thread must succeed */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync AssertReturnVoid((bool)data[2]);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync#elif defined(VBOX_WITH_SYS_V_IPC_SESSION_WATCHER)
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync# ifdef VBOX_WITH_NEW_SYS_V_KEYGEN
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync key_t key = RTStrToUInt32(strTokenId.c_str());
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync AssertMsgReturnVoid(key != 0,
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync ("Key value of 0 is not valid for client token"));
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync# else /* !VBOX_WITH_NEW_SYS_V_KEYGEN */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync char *pszSemName = NULL;
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync RTStrUtf8ToCurrentCP(&pszSemName, strTokenId);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync key_t key = ::ftok(pszSemName, 'V');
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync RTStrFree(pszSemName);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync# endif /* !VBOX_WITH_NEW_SYS_V_KEYGEN */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync int s = ::semget(key, 0, 0);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync AssertMsgReturnVoid(s >= 0,
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync ("Cannot open semaphore, errno=%d", errno));
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync /* grab the semaphore */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync ::sembuf sop = { 0, -1, SEM_UNDO };
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync int rv = ::semop(s, &sop, 1);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync AssertMsgReturnVoid(rv == 0,
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync ("Cannot grab semaphore, errno=%d", errno));
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync mSem = s;
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync#elif defined(VBOX_WITH_GENERIC_SESSION_WATCHER)
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync /* nothing to do */
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync#else
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync# error "Port me!"
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync#endif
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync}
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsyncbool Session::ClientTokenHolder::isReady()
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync{
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync#ifndef VBOX_WITH_GENERIC_SESSION_WATCHER
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync return mSem != CTHSEMARG;
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync#else /* VBOX_WITH_GENERIC_SESSION_WATCHER */
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync return !mToken.isNull();
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync#endif /* VBOX_WITH_GENERIC_SESSION_WATCHER */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync}
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync/** client token holder thread */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsyncDECLCALLBACK(int) ClientTokenHolderThread(RTTHREAD Thread, void *pvUser)
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync{
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync LogFlowFuncEnter();
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync Assert(pvUser);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync void **data = (void **)pvUser;
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync# if defined(RT_OS_WINDOWS)
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync BSTR sessionId = (BSTR)data[0];
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync HANDLE initDoneSem = (HANDLE)data[1];
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync HANDLE mutex = ::OpenMutex(MUTEX_ALL_ACCESS, FALSE, sessionId);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync AssertMsg(mutex, ("cannot open token, err=%d\n", ::GetLastError()));
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync if (mutex)
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync {
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync /* grab the token */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync DWORD wrc = ::WaitForSingleObject(mutex, 0);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync AssertMsg(wrc == WAIT_OBJECT_0, ("cannot grab token, err=%d\n", wrc));
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync if (wrc == WAIT_OBJECT_0)
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync {
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync HANDLE finishSem = ::CreateEvent(NULL, FALSE, FALSE, NULL);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync AssertMsg(finishSem, ("cannot create event sem, err=%d\n", ::GetLastError()));
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync if (finishSem)
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync {
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync data[2] = (void*)finishSem;
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync /* signal we're done with init */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync ::SetEvent(initDoneSem);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync /* wait until we're signaled to release the token */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync ::WaitForSingleObject(finishSem, INFINITE);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync /* release the token */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync LogFlow(("ClientTokenHolderThread(): releasing token...\n"));
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync BOOL success = ::ReleaseMutex(mutex);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync AssertMsg(success, ("cannot release token, err=%d\n", ::GetLastError()));
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync ::CloseHandle(mutex);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync ::CloseHandle(finishSem);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync }
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync }
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync }
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync /* signal we're done */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync ::SetEvent(initDoneSem);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync# elif defined(RT_OS_OS2)
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync Utf8Str sessionId = (BSTR)data[0];
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync RTSEMEVENT finishSem = (RTSEMEVENT)data[1];
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync LogFlowFunc(("sessionId='%s', finishSem=%p\n", sessionId.raw(), finishSem));
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync HMTX mutex = NULLHANDLE;
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync APIRET arc = ::DosOpenMutexSem((PSZ)sessionId.raw(), &mutex);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync AssertMsg(arc == NO_ERROR, ("cannot open token, arc=%ld\n", arc));
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync if (arc == NO_ERROR)
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync {
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync /* grab the token */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync LogFlowFunc(("grabbing token...\n"));
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync arc = ::DosRequestMutexSem(mutex, SEM_IMMEDIATE_RETURN);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync AssertMsg(arc == NO_ERROR, ("cannot grab token, arc=%ld\n", arc));
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync if (arc == NO_ERROR)
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync {
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync /* store the answer */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync data[2] = (void*)true;
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync /* signal we're done */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync int vrc = RTThreadUserSignal(Thread);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync AssertRC(vrc);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync /* wait until we're signaled to release the token */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync LogFlowFunc(("waiting for termination signal..\n"));
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync vrc = RTSemEventWait(finishSem, RT_INDEFINITE_WAIT);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync Assert(arc == ERROR_INTERRUPT || ERROR_TIMEOUT);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync /* release the token */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync LogFlowFunc(("releasing token...\n"));
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync arc = ::DosReleaseMutexSem(mutex);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync AssertMsg(arc == NO_ERROR, ("cannot release token, arc=%ld\n", arc));
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync }
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync ::DosCloseMutexSem(mutex);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync }
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync /* store the answer */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync data[1] = (void*)false;
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync /* signal we're done */
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync int vrc = RTThreadUserSignal(Thread);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync AssertRC(vrc);
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync# else
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync# error "Port me!"
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync# endif
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync LogFlowFuncLeave();
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync return 0;
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync}
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync#endif
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync
5637660ed0c2a4a3a114e6d2d4c8294f2fd5f18fvboxsync/* vi: set tabstop=4 shiftwidth=4 expandtab: */