/* Register a new VBVA channel by index. * */ int HGSMIChannelRegister (HGSMICHANNELINFO * pChannelInfo, uint8_t u8Channel, const char *pszName, PFNHGSMICHANNELHANDLER pfnChannelHandler, void *pvChannelHandler, HGSMICHANNELHANDLER *pOldHandler) { AssertPtrReturn(pOldHandler, VERR_INVALID_PARAMETER); /* Check whether the channel is already registered. */ HGSMICHANNEL *pChannel = HGSMIChannelFindById (pChannelInfo, u8Channel); if (!pChannel) { /* Channel is not yet registered. */ pChannel = &pChannelInfo->Channels[u8Channel]; pChannel->u8Flags = HGSMI_CH_F_REGISTERED; pChannel->u8Channel = u8Channel; pChannel->handler.pfnHandler = NULL; pChannel->handler.pvHandler = NULL; pChannel->pszName = pszName; } *pOldHandler = pChannel->handler; pChannel->handler.pfnHandler = pfnChannelHandler; pChannel->handler.pvHandler = pvChannelHandler; return VINF_SUCCESS; }
/** Register a new HGSMI channel by index. * * @returns VBox status. * @param pChannelInfo The channel pool managed by the caller. * @param u8Channel Index of the channel. * @param pszName Name of the channel (optional, allocated by the caller). * @param pfnChannelHandler The channel callback. * @param pvChannelHandler The callback pointer. */ int HGSMIChannelRegister(HGSMICHANNELINFO *pChannelInfo, uint8_t u8Channel, const char *pszName, PFNHGSMICHANNELHANDLER pfnChannelHandler, void *pvChannelHandler) { /* Check whether the channel is already registered. */ HGSMICHANNEL *pChannel = HGSMIChannelFindById(pChannelInfo, u8Channel); if (pChannel) { HGSMI_STRICT_ASSERT_FAILED(); return VERR_ALREADY_EXISTS; } /* Channel is not yet registered. */ pChannel = &pChannelInfo->Channels[u8Channel]; pChannel->u8Flags = HGSMI_CH_F_REGISTERED; pChannel->u8Channel = u8Channel; pChannel->handler.pfnHandler = pfnChannelHandler; pChannel->handler.pvHandler = pvChannelHandler; pChannel->pszName = pszName; return VINF_SUCCESS; }
int HGSMIBufferProcess (HGSMIAREA *pArea, HGSMICHANNELINFO * pChannelInfo, HGSMIOFFSET offBuffer) { LogFlowFunc(("pArea %p, offBuffer 0x%x\n", pArea, offBuffer)); AssertPtr(pArea); AssertPtr(pChannelInfo); int rc = VERR_GENERAL_FAILURE; // VM_ASSERT_EMT(pIns->pVM); /* Guest has prepared a command description at 'offBuffer'. */ const HGSMIBUFFERHEADER *pHeader = hgsmiVerifyBuffer (pArea, offBuffer); Assert(pHeader); if (pHeader) { /* Pass the command to the appropriate handler registered with this instance. * Start with the handler list head, which is the preallocated HGSMI setup channel. */ HGSMICHANNEL *pChannel = HGSMIChannelFindById (pChannelInfo, pHeader->u8Channel); Assert(pChannel); if (pChannel) { hgsmiBufferProcess (pChannel, pHeader); HGSMI_STRICT_ASSERT(hgsmiVerifyBuffer (pArea, offBuffer) != NULL); rc = VINF_SUCCESS; } else { rc = VERR_INVALID_FUNCTION; } } else { rc = VERR_INVALID_HANDLE; // LogRel(("HGSMI[%s]: ignored invalid guest buffer 0x%08X!!!\n", pIns->pszName, offBuffer)); } return rc; }
DECLCALLBACK(int) VBoxMPHGSMIHostCmdRequestCB(HVBOXVIDEOHGSMI hHGSMI, uint8_t u8Channel, uint32_t iDisplay, struct VBVAHOSTCMD **ppCmd) { LOGF_ENTER(); if (!ppCmd) { LOGF_LEAVE(); return VERR_INVALID_PARAMETER; } PHGSMIHOSTCOMMANDCONTEXT pCtx = &((PVBOXMP_COMMON)hHGSMI)->hostCtx; /* pick up the host commands */ VBoxHGSMIProcessHostQueue(pCtx); HGSMICHANNEL *pChannel = HGSMIChannelFindById(&pCtx->channels, u8Channel); if(pChannel) { VBVA_CHANNELCONTEXTS * pContexts = (VBVA_CHANNELCONTEXTS *)pChannel->handler.pvHandler; VBVADISP_CHANNELCONTEXT *pDispContext = VBoxVbvaFindHandlerInfo(pContexts, iDisplay); if(pDispContext) { VBVAHOSTCMD *pCmd; do { pCmd = ASMAtomicReadPtrT(&pDispContext->pCmd, VBVAHOSTCMD *); } while (!ASMAtomicCmpXchgPtr(&pDispContext->pCmd, NULL, pCmd)); *ppCmd = VBoxVbvaReverseList(pCmd); LOGF_LEAVE(); return VINF_SUCCESS; } else { WARN(("!pDispContext for display %d", iDisplay)); } }
/** Process a guest buffer. * * @returns VBox status. * @param pArea Area which supposed to contain the buffer. * @param pChannelInfo The channel pool. * @param offBuffer The buffer location in the area. */ int HGSMIBufferProcess(const HGSMIAREA *pArea, HGSMICHANNELINFO *pChannelInfo, HGSMIOFFSET offBuffer) { LogFlowFunc(("pArea %p, offBuffer 0x%x\n", pArea, offBuffer)); AssertPtrReturn(pArea, VERR_INVALID_PARAMETER); AssertPtrReturn(pChannelInfo, VERR_INVALID_PARAMETER); /* Guest has prepared a command description at 'offBuffer'. */ HGSMIBUFFERCONTEXT bufferContext; int rc = hgsmiVerifyBuffer(pArea, offBuffer, &bufferContext); if (RT_SUCCESS(rc)) { /* Pass the command to the appropriate handler registered with this instance. * Start with the handler list head, which is the preallocated HGSMI setup channel. */ const HGSMICHANNEL *pChannel = HGSMIChannelFindById(pChannelInfo, bufferContext.pHeader->u8Channel); if (pChannel) { const HGSMICHANNELHANDLER *pHandler = &pChannel->handler; if (pHandler->pfnHandler) { pHandler->pfnHandler(pHandler->pvHandler, bufferContext.pHeader->u16ChannelInfo, bufferContext.pvData, bufferContext.cbData); } HGSMI_STRICT_ASSERT(RT_SUCCESS(hgsmiVerifyBuffer(pArea, offBuffer, &bufferContext))); } else { rc = VERR_INVALID_FUNCTION; HGSMI_STRICT_ASSERT_FAILED(); } } return rc; }