e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync * Host channel.
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync * Copyright (C) 2012 Oracle Corporation
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.
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/* A registered provider of channels. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTLISTNODE nodeContext; /* Member of the list of providers in the service context. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync/* An established channel. */
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 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. */
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 RTLISTNODE nodeClient; /* In the client, for cleanup when a client disconnects. */
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync VBOXHOSTCHCLIENT *pClient; /* The client which uses the channel, NULL when the client does not exist. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync/* Only one service instance is supported. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync * Provider management.
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic void vhcProviderDestroy(VBOXHOSTCHPROVIDER *pProvider)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic int32_t vhcProviderAddRef(VBOXHOSTCHPROVIDER *pProvider)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic void vhcProviderRelease(VBOXHOSTCHPROVIDER *pProvider)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (c == 0)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic VBOXHOSTCHPROVIDER *vhcProviderFind(VBOXHOSTCHCTX *pCtx, const char *pszName)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListForEach(&pCtx->listProviders, pIter, VBOXHOSTCHPROVIDER, nodeContext)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic int vhcProviderRegister(VBOXHOSTCHCTX *pCtx, VBOXHOSTCHPROVIDER *pProvider)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync /* @todo check a duplicate. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListAppend(&pCtx->listProviders, &pProvider->nodeContext);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic int vhcProviderUnregister(VBOXHOSTCHPROVIDER *pProvider)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync /* @todo check that the provider is in the list. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync /* @todo mark the provider as invalid in each instance. also detach channels? */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync * Select an unique handle for the new channel.
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync * Works under the lock.
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic int vhcHandleCreate(VBOXHOSTCHCLIENT *pClient, uint32_t *pu32Handle)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t u32Handle = ASMAtomicIncU32(&pClient->u32HandleSrc);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListForEach(&pClient->listChannels, pIter, VBOXHOSTCHINSTANCE, nodeClient)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync * Channel instance management.
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic void vhcInstanceDestroy(VBOXHOSTCHINSTANCE *pInstance)
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync HOSTCHLOG(("HostChannel: destroy %p\n", pInstance));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic int32_t vhcInstanceAddRef(VBOXHOSTCHINSTANCE *pInstance)
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync HOSTCHLOG(("INST: %p %d addref\n", pInstance, pInstance->cRefs));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic void vhcInstanceRelease(VBOXHOSTCHINSTANCE *pInstance)
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync HOSTCHLOG(("INST: %p %d release\n", pInstance, pInstance->cRefs));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync if (c == 0)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic int vhcInstanceCreate(VBOXHOSTCHCLIENT *pClient, VBOXHOSTCHINSTANCE **ppInstance)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHINSTANCE *pInstance = (VBOXHOSTCHINSTANCE *)RTMemAllocZ(sizeof(VBOXHOSTCHINSTANCE));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync rc = vhcHandleCreate(pClient, &pInstance->u32Handle);
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync /* Used by the client, that is in the list of channels. */
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync /* Add to the list of created channel instances. It is inactive while pClient is 0. */
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync RTListAppend(&pClient->listChannels, &pInstance->nodeClient);
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync /* Return to the caller. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic VBOXHOSTCHINSTANCE *vhcInstanceFind(VBOXHOSTCHCLIENT *pClient, uint32_t u32Handle)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListForEach(&pClient->listChannels, pIter, VBOXHOSTCHINSTANCE, nodeClient)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic VBOXHOSTCHINSTANCE *vhcInstanceFindByChannelPtr(VBOXHOSTCHCLIENT *pClient, void *pvChannel)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListForEach(&pClient->listChannels, pIter, VBOXHOSTCHINSTANCE, nodeClient)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic void vhcInstanceDetach(VBOXHOSTCHINSTANCE *pInstance)
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync HOSTCHLOG(("HostChannel: detach %p\n", pInstance));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync pInstance->pProvider->iface.HostChannelDetach(pInstance->pvChannel);
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync vhcInstanceRelease(pInstance); /* Not in the provider's list anymore. */
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync vhcInstanceRelease(pInstance); /* Not used by the client anymore. */
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync * Channel callback contexts.
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsyncstatic int vhcCallbackCtxCreate(VBOXHOSTCHCLIENT *pClient, VBOXHOSTCHCALLBACKCTX **ppCallbackCtx)
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync VBOXHOSTCHCALLBACKCTX *pCallbackCtx = (VBOXHOSTCHCALLBACKCTX *)RTMemAllocZ(sizeof(VBOXHOSTCHCALLBACKCTX));
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync /* The callback context is accessed by the providers threads. */
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync RTListAppend(&pClient->listContexts, &pCallbackCtx->nodeClient);
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsyncstatic int vhcCallbackCtxDelete(VBOXHOSTCHCALLBACKCTX *pCallbackCtx)
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync /* The callback is associated with a client.
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync * Check that the callback is in the list and remove it from the list.
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync RTListForEach(&pClient->listContexts, pIter, VBOXHOSTCHCALLBACKCTX, nodeClient)
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync /* It is not in the clients anymore. May be the client has been disconnected.
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync * Just free the memory.
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync * Host channel service functions.
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListForEachSafe(&pCtx->listProviders, pIter, pIterNext, VBOXHOSTCHPROVIDER, nodeContext)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncint vboxHostChannelClientConnect(VBOXHOSTCHCLIENT *pClient)
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.
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncvoid vboxHostChannelClientDisconnect(VBOXHOSTCHCLIENT *pClient)
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync /* Clear the list of contexts and prevent acceess to the client. */
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync RTListForEachSafe(&pClient->listContexts, pIter, pNext, VBOXHOSTCHCALLBACKCTX, nodeClient)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync /* If there are attached channels, detach them. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync RTListForEachSafe(&pClient->listChannels, pIter, pIterNext, VBOXHOSTCHINSTANCE, nodeClient)
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncint vboxHostChannelAttach(VBOXHOSTCHCLIENT *pClient,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync const char *pszName,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync HOSTCHLOG(("HostChannel: Attach: (%d) [%s] 0x%08X\n", pClient->u32ClientID, pszName, u32Flags));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync /* Look if there is a provider. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHPROVIDER *pProvider = vhcProviderFind(pClient->pCtx, pszName);
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync rc = pProvider->iface.HostChannelAttach(pProvider->iface.pvProvider,
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync /* It is already in the channels list of the client. */
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync vhcInstanceAddRef(pInstance); /* Referenced by the list of provider's channels. */
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync RTListAppend(&pProvider->listChannels, &pInstance->nodeProvider);
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync HOSTCHLOG(("HostChannel: Attach: (%d) handle %d\n", pClient->u32ClientID, pInstance->u32Handle));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncint vboxHostChannelDetach(VBOXHOSTCHCLIENT *pClient,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync HOSTCHLOG(("HostChannel: Detach: (%d) handle %d\n", pClient->u32ClientID, u32Handle));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHINSTANCE *pInstance = vhcInstanceFind(pClient, u32Handle);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync const void *pvData,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync HOSTCHLOG(("HostChannel: Send: (%d) handle %d, %d bytes\n", pClient->u32ClientID, u32Handle, cbData));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHINSTANCE *pInstance = vhcInstanceFind(pClient, u32Handle);
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync pInstance->pProvider->iface.HostChannelSend(pInstance->pvChannel, pvData, cbData);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync HOSTCHLOG(("HostChannel: Recv: (%d) handle %d, cbData %d\n", pClient->u32ClientID, u32Handle, cbData));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHINSTANCE *pInstance = vhcInstanceFind(pClient, u32Handle);
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync rc = pInstance->pProvider->iface.HostChannelRecv(pInstance->pvChannel, pvData, cbData,
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync HOSTCHLOG(("HostChannel: Recv: (%d) handle %d, rc %Rrc, recv %d, rem %d\n",
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync pClient->u32ClientID, u32Handle, rc, cbData, *pu32SizeReceived, *pu32SizeRemaining));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncint vboxHostChannelControl(VBOXHOSTCHCLIENT *pClient,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync HOSTCHLOG(("HostChannel: Control: (%d) handle %d, cbData %d\n", pClient->u32ClientID, u32Handle, cbData));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHINSTANCE *pInstance = vhcInstanceFind(pClient, u32Handle);
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync pInstance->pProvider->iface.HostChannelControl(pInstance->pvChannel, u32Code,
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsyncint vboxHostChannelEventWait(VBOXHOSTCHCLIENT *pClient,
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync /* If there is a wait request already, cancel it. */
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync vboxHostChannelReportAsync(pClient, 0, VBOX_HOST_CHANNEL_EVENT_CANCELLED, NULL, 0);
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync /* Check if there is something in the client's event queue. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHANNELEVENT *pEvent = RTListGetFirst(&pClient->listEvents, VBOXHOSTCHANNELEVENT, NodeEvent);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync HOSTCHLOG(("HostChannel: QueryEvent: (%d), event %p\n", pClient->u32ClientID, pEvent));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync /* Report the event. */
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync HOSTCHLOG(("HostChannel: QueryEvent: (%d), cbEvent %d\n",
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync vboxHostChannelEventParmsSet(paParms, pEvent->u32ChannelHandle,
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync /* No event available at the time. Process asynchronously. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync /* Tell the caller that there is no event. */
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsyncint vboxHostChannelEventCancel(VBOXHOSTCHCLIENT *pClient)
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync /* If there is a wait request alredy, cancel it. */
c6cfa4860d893a2cfde3c4148879456093af57bfvboxsync vboxHostChannelReportAsync(pClient, 0, VBOX_HOST_CHANNEL_EVENT_CANCELLED, NULL, 0);
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync/* @thread provider */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsyncstatic DECLCALLBACK(void) HostChannelCallbackEvent(void *pvCallbacks, void *pvChannel,
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync uint32_t u32Id, const void *pvEvent, uint32_t cbEvent)
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync VBOXHOSTCHCALLBACKCTX *pCallbackCtx = (VBOXHOSTCHCALLBACKCTX *)pvCallbacks;
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync /* Check that the structure is still associated with a client.
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync * The client can disconnect and will be invalid.
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync HOSTCHLOG(("HostChannel: CallbackEvent[%p]: client gone.\n"));
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync /* The client does not exist anymore, skip the event. */
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync RTListForEach(&pClient->listContexts, pIter, VBOXHOSTCHCALLBACKCTX, nodeClient)
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync HOSTCHLOG(("HostChannel: CallbackEvent[%p]: client does not have the context.\n"));
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync /* The context is not in the list of contexts. Skip the event. */
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync VBOXHOSTCHINSTANCE *pInstance = vhcInstanceFindByChannelPtr(pClient, pvChannel);
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync HOSTCHLOG(("HostChannel: CallbackEvent[%p]: (%d) instance %p\n",
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync /* Instance was already detached. Skip the event. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync HOSTCHLOG(("HostChannel: CallbackEvent: (%d) handle %d, async %d, cbEvent %d\n",
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync pClient->u32ClientID, u32ChannelHandle, pClient->fAsync, cbEvent));
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync /* Check whether the event is waited. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync /* Report the event. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync vboxHostChannelReportAsync(pClient, u32ChannelHandle, u32Id, pvEvent, cbEvent);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync /* Put it to the queue. */
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHANNELEVENT *pEvent = (VBOXHOSTCHANNELEVENT *)RTMemAlloc(sizeof(VBOXHOSTCHANNELEVENT) + cbEvent);
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync RTListAppend(&pClient->listEvents, &pEvent->NodeEvent);
a98ffaaf4c29cf148cb52f094fe3c42fd4cdcc57vboxsync/* @thread provider */
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsyncstatic DECLCALLBACK(void) HostChannelCallbackDeleted(void *pvCallbacks, void *pvChannel)
f486cea04d3045b35f843ddd19eb2de45a9929fevboxsync vhcCallbackCtxDelete((VBOXHOSTCHCALLBACKCTX *)pvCallbacks);
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync const char *pszName,
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync HOSTCHLOG(("HostChannel: Query: (%d) name [%s], cbData %d\n", pClient->u32ClientID, pszName, cbData));
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync /* Look if there is a provider. */
f675364bced7de2a98408e697da210bc6e6ddb2avboxsync VBOXHOSTCHPROVIDER *pProvider = vhcProviderFind(pClient->pCtx, pszName);
e2a4ff87ea2e2e95350793b5fccb143c1819fadcvboxsync VBOXHOSTCHPROVIDER *pProvider = (VBOXHOSTCHPROVIDER *)RTMemAllocZ(sizeof(VBOXHOSTCHPROVIDER));