int GuestObject::callbackRemove(uint32_t uContextID) { LogFlowThisFunc(("Removing callback (Session=%RU32, Object=%RU32, Count=%RU32) CID=%RU32\n", VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(uContextID), VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(uContextID), VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(uContextID), uContextID)); GuestCtrlCallbacks::iterator it = mObject.mCallbacks.find(VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(uContextID)); if (it != mObject.mCallbacks.end()) { delete it->second; mObject.mCallbacks.erase(it); return VINF_SUCCESS; } return VERR_NOT_FOUND; }
int GuestBase::signalWaitEvent(VBoxEventType_T aType, IEvent *aEvent) { int rc = RTCritSectEnter(&mWaitEventCritSect); #ifdef DEBUG uint32_t cEvents = 0; #endif if (RT_SUCCESS(rc)) { GuestEventGroup::iterator itGroup = mWaitEventGroups.find(aType); if (itGroup != mWaitEventGroups.end()) { GuestWaitEvents::iterator itEvents = itGroup->second.begin(); while (itEvents != itGroup->second.end()) { #ifdef DEBUG LogFlowThisFunc(("Signalling event=%p, type=%ld (CID %RU32: Session=%RU32, Object=%RU32, Count=%RU32) ...\n", itEvents->second, aType, itEvents->first, VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(itEvents->first), VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(itEvents->first), VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(itEvents->first))); #endif ComPtr<IEvent> pThisEvent = aEvent; Assert(!pThisEvent.isNull()); int rc2 = itEvents->second->SignalExternal(aEvent); if (RT_SUCCESS(rc)) rc = rc2; if (RT_SUCCESS(rc2)) { /* Remove the event from all other event groups (except the * original one!) because it was signalled. */ AssertPtr(itEvents->second); const GuestEventTypes evTypes = itEvents->second->Types(); for (GuestEventTypes::const_iterator itType = evTypes.begin(); itType != evTypes.end(); itType++) { if ((*itType) != aType) /* Only remove all other groups. */ { /* Get current event group. */ GuestEventGroup::iterator evGroup = mWaitEventGroups.find((*itType)); Assert(evGroup != mWaitEventGroups.end()); /* Lookup event in event group. */ GuestWaitEvents::iterator evEvent = evGroup->second.find(itEvents->first /* Context ID */); Assert(evEvent != evGroup->second.end()); LogFlowThisFunc(("Removing event=%p (type %ld)\n", evEvent->second, (*itType))); evGroup->second.erase(evEvent); LogFlowThisFunc(("%zu events for type=%ld left\n", evGroup->second.size(), aType)); } } /* Remove the event from the passed-in event group. */ itGroup->second.erase(itEvents++); } else itEvents++; #ifdef DEBUG cEvents++; #endif } } int rc2 = RTCritSectLeave(&mWaitEventCritSect); if (RT_SUCCESS(rc)) rc = rc2; } #ifdef DEBUG LogFlowThisFunc(("Signalled %RU32 events, rc=%Rrc\n", cEvents, rc)); #endif return rc; }
int GuestFile::i_onFileNotify(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData) { AssertPtrReturn(pCbCtx, VERR_INVALID_POINTER); AssertPtrReturn(pSvcCbData, VERR_INVALID_POINTER); LogFlowThisFuncEnter(); if (pSvcCbData->mParms < 3) return VERR_INVALID_PARAMETER; int vrc = VINF_SUCCESS; int idx = 1; /* Current parameter index. */ CALLBACKDATA_FILE_NOTIFY dataCb; /* pSvcCb->mpaParms[0] always contains the context ID. */ pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.uType); pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.rc); int guestRc = (int)dataCb.rc; /* uint32_t vs. int. */ LogFlowFunc(("uType=%RU32, guestRc=%Rrc\n", dataCb.uType, guestRc)); if (RT_FAILURE(guestRc)) { int rc2 = i_setFileStatus(FileStatus_Error, guestRc); AssertRC(rc2); rc2 = signalWaitEventInternal(pCbCtx, guestRc, NULL /* pPayload */); AssertRC(rc2); return VINF_SUCCESS; /* Report to the guest. */ } switch (dataCb.uType) { case GUEST_FILE_NOTIFYTYPE_ERROR: { int rc2 = i_setFileStatus(FileStatus_Error, guestRc); AssertRC(rc2); break; } case GUEST_FILE_NOTIFYTYPE_OPEN: { if (pSvcCbData->mParms == 4) { pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.u.open.uHandle); AssertMsg(mData.mID == VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCbCtx->uContextID), ("File ID %RU32 does not match context ID %RU32\n", mData.mID, VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCbCtx->uContextID))); /* Set the process status. */ int rc2 = i_setFileStatus(FileStatus_Open, guestRc); AssertRC(rc2); } else vrc = VERR_NOT_SUPPORTED; break; } case GUEST_FILE_NOTIFYTYPE_CLOSE: { int rc2 = i_setFileStatus(FileStatus_Closed, guestRc); AssertRC(rc2); break; } case GUEST_FILE_NOTIFYTYPE_READ: { if (pSvcCbData->mParms == 4) { pSvcCbData->mpaParms[idx++].getPointer(&dataCb.u.read.pvData, &dataCb.u.read.cbData); uint32_t cbRead = dataCb.u.read.cbData; AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); mData.mOffCurrent += cbRead; alock.release(); com::SafeArray<BYTE> data((size_t)cbRead); data.initFrom((BYTE*)dataCb.u.read.pvData, cbRead); fireGuestFileReadEvent(mEventSource, mSession, this, mData.mOffCurrent, cbRead, ComSafeArrayAsInParam(data)); } else vrc = VERR_NOT_SUPPORTED; break; } case GUEST_FILE_NOTIFYTYPE_WRITE: { if (pSvcCbData->mParms == 4) { pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.u.write.cbWritten); AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); mData.mOffCurrent += dataCb.u.write.cbWritten; uint64_t uOffCurrent = mData.mOffCurrent; alock.release(); fireGuestFileWriteEvent(mEventSource, mSession, this, uOffCurrent, dataCb.u.write.cbWritten); } else vrc = VERR_NOT_SUPPORTED; break; } case GUEST_FILE_NOTIFYTYPE_SEEK: { if (pSvcCbData->mParms == 4) { pSvcCbData->mpaParms[idx++].getUInt64(&dataCb.u.seek.uOffActual); AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); mData.mOffCurrent = dataCb.u.seek.uOffActual; alock.release(); fireGuestFileOffsetChangedEvent(mEventSource, mSession, this, dataCb.u.seek.uOffActual, 0 /* Processed */); } else vrc = VERR_NOT_SUPPORTED; break; } case GUEST_FILE_NOTIFYTYPE_TELL: { if (pSvcCbData->mParms == 4) { pSvcCbData->mpaParms[idx++].getUInt64(&dataCb.u.tell.uOffActual); AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); mData.mOffCurrent = dataCb.u.tell.uOffActual; alock.release(); fireGuestFileOffsetChangedEvent(mEventSource, mSession, this, dataCb.u.tell.uOffActual, 0 /* Processed */); } else vrc = VERR_NOT_SUPPORTED; break; } default: vrc = VERR_NOT_SUPPORTED; break; } if (RT_SUCCESS(vrc)) { GuestWaitEventPayload payload(dataCb.uType, &dataCb, sizeof(dataCb)); int rc2 = signalWaitEventInternal(pCbCtx, guestRc, &payload); AssertRC(rc2); } LogFlowThisFunc(("uType=%RU32, guestRc=%Rrc\n", dataCb.uType, dataCb.rc)); LogFlowFuncLeaveRC(vrc); return vrc; }