/* static */ DECLCALLBACK(int) Guest::i_notifyCtrlDispatcher(void *pvExtension, uint32_t u32Function, void *pvData, uint32_t cbData) { using namespace guestControl; /* * No locking, as this is purely a notification which does not make any * changes to the object state. */ LogFlowFunc(("pvExtension=%p, u32Function=%RU32, pvParms=%p, cbParms=%RU32\n", pvExtension, u32Function, pvData, cbData)); ComObjPtr<Guest> pGuest = reinterpret_cast<Guest *>(pvExtension); Assert(!pGuest.isNull()); /* * For guest control 2.0 using the legacy commands we need to do the following here: * - Get the callback header to access the context ID * - Get the context ID of the callback * - Extract the session ID out of the context ID * - Dispatch the whole stuff to the appropriate session (if still exists) */ if (cbData != sizeof(VBOXGUESTCTRLHOSTCALLBACK)) return VERR_NOT_SUPPORTED; PVBOXGUESTCTRLHOSTCALLBACK pSvcCb = (PVBOXGUESTCTRLHOSTCALLBACK)pvData; AssertPtr(pSvcCb); if (!pSvcCb->mParms) /* At least context ID must be present. */ return VERR_INVALID_PARAMETER; uint32_t uContextID; int rc = pSvcCb->mpaParms[0].getUInt32(&uContextID); AssertMsgRCReturn(rc, ("Unable to extract callback context ID, pvData=%p\n", pSvcCb), rc); #ifdef DEBUG LogFlowFunc(("CID=%RU32, uSession=%RU32, uObject=%RU32, uCount=%RU32\n", uContextID, VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(uContextID), VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(uContextID), VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(uContextID))); #endif VBOXGUESTCTRLHOSTCBCTX ctxCb = { u32Function, uContextID }; rc = pGuest->i_dispatchToSession(&ctxCb, pSvcCb); LogFlowFunc(("Returning rc=%Rrc\n", rc)); return rc; }
/* static */ DECLCALLBACK(int) Guest::i_notifyCtrlDispatcher(void *pvExtension, uint32_t idMessage, void *pvData, uint32_t cbData) { using namespace guestControl; /* * No locking, as this is purely a notification which does not make any * changes to the object state. */ Log2Func(("pvExtension=%p, idMessage=%RU32, pvParms=%p, cbParms=%RU32\n", pvExtension, idMessage, pvData, cbData)); ComObjPtr<Guest> pGuest = reinterpret_cast<Guest *>(pvExtension); AssertReturn(pGuest.isNotNull(), VERR_WRONG_ORDER); /* * The data packet should ever be a problem, but check to be sure. */ AssertMsgReturn(cbData == sizeof(VBOXGUESTCTRLHOSTCALLBACK), ("Guest control host callback data has wrong size (expected %zu, got %zu) - buggy host service!\n", sizeof(VBOXGUESTCTRLHOSTCALLBACK), cbData), VERR_INVALID_PARAMETER); PVBOXGUESTCTRLHOSTCALLBACK pSvcCb = (PVBOXGUESTCTRLHOSTCALLBACK)pvData; AssertPtrReturn(pSvcCb, VERR_INVALID_POINTER); /* * For guest control 2.0 using the legacy messages we need to do the following here: * - Get the callback header to access the context ID * - Get the context ID of the callback * - Extract the session ID out of the context ID * - Dispatch the whole stuff to the appropriate session (if still exists) * * At least context ID parameter must always be present. */ ASSERT_GUEST_RETURN(pSvcCb->mParms > 0, VERR_WRONG_PARAMETER_COUNT); ASSERT_GUEST_MSG_RETURN(pSvcCb->mpaParms[0].type == VBOX_HGCM_SVC_PARM_32BIT, ("type=%d\n", pSvcCb->mpaParms[0].type), VERR_WRONG_PARAMETER_TYPE); uint32_t const idContext = pSvcCb->mpaParms[0].u.uint32; VBOXGUESTCTRLHOSTCBCTX CtxCb = { idMessage, idContext }; int rc = pGuest->i_dispatchToSession(&CtxCb, pSvcCb); Log2Func(("CID=%#x, idSession=%RU32, uObject=%RU32, uCount=%RU32, rc=%Rrc\n", idContext, VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(idContext), VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(idContext), VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(idContext), rc)); return rc; }