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
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic DECLCALLBACK(void) HostChannelCallbackEvent(void *pvCallbacks, void *pvInstance,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t u32Id, const void *pvEvent, uint32_t cbEvent);
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsyncstatic DECLCALLBACK(void) HostChannelCallbackDeleted(void *pvCallbacks, void *pvChannel);
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
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync/* The channel callbacks context. The provider passes the pointer as a callback parameter.
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync * Created for the provider and deleted when the provider says so.
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync */
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsynctypedef struct VBOXHOSTCHCALLBACKCTX
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync{
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync RTLISTNODE nodeClient; /* In the client, for cleanup when a client disconnects. */
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync VBOXHOSTCHCLIENT *pClient; /* The client which uses the channel, NULL when the client does not exist. */
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync} VBOXHOSTCHCALLBACKCTX;
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync/* Only one service instance is supported. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic VBOXHOSTCHCTX g_ctx = { false };
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
920730ce664b646eea6da4219b93030b1ee32405vboxsyncstatic VBOXHOSTCHANNELCALLBACKS g_callbacks =
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync HostChannelCallbackEvent,
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync HostChannelCallbackDeleted
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{
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync HOSTCHLOG(("HostChannel: destroy %p\n", pInstance));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic int32_t vhcInstanceAddRef(VBOXHOSTCHINSTANCE *pInstance)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync HOSTCHLOG(("INST: %p %d addref\n", pInstance, pInstance->cRefs));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return ASMAtomicIncS32(&pInstance->cRefs);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic void vhcInstanceRelease(VBOXHOSTCHINSTANCE *pInstance)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync int32_t c = ASMAtomicDecS32(&pInstance->cRefs);
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync HOSTCHLOG(("INST: %p %d release\n", pInstance, 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 {
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync /* Used by the client, that is in the list of channels. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcInstanceAddRef(pInstance);
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync /* Add to the list of created channel instances. It is inactive while pClient is 0. */
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync RTListAppend(&pClient->listChannels, &pInstance->nodeClient);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync /* Return to the caller. */
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync vhcInstanceAddRef(pInstance);
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 {
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync if ( pIter->pClient
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync && 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
732da7aa8afe6d7a7afd51b07888b2ef48d22a31vboxsync if (pvChannel == NULL)
732da7aa8afe6d7a7afd51b07888b2ef48d22a31vboxsync {
732da7aa8afe6d7a7afd51b07888b2ef48d22a31vboxsync return NULL;
732da7aa8afe6d7a7afd51b07888b2ef48d22a31vboxsync }
732da7aa8afe6d7a7afd51b07888b2ef48d22a31vboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync int rc = vboxHostChannelLock();
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (RT_SUCCESS(rc))
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHINSTANCE *pIter;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListForEach(&pClient->listChannels, pIter, VBOXHOSTCHINSTANCE, nodeClient)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync if ( pIter->pClient
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync && 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{
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync HOSTCHLOG(("HostChannel: detach %p\n", pInstance));
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (pInstance->pProvider)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pInstance->pProvider->iface.HostChannelDetach(pInstance->pvChannel);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListNodeRemove(&pInstance->nodeProvider);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vhcProviderRelease(pInstance->pProvider);
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync pInstance->pProvider = NULL;
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync vhcInstanceRelease(pInstance); /* Not in the provider's list anymore. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync int rc = vboxHostChannelLock();
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync if (RT_SUCCESS(rc))
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync {
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync RTListNodeRemove(&pInstance->nodeClient);
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync vboxHostChannelUnlock();
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync vhcInstanceRelease(pInstance); /* Not used by the client anymore. */
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync/*
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync * Channel callback contexts.
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync */
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsyncstatic int vhcCallbackCtxCreate(VBOXHOSTCHCLIENT *pClient, VBOXHOSTCHCALLBACKCTX **ppCallbackCtx)
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync{
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync int rc = VINF_SUCCESS;
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync VBOXHOSTCHCALLBACKCTX *pCallbackCtx = (VBOXHOSTCHCALLBACKCTX *)RTMemAllocZ(sizeof(VBOXHOSTCHCALLBACKCTX));
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync if (pCallbackCtx != NULL)
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync {
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync /* The callback context is accessed by the providers threads. */
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync rc = vboxHostChannelLock();
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync if (RT_SUCCESS(rc))
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync {
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync RTListAppend(&pClient->listContexts, &pCallbackCtx->nodeClient);
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync pCallbackCtx->pClient = pClient;
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync vboxHostChannelUnlock();
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync }
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync else
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync {
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync RTMemFree(pCallbackCtx);
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync }
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync }
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync else
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync {
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync rc = VERR_NO_MEMORY;
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync }
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync if (RT_SUCCESS(rc))
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync {
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync *ppCallbackCtx = pCallbackCtx;
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync }
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync return rc;
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync}
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsyncstatic int vhcCallbackCtxDelete(VBOXHOSTCHCALLBACKCTX *pCallbackCtx)
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync{
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync int rc = vboxHostChannelLock();
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync if (RT_SUCCESS(rc))
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync {
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync VBOXHOSTCHCLIENT *pClient = pCallbackCtx->pClient;
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync if (pClient != NULL)
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync {
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync /* The callback is associated with a client.
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync * Check that the callback is in the list and remove it from the list.
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync */
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync bool fFound = false;
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync VBOXHOSTCHCALLBACKCTX *pIter;
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync RTListForEach(&pClient->listContexts, pIter, VBOXHOSTCHCALLBACKCTX, nodeClient)
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync {
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync if (pIter == pCallbackCtx)
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync {
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync fFound = true;
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync break;
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync }
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync }
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync if (fFound)
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync {
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync RTListNodeRemove(&pCallbackCtx->nodeClient);
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync }
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync else
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync {
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync AssertFailed();
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync rc = VERR_INVALID_PARAMETER;
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync }
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync }
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync else
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync {
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync /* It is not in the clients anymore. May be the client has been disconnected.
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync * Just free the memory.
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync */
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync }
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync vboxHostChannelUnlock();
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync }
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync if (RT_SUCCESS(rc))
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync {
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync RTMemFree(pCallbackCtx);
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync }
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync return rc;
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync}
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);
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync RTListInit(&pClient->listContexts);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return VINF_SUCCESS;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncvoid vboxHostChannelClientDisconnect(VBOXHOSTCHCLIENT *pClient)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync /* Clear the list of contexts and prevent acceess to the client. */
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync int rc = vboxHostChannelLock();
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync if (RT_SUCCESS(rc))
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync {
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync VBOXHOSTCHCALLBACKCTX *pIter;
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync VBOXHOSTCHCALLBACKCTX *pNext;
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync RTListForEachSafe(&pClient->listContexts, pIter, pNext, VBOXHOSTCHCALLBACKCTX, nodeClient)
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync {
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync pIter->pClient = NULL;
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync RTListNodeRemove(&pIter->nodeClient);
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync }
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync vboxHostChannelUnlock();
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync }
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
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 {
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync VBOXHOSTCHCALLBACKCTX *pCallbackCtx = NULL;
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync rc = vhcCallbackCtxCreate(pClient, &pCallbackCtx);
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (RT_SUCCESS(rc))
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync void *pvChannel = NULL;
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync rc = pProvider->iface.HostChannelAttach(pProvider->iface.pvProvider,
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync &pvChannel,
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync u32Flags,
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync &g_callbacks, pCallbackCtx);
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync if (RT_SUCCESS(rc))
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync {
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync vhcProviderAddRef(pProvider);
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync pInstance->pProvider = pProvider;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync pInstance->pClient = pClient;
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync pInstance->pvChannel = pvChannel;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync /* It is already in the channels list of the client. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync vhcInstanceAddRef(pInstance); /* Referenced by the list of provider's channels. */
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync RTListAppend(&pProvider->listChannels, &pInstance->nodeProvider);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync *pu32Handle = pInstance->u32Handle;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync HOSTCHLOG(("HostChannel: Attach: (%d) handle %d\n", pClient->u32ClientID, pInstance->u32Handle));
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync }
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync if (RT_FAILURE(rc))
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync {
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync vhcCallbackCtxDelete(pCallbackCtx);
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync if (RT_FAILURE(rc))
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync {
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync vhcInstanceDetach(pInstance);
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync }
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync
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
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync if (pInstance)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync if (pInstance->pProvider)
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync {
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync pInstance->pProvider->iface.HostChannelSend(pInstance->pvChannel, pvData, cbData);
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync }
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
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync if (pInstance)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync if (pInstance->pProvider)
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync {
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync rc = pInstance->pProvider->iface.HostChannelRecv(pInstance->pvChannel, pvData, cbData,
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync pu32SizeReceived, pu32SizeRemaining);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync HOSTCHLOG(("HostChannel: Recv: (%d) handle %d, rc %Rrc, recv %d, rem %d\n",
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync pClient->u32ClientID, u32Handle, rc, cbData, *pu32SizeReceived, *pu32SizeRemaining));
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync }
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
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync if (pInstance)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync if (pInstance->pProvider)
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync {
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync pInstance->pProvider->iface.HostChannelControl(pInstance->pvChannel, u32Code,
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync pvParm, cbParm,
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync pvData, cbData, pu32SizeDataReturned);
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync }
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
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsyncint vboxHostChannelEventWait(VBOXHOSTCHCLIENT *pClient,
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync bool *pfEvent,
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync VBOXHGCMCALLHANDLE callHandle,
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync VBOXHGCMSVCPARM *paParms)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync int rc = vboxHostChannelLock();
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync if (RT_FAILURE(rc))
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync {
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync return rc;
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync if (pClient->fAsync)
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync {
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync /* If there is a wait request already, cancel it. */
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync vboxHostChannelReportAsync(pClient, 0, VBOX_HOST_CHANNEL_EVENT_CANCELLED, NULL, 0);
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync pClient->fAsync = false;
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync }
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync /* Check if there is something in the client's event queue. */
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
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync HOSTCHLOG(("HostChannel: QueryEvent: (%d), cbEvent %d\n",
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync pClient->u32ClientID, pEvent->cbEvent));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync vboxHostChannelEventParmsSet(paParms, pEvent->u32ChannelHandle,
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync pEvent->u32Id, pEvent->pvEvent, pEvent->cbEvent);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync *pfEvent = true;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTMemFree(pEvent);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync else
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync /* No event available at the time. Process asynchronously. */
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync pClient->fAsync = true;
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync pClient->async.callHandle = callHandle;
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync pClient->async.paParms = paParms;
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync /* Tell the caller that there is no event. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync *pfEvent = false;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync vboxHostChannelUnlock();
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync return rc;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsyncint vboxHostChannelEventCancel(VBOXHOSTCHCLIENT *pClient)
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync{
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync int rc = vboxHostChannelLock();
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync if (RT_SUCCESS(rc))
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync {
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync if (pClient->fAsync)
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync {
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync /* If there is a wait request alredy, cancel it. */
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync vboxHostChannelReportAsync(pClient, 0, VBOX_HOST_CHANNEL_EVENT_CANCELLED, NULL, 0);
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync pClient->fAsync = false;
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync }
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync vboxHostChannelUnlock();
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync }
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync return rc;
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync}
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync/* @thread provider */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic DECLCALLBACK(void) HostChannelCallbackEvent(void *pvCallbacks, void *pvChannel,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t u32Id, const void *pvEvent, uint32_t cbEvent)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync{
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync VBOXHOSTCHCALLBACKCTX *pCallbackCtx = (VBOXHOSTCHCALLBACKCTX *)pvCallbacks;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync int rc = vboxHostChannelLock();
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync if (RT_FAILURE(rc))
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync {
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync return;
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync /* Check that the structure is still associated with a client.
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync * The client can disconnect and will be invalid.
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync */
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync VBOXHOSTCHCLIENT *pClient = pCallbackCtx->pClient;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync if (pClient == NULL)
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync {
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync vboxHostChannelUnlock();
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync HOSTCHLOG(("HostChannel: CallbackEvent[%p]: client gone.\n"));
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync /* The client does not exist anymore, skip the event. */
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync return;
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync }
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync bool fFound = false;
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync VBOXHOSTCHCALLBACKCTX *pIter;
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync RTListForEach(&pClient->listContexts, pIter, VBOXHOSTCHCALLBACKCTX, nodeClient)
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync {
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync if (pIter == pCallbackCtx)
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync {
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync fFound = true;
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync break;
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync }
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync }
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync if (!fFound)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync AssertFailed();
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync vboxHostChannelUnlock();
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync HOSTCHLOG(("HostChannel: CallbackEvent[%p]: client does not have the context.\n"));
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync /* The context is not in the list of contexts. Skip the event. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync VBOXHOSTCHINSTANCE *pInstance = vhcInstanceFindByChannelPtr(pClient, pvChannel);
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync HOSTCHLOG(("HostChannel: CallbackEvent[%p]: (%d) instance %p\n",
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync pCallbackCtx, pClient->u32ClientID, pInstance));
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync if (!pInstance)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync /* Instance was already detached. Skip the event. */
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync vboxHostChannelUnlock();
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync return;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t u32ChannelHandle = pInstance->u32Handle;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync HOSTCHLOG(("HostChannel: CallbackEvent: (%d) handle %d, async %d, cbEvent %d\n",
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync 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 {
f17aa73b10e13ac2061271144c7cbaa5133605dcvboxsync pEvent->pvEvent = &pEvent[1];
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync memcpy(pEvent->pvEvent, pvEvent, cbEvent);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync else
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync {
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pEvent->pvEvent = NULL;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pEvent->cbEvent = cbEvent;
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync RTListAppend(&pClient->listEvents, &pEvent->NodeEvent);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync }
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vboxHostChannelUnlock();
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync vhcInstanceRelease(pInstance);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync}
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync/* @thread provider */
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsyncstatic DECLCALLBACK(void) HostChannelCallbackDeleted(void *pvCallbacks, void *pvChannel)
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync{
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync vhcCallbackCtxDelete((VBOXHOSTCHCALLBACKCTX *)pvCallbacks);
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync}
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync
f675364bced7de2a98408e697da210bc6e6ddb2avboxsyncint vboxHostChannelQuery(VBOXHOSTCHCLIENT *pClient,
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync const char *pszName,
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync uint32_t u32Code,
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync void *pvParm,
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync uint32_t cbParm,
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync void *pvData,
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync uint32_t cbData,
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync uint32_t *pu32SizeDataReturned)
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync{
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync HOSTCHLOG(("HostChannel: Query: (%d) name [%s], cbData %d\n", pClient->u32ClientID, pszName, cbData));
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync int rc = VINF_SUCCESS;
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync /* Look if there is a provider. */
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync VBOXHOSTCHPROVIDER *pProvider = vhcProviderFind(pClient->pCtx, pszName);
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync if (pProvider)
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync {
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync pProvider->iface.HostChannelControl(NULL, u32Code,
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync pvParm, cbParm,
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync pvData, cbData, pu32SizeDataReturned);
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync vhcProviderRelease(pProvider);
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync }
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync else
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync {
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync rc = VERR_NOT_SUPPORTED;
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync }
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync return rc;
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync}
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync
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}