/* static */ DECLCALLBACK(int) Guest::notifyCtrlDispatcher(void *pvExtension, uint32_t u32Function, void *pvParms, uint32_t cbParms) { 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, pvParms, cbParms)); 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) */ PCALLBACKHEADER pHeader = (PCALLBACKHEADER)pvParms; AssertPtr(pHeader); #ifdef DEBUG LogFlowFunc(("CID=%RU32, uSession=%RU32, uObject=%RU32, uCount=%RU32\n", pHeader->u32ContextID, VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pHeader->u32ContextID), VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pHeader->u32ContextID), VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(pHeader->u32ContextID))); #endif bool fDispatch = true; #ifdef DEBUG /* * Pre-check: If we got a status message with an error and VERR_TOO_MUCH_DATA * it means that that guest could not handle the entire message * because of its exceeding size. This should not happen on daily * use but testcases might try this. It then makes no sense to dispatch * this further because we don't have a valid context ID. */ if (u32Function == GUEST_EXEC_SEND_STATUS) { PCALLBACKDATAEXECSTATUS pCallbackData = reinterpret_cast<PCALLBACKDATAEXECSTATUS>(pvParms); AssertPtr(pCallbackData); AssertReturn(sizeof(CALLBACKDATAEXECSTATUS) == cbParms, VERR_INVALID_PARAMETER); AssertReturn(CALLBACKDATAMAGIC_EXEC_STATUS == pCallbackData->hdr.u32Magic, VERR_INVALID_PARAMETER); if ( pCallbackData->u32Status == PROC_STS_ERROR && ((int)pCallbackData->u32Flags) == VERR_TOO_MUCH_DATA) { LogFlowFunc(("Requested command with too much data, skipping dispatching ...\n")); Assert(pCallbackData->u32PID == 0); fDispatch = false; } } #endif int rc = VINF_SUCCESS; if (fDispatch) { rc = pGuest->dispatchToSession(pHeader->u32ContextID, u32Function, pvParms, cbParms); if (RT_SUCCESS(rc)) return rc; } LogFlowFuncLeaveRC(rc); return rc; }