INT4 COfRecvWorker::procRecvBuffer(INT4 sockfd, INT1* buffer, UINT4 len, CSmartPtr<CLoopBuffer>& recvBuffer) { struct ofp_header* header = NULL; const UINT4 headerLen = sizeof(struct ofp_header); UINT2 lenTotal = 0; INT1* pdata = NULL, *pmsg = NULL; CMsg* ofmsg = NULL; CMsgTree& msgTree = CControl::getInstance()->getMsgTree(); while (len >= headerLen) { header = (struct ofp_header*)buffer; lenTotal = ntohs(header->length); if (lenTotal < headerLen) { LOG_WARN_FMT("%s drop packet when invalid ofp_header.length %u !!!", toString(), lenTotal); return BNC_ERR; } if (len < lenTotal) break; procStats(); pdata = (INT1*)m_memPool.alloc(lenTotal); if (NULL == pdata) { LOG_ERROR_FMT("alloc %u bytes failed!", lenTotal); return BNC_ERR; } memcpy(pdata, buffer, lenTotal); pmsg = (INT1*)m_memPool.alloc(sizeof(CMsg)); if (NULL == pmsg) { LOG_ERROR_FMT("alloc CMsg failed !"); m_memPool.release(pdata); return BNC_ERR; } ofmsg = new(pmsg) CMsg(sockfd, header->version, header->type, pdata, lenTotal); ofmsg->setPath(); ofmsg->setKey(); CSmartPtr<CMsgCommon> msg(ofmsg, deleteCmsg); if (msgTree.pushMsg(msg) != BNC_OK) { LOG_INFO_FMT("push msg[%s]key[%s] from sockfd[%d] into tree failed", ofmsg->getPath().c_str(), ofmsg->getKey().c_str(), sockfd); } buffer += lenTotal; len -= lenTotal; } if (len > 0) recvBuffer->write(buffer, len); return BNC_OK; }
INT4 COfRecvWorker::process(INT4 sockfd, INT1* buffer, UINT4 len) { CSmartPtr<CLoopBuffer>& recvBuffer = m_recvBuffer[sockfd]; if (recvBuffer.isNull()) { LOG_WARN_FMT("m_recvBuffer[%d] is null !", sockfd); return BNC_ERR; } UINT4 recvBufLen = recvBuffer->length(); if (0 == recvBufLen) { return procRecvBuffer(sockfd, buffer, len, recvBuffer); } else { if (recvBufLen + len < sizeof(struct ofp_header)) { recvBuffer->write(buffer, len); return BNC_OK; } struct ofp_header header = {0}; INT1* ptr = (INT1*)&header; if (recvBufLen < sizeof(struct ofp_header)) { recvBuffer->read(ptr, recvBufLen, TRUE); memcpy(ptr+recvBufLen, buffer, sizeof(struct ofp_header)-recvBufLen); } else { recvBuffer->read(ptr, sizeof(struct ofp_header), TRUE); } UINT2 lenTotal = ntohs(header.length); if (recvBufLen + len < lenTotal) { recvBuffer->write(buffer, len); } else { procStats(); INT1* pdata = (INT1*)m_memPool.alloc(lenTotal); if (NULL == pdata) { LOG_ERROR_FMT("alloc %u bytes failed!", lenTotal); return BNC_ERR; } recvBuffer->read(pdata, recvBufLen); memcpy(pdata+recvBufLen, buffer, lenTotal-recvBufLen); INT1* pmsg = (INT1*)m_memPool.alloc(sizeof(CMsg)); if (NULL == pmsg) { LOG_ERROR_FMT("alloc CMsg failed !"); m_memPool.release(pdata); return BNC_ERR; } CMsg* ofmsg = new(pmsg) CMsg(sockfd, header.version, header.type, pdata, lenTotal); ofmsg->setPath(); ofmsg->setKey(); CSmartPtr<CMsgCommon> msg(ofmsg, deleteCmsg); if (CControl::getInstance()->getMsgTree().pushMsg(msg) != BNC_OK) { LOG_INFO_FMT("push msg[%s]key[%s] from sockfd[%d] into tree failed", ofmsg->getPath().c_str(), ofmsg->getKey().c_str(), sockfd); } INT1* bufLeft = buffer + (lenTotal - recvBufLen); UINT4 lenLeft = len - (lenTotal - recvBufLen); if (lenLeft > 0) return procRecvBuffer(sockfd, bufLeft, lenLeft, recvBuffer); } } return BNC_OK; }
STDMETHODIMP GuestSessionEventListener::HandleEvent(VBoxEventType_T aType, IEvent *aEvent) { switch (aType) { case VBoxEventType_OnGuestFileRegistered: { HRESULT rc; do { ComPtr<IGuestFileRegisteredEvent> pEvent = aEvent; Assert(!pEvent.isNull()); ComPtr<IGuestFile> pFile; CHECK_ERROR_BREAK(pEvent, COMGETTER(File)(pFile.asOutParam())); AssertBreak(!pFile.isNull()); BOOL fRegistered; CHECK_ERROR_BREAK(pEvent, COMGETTER(Registered)(&fRegistered)); Bstr strPath; CHECK_ERROR_BREAK(pFile, COMGETTER(FileName)(strPath.asOutParam())); RTPrintf("File \"%s\" %s\n", Utf8Str(strPath).c_str(), fRegistered ? "registered" : "unregistered"); if (fRegistered) { if (mfVerbose) RTPrintf("Registering ...\n"); /* Register for IGuestFile events. */ ComObjPtr<GuestFileEventListenerImpl> pListener; pListener.createObject(); CHECK_ERROR_BREAK(pListener, init(new GuestFileEventListener())); ComPtr<IEventSource> es; CHECK_ERROR_BREAK(pFile, COMGETTER(EventSource)(es.asOutParam())); com::SafeArray<VBoxEventType_T> eventTypes; eventTypes.push_back(VBoxEventType_OnGuestFileStateChanged); CHECK_ERROR_BREAK(es, RegisterListener(pListener, ComSafeArrayAsInParam(eventTypes), true /* Active listener */)); GuestFileStats fileStats(pListener); mFiles[pFile] = fileStats; } else { GuestEventFiles::iterator itFile = mFiles.find(pFile); if (itFile != mFiles.end()) { if (mfVerbose) RTPrintf("Unregistering file ...\n"); if (!itFile->first.isNull()) { /* Listener unregistration. */ ComPtr<IEventSource> pES; CHECK_ERROR(itFile->first, COMGETTER(EventSource)(pES.asOutParam())); if (!pES.isNull()) CHECK_ERROR(pES, UnregisterListener(itFile->second.mListener)); itFile->first->Release(); } mFiles.erase(itFile); } } } while (0); break; } case VBoxEventType_OnGuestProcessRegistered: { HRESULT rc; do { ComPtr<IGuestProcessRegisteredEvent> pEvent = aEvent; Assert(!pEvent.isNull()); ComPtr<IGuestProcess> pProcess; CHECK_ERROR_BREAK(pEvent, COMGETTER(Process)(pProcess.asOutParam())); AssertBreak(!pProcess.isNull()); BOOL fRegistered; CHECK_ERROR_BREAK(pEvent, COMGETTER(Registered)(&fRegistered)); Bstr strPath; CHECK_ERROR_BREAK(pProcess, COMGETTER(ExecutablePath)(strPath.asOutParam())); RTPrintf("Process \"%s\" %s\n", Utf8Str(strPath).c_str(), fRegistered ? "registered" : "unregistered"); if (fRegistered) { if (mfVerbose) RTPrintf("Registering ...\n"); /* Register for IGuestProcess events. */ ComObjPtr<GuestProcessEventListenerImpl> pListener; pListener.createObject(); CHECK_ERROR_BREAK(pListener, init(new GuestProcessEventListener())); ComPtr<IEventSource> es; CHECK_ERROR_BREAK(pProcess, COMGETTER(EventSource)(es.asOutParam())); com::SafeArray<VBoxEventType_T> eventTypes; eventTypes.push_back(VBoxEventType_OnGuestProcessStateChanged); CHECK_ERROR_BREAK(es, RegisterListener(pListener, ComSafeArrayAsInParam(eventTypes), true /* Active listener */)); GuestProcStats procStats(pListener); mProcs[pProcess] = procStats; } else { GuestEventProcs::iterator itProc = mProcs.find(pProcess); if (itProc != mProcs.end()) { if (mfVerbose) RTPrintf("Unregistering process ...\n"); if (!itProc->first.isNull()) { /* Listener unregistration. */ ComPtr<IEventSource> pES; CHECK_ERROR(itProc->first, COMGETTER(EventSource)(pES.asOutParam())); if (!pES.isNull()) CHECK_ERROR(pES, UnregisterListener(itProc->second.mListener)); itProc->first->Release(); } mProcs.erase(itProc); } } } while (0); break; } case VBoxEventType_OnGuestSessionStateChanged: { HRESULT rc; do { ComPtr<IGuestSessionStateChangedEvent> pEvent = aEvent; Assert(!pEvent.isNull()); ComPtr<IGuestSession> pSession; CHECK_ERROR_BREAK(pEvent, COMGETTER(Session)(pSession.asOutParam())); AssertBreak(!pSession.isNull()); GuestSessionStatus_T sessSts; CHECK_ERROR_BREAK(pSession, COMGETTER(Status)(&sessSts)); ULONG uID; CHECK_ERROR_BREAK(pSession, COMGETTER(Id)(&uID)); Bstr strName; CHECK_ERROR_BREAK(pSession, COMGETTER(Name)(strName.asOutParam())); RTPrintf("Session ID=%RU32 \"%s\" changed status to [%s]\n", uID, Utf8Str(strName).c_str(), gctlGuestSessionStatusToText(sessSts)); } while (0); break; } default: AssertFailed(); } return S_OK; }