HostChannel.cpp revision e2a4ff87ea2e2e95350793b5fccb143c1819fadc
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync/** @file
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync * Host channel.
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync/*
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync * Copyright (C) 2012 Oracle Corporation
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync *
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync * available from http://www.virtualbox.org. This file is free software;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync * you can redistribute it and/or modify it under the terms of the GNU
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync * General Public License (GPL) as published by the Free Software
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync#include <iprt/alloc.h>
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync#include <iprt/string.h>
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync#include <iprt/asm.h>
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync#include <iprt/assert.h>
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync#include "HostChannel.h"
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic DECLCALLBACK(void) HostChannelCallbackEvent(void *pvCallbacks, void *pvInstance,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t u32Id, const void *pvEvent, uint32_t cbEvent);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync/* A registered provider of channels. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsynctypedef struct VBOXHOSTCHPROVIDER
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync int32_t volatile cRefs;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTLISTNODE nodeContext; /* Member of the list of providers in the service context. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHCTX *pCtx;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHANNELINTERFACE iface;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync char *pszName;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTLISTANCHOR listChannels;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync} VBOXHOSTCHPROVIDER;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync/* An established channel. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsynctypedef struct VBOXHOSTCHINSTANCE
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync int32_t volatile cRefs;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTLISTNODE nodeClient; /* In the client, for cleanup when a client disconnects. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTLISTNODE nodeProvider; /* In the provider, needed for cleanup when the provider is unregistered. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHCLIENT *pClient; /* The client which uses the channel. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHPROVIDER *pProvider; /* NULL if the provider was unregistered. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync void *pvChannel; /* Provider's context of the channel. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t u32Handle; /* handle assigned to the channel by the service. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync} VBOXHOSTCHINSTANCE;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstruct VBOXHOSTCHCTX
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync bool fInitialized;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTLISTANCHOR listProviders;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync};
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync/* Only one service instance is supported. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic VBOXHOSTCHCTX g_ctx = { false };
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic VBOXHOSTCHANNELCALLBACKS g_callbacks =
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync HostChannelCallbackEvent
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync};
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync/*
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync * Provider management.
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic void vhcProviderDestroy(VBOXHOSTCHPROVIDER *pProvider)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTStrFree(pProvider->pszName);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic int32_t vhcProviderAddRef(VBOXHOSTCHPROVIDER *pProvider)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return ASMAtomicIncS32(&pProvider->cRefs);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic void vhcProviderRelease(VBOXHOSTCHPROVIDER *pProvider)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync int32_t c = ASMAtomicDecS32(&pProvider->cRefs);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync Assert(c >= 0);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (c == 0)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcProviderDestroy(pProvider);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTMemFree(pProvider);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic VBOXHOSTCHPROVIDER *vhcProviderFind(VBOXHOSTCHCTX *pCtx, const char *pszName)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHPROVIDER *pProvider = NULL;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync int rc = vboxHostChannelLock();
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (RT_SUCCESS(rc))
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHPROVIDER *pIter;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListForEach(&pCtx->listProviders, pIter, VBOXHOSTCHPROVIDER, nodeContext)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (RTStrCmp(pIter->pszName, pszName) == 0)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pProvider = pIter;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcProviderAddRef(pProvider);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync break;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vboxHostChannelUnlock();
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return pProvider;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic int vhcProviderRegister(VBOXHOSTCHCTX *pCtx, VBOXHOSTCHPROVIDER *pProvider)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync int rc = vboxHostChannelLock();
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (RT_SUCCESS(rc))
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync /* @todo check a duplicate. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListAppend(&pCtx->listProviders, &pProvider->nodeContext);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vboxHostChannelUnlock();
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (RT_FAILURE(rc))
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcProviderRelease(pProvider);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return rc;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic int vhcProviderUnregister(VBOXHOSTCHPROVIDER *pProvider)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync int rc = vboxHostChannelLock();
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (RT_SUCCESS(rc))
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync /* @todo check that the provider is in the list. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync /* @todo mark the provider as invalid in each instance. also detach channels? */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListNodeRemove(&pProvider->nodeContext);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vboxHostChannelUnlock();
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcProviderRelease(pProvider);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return rc;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync/*
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync * Select an unique handle for the new channel.
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync * Works under the lock.
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic int vhcHandleCreate(VBOXHOSTCHCLIENT *pClient, uint32_t *pu32Handle)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync bool fOver = false;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync for(;;)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t u32Handle = ASMAtomicIncU32(&pClient->u32HandleSrc);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (u32Handle == 0)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (fOver)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return VERR_NOT_SUPPORTED;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync fOver = true;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync continue;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHINSTANCE *pDuplicate = NULL;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHINSTANCE *pIter;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListForEach(&pClient->listChannels, pIter, VBOXHOSTCHINSTANCE, nodeClient)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (pIter->u32Handle == u32Handle)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pDuplicate = pIter;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync break;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (pDuplicate == NULL)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync *pu32Handle = u32Handle;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync break;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return VINF_SUCCESS;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync/*
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync * Channel instance management.
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic void vhcInstanceDestroy(VBOXHOSTCHINSTANCE *pInstance)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync /* @todo free u32Handle? */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic int32_t vhcInstanceAddRef(VBOXHOSTCHINSTANCE *pInstance)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return ASMAtomicIncS32(&pInstance->cRefs);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic void vhcInstanceRelease(VBOXHOSTCHINSTANCE *pInstance)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync int32_t c = ASMAtomicDecS32(&pInstance->cRefs);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync Assert(c >= 0);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (c == 0)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcInstanceDestroy(pInstance);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTMemFree(pInstance);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic int vhcInstanceCreate(VBOXHOSTCHCLIENT *pClient, VBOXHOSTCHINSTANCE **ppInstance)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync int rc = VINF_SUCCESS;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHINSTANCE *pInstance = (VBOXHOSTCHINSTANCE *)RTMemAllocZ(sizeof(VBOXHOSTCHINSTANCE));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (pInstance)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync rc = vboxHostChannelLock();
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (RT_SUCCESS(rc))
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync rc = vhcHandleCreate(pClient, &pInstance->u32Handle);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (RT_SUCCESS(rc))
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcInstanceAddRef(pInstance);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync *ppInstance = pInstance;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vboxHostChannelUnlock();
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (RT_FAILURE(rc))
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTMemFree(pInstance);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync else
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync rc = VERR_NO_MEMORY;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return rc;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic VBOXHOSTCHINSTANCE *vhcInstanceFind(VBOXHOSTCHCLIENT *pClient, uint32_t u32Handle)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHINSTANCE *pInstance = NULL;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync int rc = vboxHostChannelLock();
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (RT_SUCCESS(rc))
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHINSTANCE *pIter;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListForEach(&pClient->listChannels, pIter, VBOXHOSTCHINSTANCE, nodeClient)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (pIter->u32Handle == u32Handle)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pInstance = pIter;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcInstanceAddRef(pInstance);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync break;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vboxHostChannelUnlock();
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return pInstance;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic VBOXHOSTCHINSTANCE *vhcInstanceFindByChannelPtr(VBOXHOSTCHCLIENT *pClient, void *pvChannel)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHINSTANCE *pInstance = NULL;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync int rc = vboxHostChannelLock();
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (RT_SUCCESS(rc))
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHINSTANCE *pIter;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListForEach(&pClient->listChannels, pIter, VBOXHOSTCHINSTANCE, nodeClient)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (pIter->pvChannel == pvChannel)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pInstance = pIter;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcInstanceAddRef(pInstance);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync break;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vboxHostChannelUnlock();
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return pInstance;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic void vhcInstanceDetach(VBOXHOSTCHINSTANCE *pInstance)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (pInstance->pProvider)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pInstance->pProvider->iface.HostChannelDetach(pInstance->pvChannel);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListNodeRemove(&pInstance->nodeProvider);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcProviderRelease(pInstance->pProvider);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcInstanceRelease(pInstance); /* Not in the list anymore. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListNodeRemove(&pInstance->nodeClient);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcInstanceRelease(pInstance); /* Not in the list anymore. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync/*
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync * Host channel service functions.
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncint vboxHostChannelInit(void)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHCTX *pCtx = &g_ctx;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (pCtx->fInitialized)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return VERR_NOT_SUPPORTED;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pCtx->fInitialized = true;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListInit(&pCtx->listProviders);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return VINF_SUCCESS;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncvoid vboxHostChannelDestroy(void)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHCTX *pCtx = &g_ctx;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHPROVIDER *pIter;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHPROVIDER *pIterNext;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListForEachSafe(&pCtx->listProviders, pIter, pIterNext, VBOXHOSTCHPROVIDER, nodeContext)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcProviderUnregister(pIter);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pCtx->fInitialized = false;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncint vboxHostChannelClientConnect(VBOXHOSTCHCLIENT *pClient)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync /* A guest client is connecting to the service.
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync * Later the client will use Attach calls to connect to channel providers.
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync * pClient is already zeroed.
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pClient->pCtx = &g_ctx;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListInit(&pClient->listChannels);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListInit(&pClient->listEvents);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return VINF_SUCCESS;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncvoid vboxHostChannelClientDisconnect(VBOXHOSTCHCLIENT *pClient)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync /* If there are attached channels, detach them. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHINSTANCE *pIter;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHINSTANCE *pIterNext;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListForEachSafe(&pClient->listChannels, pIter, pIterNext, VBOXHOSTCHINSTANCE, nodeClient)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcInstanceDetach(pIter);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncint vboxHostChannelAttach(VBOXHOSTCHCLIENT *pClient,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t *pu32Handle,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync const char *pszName,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t u32Flags)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync int rc = VINF_SUCCESS;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync HOSTCHLOG(("HostChannel: Attach: (%d) [%s] 0x%08X\n", pClient->u32ClientID, pszName, u32Flags));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync /* Look if there is a provider. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHPROVIDER *pProvider = vhcProviderFind(pClient->pCtx, pszName);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (pProvider)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHINSTANCE *pInstance = NULL;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync rc = vhcInstanceCreate(pClient, &pInstance);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (RT_SUCCESS(rc))
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync void *pvChannel = NULL;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync rc = pProvider->iface.HostChannelAttach(pProvider->iface.pvProvider,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync &pvChannel,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync u32Flags,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync &g_callbacks, pClient);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (RT_SUCCESS(rc))
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcProviderAddRef(pProvider);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pInstance->pProvider = pProvider;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pInstance->pClient = pClient;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pInstance->pvChannel = pvChannel;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcInstanceAddRef(pInstance); /* Referenced by the list client's channels. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListAppend(&pClient->listChannels, &pInstance->nodeClient);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcInstanceAddRef(pInstance); /* Referenced by the list of provider's channels. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListAppend(&pProvider->listChannels, &pInstance->nodeProvider);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync *pu32Handle = pInstance->u32Handle;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync HOSTCHLOG(("HostChannel: Attach: (%d) handle %d\n", pClient->u32ClientID, pInstance->u32Handle));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcInstanceRelease(pInstance);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcProviderRelease(pProvider);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync else
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync rc = VERR_NOT_SUPPORTED;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return rc;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncint vboxHostChannelDetach(VBOXHOSTCHCLIENT *pClient,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t u32Handle)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync HOSTCHLOG(("HostChannel: Detach: (%d) handle %d\n", pClient->u32ClientID, u32Handle));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync int rc = VINF_SUCCESS;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHINSTANCE *pInstance = vhcInstanceFind(pClient, u32Handle);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (pInstance)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcInstanceDetach(pInstance);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcInstanceRelease(pInstance);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync else
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync rc = VERR_NOT_SUPPORTED;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return rc;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncint vboxHostChannelSend(VBOXHOSTCHCLIENT *pClient,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t u32Handle,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync const void *pvData,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t cbData)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync HOSTCHLOG(("HostChannel: Send: (%d) handle %d, %d bytes\n", pClient->u32ClientID, u32Handle, cbData));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync int rc = VINF_SUCCESS;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHINSTANCE *pInstance = vhcInstanceFind(pClient, u32Handle);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if ( pInstance
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync && pInstance->pProvider)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pInstance->pProvider->iface.HostChannelSend(pInstance->pvChannel, pvData, cbData);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcInstanceRelease(pInstance);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync else
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync rc = VERR_NOT_SUPPORTED;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return rc;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncint vboxHostChannelRecv(VBOXHOSTCHCLIENT *pClient,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t u32Handle,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync void *pvData,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t cbData,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t *pu32SizeReceived,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t *pu32SizeRemaining)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync HOSTCHLOG(("HostChannel: Recv: (%d) handle %d, cbData %d\n", pClient->u32ClientID, u32Handle, cbData));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync int rc = VINF_SUCCESS;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHINSTANCE *pInstance = vhcInstanceFind(pClient, u32Handle);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if ( pInstance
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync && pInstance->pProvider)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync rc = pInstance->pProvider->iface.HostChannelRecv(pInstance->pvChannel, pvData, cbData,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pu32SizeReceived, pu32SizeRemaining);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync HOSTCHLOG(("HostChannel: Recv: (%d) handle %d, rc %Rrc, recv %d, rem %d\n",
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pClient->u32ClientID, u32Handle, rc, cbData, *pu32SizeReceived, *pu32SizeRemaining));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcInstanceRelease(pInstance);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync else
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync rc = VERR_NOT_SUPPORTED;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return rc;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncint vboxHostChannelControl(VBOXHOSTCHCLIENT *pClient,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t u32Handle,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t u32Code,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync void *pvParm,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t cbParm,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync void *pvData,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t cbData,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t *pu32SizeDataReturned)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync HOSTCHLOG(("HostChannel: Control: (%d) handle %d, cbData %d\n", pClient->u32ClientID, u32Handle, cbData));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync int rc = VINF_SUCCESS;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHINSTANCE *pInstance = vhcInstanceFind(pClient, u32Handle);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if ( pInstance
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync && pInstance->pProvider)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pInstance->pProvider->iface.HostChannelControl(pInstance->pvChannel, u32Code,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pvParm, cbParm,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pvData, cbData, pu32SizeDataReturned);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcInstanceRelease(pInstance);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync else
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync rc = VERR_NOT_SUPPORTED;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return rc;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsynctypedef struct VBOXHOSTCHANNELEVENT
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTLISTNODE NodeEvent;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t u32ChannelHandle;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t u32Id;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync void *pvEvent;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t cbEvent;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync} VBOXHOSTCHANNELEVENT;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync/* This is called under the lock. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncint vboxHostChannelQueryEvent(VBOXHOSTCHCLIENT *pClient,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync bool *pfEvent,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t *pu32Handle,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t *pu32Id,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync void *pvParm,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t cbParm,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t *pcbParmOut)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync /* Check if there is something in the client's event queue. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHANNELEVENT *pEvent = RTListGetFirst(&pClient->listEvents, VBOXHOSTCHANNELEVENT, NodeEvent);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync HOSTCHLOG(("HostChannel: QueryEvent: (%d), event %p\n", pClient->u32ClientID, pEvent));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (pEvent)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync /* Report the event. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListNodeRemove(&pEvent->NodeEvent);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync *pfEvent = true;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync *pu32Handle = pEvent->u32ChannelHandle;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync *pu32Id = pEvent->u32Id;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t cbToCopy = RT_MIN(cbParm, pEvent->cbEvent);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync HOSTCHLOG(("HostChannel: QueryEvent: (%d), cbParm %d, cbEvent %d\n",
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pClient->u32ClientID, cbParm, pEvent->cbEvent));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (cbToCopy > 0)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync memcpy(pvParm, pEvent->pvEvent, cbToCopy);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync *pcbParmOut = cbToCopy;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTMemFree(pEvent);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync else
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync /* Tell the caller that there is no event. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync *pfEvent = false;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return VINF_SUCCESS;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic DECLCALLBACK(void) HostChannelCallbackEvent(void *pvCallbacks, void *pvChannel,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t u32Id, const void *pvEvent, uint32_t cbEvent)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHCLIENT *pClient = (VBOXHOSTCHCLIENT *)pvCallbacks;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHINSTANCE *pInstance = vhcInstanceFindByChannelPtr(pClient, pvChannel);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync HOSTCHLOG(("HostChannel: CallbackEvent: (%d) instance %p\n",
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pClient->u32ClientID, pInstance));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (!pInstance)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync#ifdef DEBUG_sunlover
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync AssertFailed();
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync#endif
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync int rc = vboxHostChannelLock();
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (RT_FAILURE(rc))
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t u32ChannelHandle = pInstance->u32Handle;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync HOSTCHLOG(("HostChannel: CallbackEvent: (%d) handle %d, async %d, cbEvent %d\n",
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pClient->u32ClientID, u32ChannelHandle, pClient->fAsync, cbEvent));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync /* Check whether the event is waited. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (pClient->fAsync)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync /* Report the event. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vboxHostChannelReportAsync(pClient, u32ChannelHandle, u32Id, pvEvent, cbEvent);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pClient->fAsync = false;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync else
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync /* Put it to the queue. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHANNELEVENT *pEvent = (VBOXHOSTCHANNELEVENT *)RTMemAlloc(sizeof(VBOXHOSTCHANNELEVENT) + cbEvent);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (pEvent)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pEvent->u32ChannelHandle = u32ChannelHandle;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pEvent->u32Id = u32Id;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (cbEvent)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pEvent->pvEvent = &pEvent[0];
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync memcpy(pEvent->pvEvent, pvEvent, cbEvent);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync else
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pEvent->pvEvent = NULL;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pEvent->cbEvent = cbEvent;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (RT_SUCCESS(rc))
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListAppend(&pClient->listEvents, &pEvent->NodeEvent);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync else
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTMemFree(pEvent);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vboxHostChannelUnlock();
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncint vboxHostChannelRegister(const char *pszName,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync const VBOXHOSTCHANNELINTERFACE *pInterface,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t cbInterface)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync int rc = VINF_SUCCESS;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHCTX *pCtx = &g_ctx;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHPROVIDER *pProvider = (VBOXHOSTCHPROVIDER *)RTMemAllocZ(sizeof(VBOXHOSTCHPROVIDER));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (pProvider)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pProvider->pCtx = pCtx;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pProvider->iface = *pInterface;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListInit(&pProvider->listChannels);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pProvider->pszName = RTStrDup(pszName);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (pProvider->pszName)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcProviderAddRef(pProvider);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync rc = vhcProviderRegister(pCtx, pProvider);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync else
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTMemFree(pProvider);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync rc = VERR_NO_MEMORY;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync else
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync rc = VERR_NO_MEMORY;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return rc;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncint vboxHostChannelUnregister(const char *pszName)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync int rc = VINF_SUCCESS;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHCTX *pCtx = &g_ctx;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHPROVIDER *pProvider = vhcProviderFind(pCtx, pszName);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (pProvider)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync rc = vhcProviderUnregister(pProvider);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcProviderRelease(pProvider);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return rc;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}