HRESULT USBDeviceFilters::createDeviceFilter(const com::Utf8Str &aName, ComPtr<IUSBDeviceFilter> &aFilter) { #ifdef VBOX_WITH_USB /* the machine needs to be mutable */ AutoMutableStateDependency adep(m->pParent); if (FAILED(adep.rc())) return adep.rc(); AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); ComObjPtr<USBDeviceFilter> pFilter; pFilter.createObject(); HRESULT rc = pFilter->init(this, Bstr(aName).raw()); ComAssertComRCRetRC(rc); rc = pFilter.queryInterfaceTo(aFilter.asOutParam()); AssertComRCReturnRC(rc); return S_OK; #else NOREF(aName); NOREF(aFilter); ReturnComNotImplemented(); #endif }
HRESULT Guest::facilityUpdate(VBoxGuestFacilityType enmFacility, VBoxGuestFacilityStatus enmStatus) { ComAssertRet(enmFacility < INT32_MAX, E_INVALIDARG); HRESULT rc; RTTIMESPEC tsNow; RTTimeNow(&tsNow); FacilityMapIter it = mData.mFacilityMap.find((AdditionsFacilityType_T)enmFacility); if (it != mData.mFacilityMap.end()) { AdditionsFacility *pFac = it->second; rc = pFac->update((AdditionsFacilityStatus_T)enmStatus, tsNow); } else { ComObjPtr<AdditionsFacility> pFacility; pFacility.createObject(); ComAssert(!pFacility.isNull()); rc = pFacility->init(this, (AdditionsFacilityType_T)enmFacility, (AdditionsFacilityStatus_T)enmStatus); if (SUCCEEDED(rc)) mData.mFacilityMap.insert(std::make_pair((AdditionsFacilityType_T)enmFacility, pFacility)); } LogFlowFunc(("Returned with rc=%Rrc\n")); return rc; }
/** * Loads settings from the given machine node. * May be called once right after this object creation. * * @param aMachineNode <Machine> node. * * @note Does not lock "this" as Machine::loadHardware, which calls this, does not lock either. */ HRESULT USBDeviceFilters::i_loadSettings(const settings::USB &data) { AutoCaller autoCaller(this); AssertComRCReturnRC(autoCaller.rc()); /* Note: we assume that the default values for attributes of optional * nodes are assigned in the Data::Data() constructor and don't do it * here. It implies that this method may only be called after constructing * a new USBDeviceFilters object while all its data fields are in the default * values. Exceptions are fields whose creation time defaults don't match * values that should be applied when these fields are not explicitly set * in the settings file (for backwards compatibility reasons). This takes * place when a setting of a newly created object must default to A while * the same setting of an object loaded from the old settings file must * default to B. */ #ifdef VBOX_WITH_USB for (settings::USBDeviceFiltersList::const_iterator it = data.llDeviceFilters.begin(); it != data.llDeviceFilters.end(); ++it) { const settings::USBDeviceFilter &f = *it; ComObjPtr<USBDeviceFilter> pFilter; pFilter.createObject(); HRESULT rc = pFilter->init(this, // parent f); if (FAILED(rc)) return rc; m->llDeviceFilters->push_back(pFilter); pFilter->mInList = true; } #endif /* VBOX_WITH_USB */ return S_OK; }
HRESULT VirtualBoxErrorInfo::init(const com::ErrorInfo &info, IVirtualBoxErrorInfo *aNext) { m_resultCode = info.getResultCode(); m_resultDetail = info.getResultDetail(); m_IID = info.getInterfaceID(); m_strComponent = info.getComponent(); m_strText = info.getText(); /* Recursively create VirtualBoxErrorInfo instances for the next objects. */ const com::ErrorInfo *pInfo = info.getNext(); if (pInfo) { ComObjPtr<VirtualBoxErrorInfo> nextEI; HRESULT rc = nextEI.createObject(); if (FAILED(rc)) return rc; rc = nextEI->init(*pInfo, aNext); if (FAILED(rc)) return rc; mNext = nextEI; } else mNext = aNext; return S_OK; }
/** * Initializes the USB controller object given another guest object * (a kind of copy constructor). This object makes a private copy of data * of the original object passed as an argument. */ HRESULT USBDeviceFilters::initCopy(Machine *aParent, USBDeviceFilters *aPeer) { LogFlowThisFunc(("aParent=%p, aPeer=%p\n", aParent, aPeer)); ComAssertRet(aParent && aPeer, E_INVALIDARG); /* Enclose the state transition NotReady->InInit->Ready */ AutoInitSpan autoInitSpan(this); AssertReturn(autoInitSpan.isOk(), E_FAIL); m = new Data(aParent); /* mPeer is left null */ AutoWriteLock thatlock(aPeer COMMA_LOCKVAL_SRC_POS); #ifdef VBOX_WITH_USB /* create private copies of all filters */ m->llDeviceFilters.allocate(); DeviceFilterList::const_iterator it = aPeer->m->llDeviceFilters->begin(); while (it != aPeer->m->llDeviceFilters->end()) { ComObjPtr<USBDeviceFilter> pFilter; pFilter.createObject(); pFilter->initCopy(this, *it); m->llDeviceFilters->push_back(pFilter); ++it; } #endif /* VBOX_WITH_USB */ /* Confirm a successful initialization */ autoInitSpan.setSucceeded(); return S_OK; }
void Guest::facilityUpdate(VBoxGuestFacilityType a_enmFacility, VBoxGuestFacilityStatus a_enmStatus, uint32_t a_fFlags, PCRTTIMESPEC a_pTimeSpecTS) { AssertReturnVoid( a_enmFacility < VBoxGuestFacilityType_All && a_enmFacility > VBoxGuestFacilityType_Unknown); FacilityMapIter it = mData.mFacilityMap.find((AdditionsFacilityType_T)a_enmFacility); if (it != mData.mFacilityMap.end()) { AdditionsFacility *pFac = it->second; pFac->update((AdditionsFacilityStatus_T)a_enmStatus, a_fFlags, a_pTimeSpecTS); } else { if (mData.mFacilityMap.size() > 64) { /* The easy way out for now. We could automatically destroy inactive facilities like VMMDev does if we like... */ AssertFailedReturnVoid(); } ComObjPtr<AdditionsFacility> ptrFac; ptrFac.createObject(); AssertReturnVoid(!ptrFac.isNull()); HRESULT hrc = ptrFac->init(this, (AdditionsFacilityType_T)a_enmFacility, (AdditionsFacilityStatus_T)a_enmStatus, a_fFlags, a_pTimeSpecTS); if (SUCCEEDED(hrc)) mData.mFacilityMap.insert(std::make_pair((AdditionsFacilityType_T)a_enmFacility, ptrFac)); } }
STDMETHODIMP USBController::CreateDeviceFilter (IN_BSTR aName, IUSBDeviceFilter **aFilter) { #ifdef VBOX_WITH_USB CheckComArgOutPointerValid(aFilter); CheckComArgStrNotEmptyOrNull(aName); AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); /* the machine needs to be mutable */ AutoMutableStateDependency adep(m->pParent); if (FAILED(adep.rc())) return adep.rc(); AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); ComObjPtr<USBDeviceFilter> filter; filter.createObject(); HRESULT rc = filter->init (this, aName); ComAssertComRCRetRC (rc); rc = filter.queryInterfaceTo(aFilter); AssertComRCReturnRC(rc); return S_OK; #else NOREF(aName); NOREF(aFilter); ReturnComNotImplemented(); #endif }
/** * @interface_method_impl{PDMIPCIRAWUP,pfnPciDeviceConstructComplete} */ DECLCALLBACK(int) PCIRawDev::drvDeviceConstructComplete(PPDMIPCIRAWCONNECTOR pInterface, const char *pcszName, uint32_t uHostPCIAddress, uint32_t uGuestPCIAddress, int rc) { PDRVMAINPCIRAWDEV pThis = RT_FROM_CPP_MEMBER(pInterface, DRVMAINPCIRAWDEV, IConnector); Console *pConsole = pThis->pPCIRawDev->getParent(); const ComPtr<IMachine>& machine = pConsole->machine(); ComPtr<IVirtualBox> vbox; HRESULT hrc = machine->COMGETTER(Parent)(vbox.asOutParam()); Assert(SUCCEEDED(hrc)); ComPtr<IEventSource> es; hrc = vbox->COMGETTER(EventSource)(es.asOutParam()); Assert(SUCCEEDED(hrc)); Bstr bstrId; hrc = machine->COMGETTER(Id)(bstrId.asOutParam()); Assert(SUCCEEDED(hrc)); ComObjPtr<PCIDeviceAttachment> pda; BstrFmt bstrName(pcszName); pda.createObject(); pda->init(machine, bstrName, uHostPCIAddress, uGuestPCIAddress, TRUE); Bstr msg(""); if (RT_FAILURE(rc)) msg = BstrFmt("runtime error %Rrc", rc); fireHostPCIDevicePlugEvent(es, bstrId.raw(), true /* plugged */, RT_SUCCESS(rc) /* success */, pda, msg.raw()); return VINF_SUCCESS; }
int NetIfList(std::list <ComObjPtr<HostNetworkInterface> > &list) { char szDefaultIface[256]; int rc = getDefaultIfaceName(szDefaultIface); if (RT_FAILURE(rc)) { Log(("NetIfList: Failed to find default interface.\n")); szDefaultIface[0] = 0; } int sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock >= 0) { FILE *fp = fopen("/proc/net/dev", "r"); if (fp) { char buf[256]; while (fgets(buf, sizeof(buf), fp)) { char *pszEndOfName = strchr(buf, ':'); if (!pszEndOfName) continue; *pszEndOfName = 0; int iFirstNonWS = strspn(buf, " "); char *pszName = buf+iFirstNonWS; NETIFINFO Info; RT_ZERO(Info); rc = getInterfaceInfo(sock, pszName, &Info); if (RT_FAILURE(rc)) break; if (Info.enmMediumType == NETIF_T_ETHERNET) { ComObjPtr<HostNetworkInterface> IfObj; IfObj.createObject(); HostNetworkInterfaceType_T enmType; if (strncmp(pszName, RT_STR_TUPLE("vboxnet"))) enmType = HostNetworkInterfaceType_Bridged; else enmType = HostNetworkInterfaceType_HostOnly; if (SUCCEEDED(IfObj->init(Bstr(pszName), enmType, &Info))) { if (strcmp(pszName, szDefaultIface) == 0) list.push_front(IfObj); else list.push_back(IfObj); } } } fclose(fp); } close(sock); } else rc = VERR_INTERNAL_ERROR; return rc; }
STDMETHODIMP Guest::DirectoryRead(ULONG aHandle, IGuestDirEntry **aDirEntry) { #ifndef VBOX_WITH_GUEST_CONTROL ReturnComNotImplemented(); #else /* VBOX_WITH_GUEST_CONTROL */ using namespace guestControl; CheckComArgOutPointerValid(aDirEntry); AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); HRESULT hr = S_OK; try { GuestProcessStreamBlock streamBlock; int rc = directoryGetNextEntry(aHandle, streamBlock); if (RT_SUCCESS(rc)) { if (streamBlock.GetCount()) { ComObjPtr <GuestDirEntry> pDirEntry; hr = pDirEntry.createObject(); ComAssertComRC(hr); hr = pDirEntry->init(this, streamBlock); if (SUCCEEDED(hr)) { pDirEntry.queryInterfaceTo(aDirEntry); } else { #ifdef DEBUG streamBlock.DumpToLog(); #endif hr = VBOX_E_FILE_ERROR; } } else { /* No more directory entries to read. That's fine. */ hr = E_ABORT; /** @todo Find/define a better rc! */ } } else hr = setError(VBOX_E_IPRT_ERROR, Guest::tr("Failed getting next directory entry (%Rrc)"), rc); } catch (std::bad_alloc &) { hr = E_OUTOFMEMORY; } return hr; #endif }
/** * Initializes the system information object. * * @returns COM result indicator */ HRESULT SystemProperties::init(VirtualBox *aParent) { LogFlowThisFunc(("aParent=%p\n", aParent)); ComAssertRet(aParent, E_FAIL); /* Enclose the state transition NotReady->InInit->Ready */ AutoInitSpan autoInitSpan(this); AssertReturn(autoInitSpan.isOk(), E_FAIL); unconst(mParent) = aParent; setDefaultMachineFolder(Utf8Str::Empty); setDefaultHardDiskFormat(Utf8Str::Empty); setVRDEAuthLibrary(Utf8Str::Empty); setDefaultVRDEExtPack(Utf8Str::Empty); m->ulLogHistoryCount = 3; HRESULT rc = S_OK; /* Fetch info of all available hd backends. */ /// @todo NEWMEDIA VDBackendInfo needs to be improved to let us enumerate /// any number of backends VDBACKENDINFO aVDInfo[100]; unsigned cEntries; int vrc = VDBackendInfo(RT_ELEMENTS(aVDInfo), aVDInfo, &cEntries); AssertRC(vrc); if (RT_SUCCESS(vrc)) { for (unsigned i = 0; i < cEntries; ++ i) { ComObjPtr<MediumFormat> hdf; rc = hdf.createObject(); if (FAILED(rc)) break; rc = hdf->init(&aVDInfo[i]); if (FAILED(rc)) break; m_llMediumFormats.push_back(hdf); } } /* Confirm a successful initialization */ if (SUCCEEDED(rc)) autoInitSpan.setSucceeded(); return rc; }
int Guest::sessionCreate(const Utf8Str &strUser, const Utf8Str &strPassword, const Utf8Str &strDomain, const Utf8Str &strSessionName, ComObjPtr<GuestSession> &pGuestSession) { AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); int rc = VERR_MAX_PROCS_REACHED; if (mData.mGuestSessions.size() >= VBOX_GUESTCTRL_MAX_SESSIONS) return rc; try { /* Create a new session ID and assign it. */ uint32_t uNewSessionID = 0; uint32_t uTries = 0; for (;;) { /* Is the context ID already used? */ if (!sessionExists(uNewSessionID)) { rc = VINF_SUCCESS; break; } uNewSessionID++; if (uNewSessionID >= VBOX_GUESTCTRL_MAX_SESSIONS) uNewSessionID = 0; if (++uTries == UINT32_MAX) break; /* Don't try too hard. */ } if (RT_FAILURE(rc)) throw rc; /* Create the session object. */ HRESULT hr = pGuestSession.createObject(); if (FAILED(hr)) throw VERR_COM_UNEXPECTED; rc = pGuestSession->init(this, uNewSessionID, strUser, strPassword, strDomain, strSessionName); if (RT_FAILURE(rc)) throw rc; mData.mGuestSessions[uNewSessionID] = pGuestSession; LogFlowFunc(("Added new session (pSession=%p, ID=%RU32), now %ld sessions total\n", pGuestSession, uNewSessionID, mData.mGuestSessions.size())); } catch (int rc2) { rc = rc2; } return rc; }
int NetIfRemoveHostOnlyNetworkInterface(VirtualBox *pVirtualBox, IN_GUID aId, IProgress **aProgress) { #if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) /* create a progress object */ ComObjPtr<Progress> progress; progress.createObject(); ComPtr<IHost> host; int rc = VINF_SUCCESS; HRESULT hr = pVirtualBox->COMGETTER(Host)(host.asOutParam()); if (SUCCEEDED(hr)) { Bstr ifname; ComPtr<IHostNetworkInterface> iface; if (FAILED(host->FindHostNetworkInterfaceById(Guid(aId).toUtf16().raw(), iface.asOutParam()))) return VERR_INVALID_PARAMETER; iface->COMGETTER(Name)(ifname.asOutParam()); if (ifname.isEmpty()) return VERR_INTERNAL_ERROR; rc = progress->init(pVirtualBox, host, Bstr("Removing host network interface").raw(), FALSE /* aCancelable */); if (SUCCEEDED(rc)) { progress.queryInterfaceTo(aProgress); rc = NetIfAdpCtl(Utf8Str(ifname).c_str(), "remove", NULL, NULL); if (RT_FAILURE(rc)) progress->i_notifyComplete(E_FAIL, COM_IIDOF(IHostNetworkInterface), HostNetworkInterface::getStaticComponentName(), "Failed to execute '" VBOXNETADPCTL_NAME "' (exit status: %d)", rc); else progress->i_notifyComplete(S_OK); } } else { progress->i_notifyComplete(hr); rc = VERR_INTERNAL_ERROR; } return rc; #else NOREF(pVirtualBox); NOREF(aId); NOREF(aProgress); return VERR_NOT_IMPLEMENTED; #endif }
STDMETHODIMP VFSExplorer::Remove(ComSafeArrayIn(IN_BSTR, aNames), IProgress **aProgress) { CheckComArgSafeArrayNotNull(aNames); CheckComArgOutPointerValid(aProgress); AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); HRESULT rc = S_OK; com::SafeArray<IN_BSTR> sfaNames(ComSafeArrayInArg(aNames)); ComObjPtr<Progress> progress; try { /* Create the progress object */ progress.createObject(); rc = progress->init(mVirtualBox, static_cast<IVFSExplorer*>(this), Bstr(tr("Delete files")).raw(), TRUE /* aCancelable */); if (FAILED(rc)) throw rc; /* Initialize our worker task */ std::auto_ptr<TaskVFSExplorer> task(new TaskVFSExplorer(TaskVFSExplorer::Delete, this, progress)); /* Add all filenames to delete as task data */ for (size_t a=0; a < sfaNames.size(); ++a) task->filenames.push_back(Utf8Str(sfaNames[a])); rc = task->startThread(); if (FAILED(rc)) throw rc; /* Don't destruct on success */ task.release(); } catch (HRESULT aRC) { rc = aRC; } if (SUCCEEDED(rc)) /* Return progress to the caller */ progress.queryInterfaceTo(aProgress); return rc; }
void BusAssignmentManager::State::listAttachedPCIDevices(std::vector<ComPtr<IPCIDeviceAttachment> > &aAttached) { aAttached.resize(mPCIMap.size()); size_t i = 0; ComObjPtr<PCIDeviceAttachment> dev; for (PCIMap::const_iterator it = mPCIMap.begin(); it != mPCIMap.end(); ++it, ++i) { dev.createObject(); com::Bstr devname(it->second.szDevName); dev->init(NULL, devname, it->second.HostAddress.valid() ? it->second.HostAddress.asLong() : -1, it->first.asLong(), it->second.HostAddress.valid()); dev.queryInterfaceTo(aAttached[i].asOutParam()); } }
/** * @note Locks this object for writing, together with the peer object * represented by @a aThat (locked for reading). */ void USBController::copyFrom (USBController *aThat) { AssertReturnVoid (aThat != NULL); /* sanity */ AutoCaller autoCaller(this); AssertComRCReturnVoid (autoCaller.rc()); /* sanity too */ AutoCaller thatCaller (aThat); AssertComRCReturnVoid (thatCaller.rc()); /* even more sanity */ AutoAnyStateDependency adep(m->pParent); AssertComRCReturnVoid (adep.rc()); /* Machine::copyFrom() may not be called when the VM is running */ AssertReturnVoid (!Global::IsOnline (adep.machineState())); /* peer is not modified, lock it for reading (aThat is "master" so locked * first) */ AutoReadLock rl(aThat COMMA_LOCKVAL_SRC_POS); AutoWriteLock wl(this COMMA_LOCKVAL_SRC_POS); /* this will back up current data */ m->bd.assignCopy(aThat->m->bd); #ifdef VBOX_WITH_USB /* Note that we won't inform the USB proxy about new filters since the VM is * not running when we are here and therefore no need to do so */ /* create private copies of all filters */ m->llDeviceFilters.backup(); m->llDeviceFilters->clear(); for (DeviceFilterList::const_iterator it = aThat->m->llDeviceFilters->begin(); it != aThat->m->llDeviceFilters->end(); ++ it) { ComObjPtr<USBDeviceFilter> filter; filter.createObject(); filter->initCopy (this, *it); m->llDeviceFilters->push_back (filter); } #endif /* VBOX_WITH_USB */ }
STDMETHODIMP VFSExplorer::Update(IProgress **aProgress) { CheckComArgOutPointerValid(aProgress); AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); HRESULT rc = S_OK; ComObjPtr<Progress> progress; try { Bstr progressDesc = BstrFmt(tr("Update directory info for '%s'"), m->strPath.c_str()); /* Create the progress object */ progress.createObject(); rc = progress->init(mVirtualBox, static_cast<IVFSExplorer*>(this), progressDesc.raw(), TRUE /* aCancelable */); if (FAILED(rc)) throw rc; /* Initialize our worker task */ std::auto_ptr<TaskVFSExplorer> task(new TaskVFSExplorer(TaskVFSExplorer::Update, this, progress)); rc = task->startThread(); if (FAILED(rc)) throw rc; /* Don't destruct on success */ task.release(); } catch (HRESULT aRC) { rc = aRC; } if (SUCCEEDED(rc)) /* Return progress to the caller */ progress.queryInterfaceTo(aProgress); return rc; }
HRESULT VFSExplorer::remove(const std::vector<com::Utf8Str> &aNames, ComPtr<IProgress> &aProgress) { AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); HRESULT rc = S_OK; ComObjPtr<Progress> progress; try { /* Create the progress object */ progress.createObject(); rc = progress->init(mVirtualBox, static_cast<IVFSExplorer*>(this), Bstr(tr("Delete files")).raw(), TRUE /* aCancelable */); if (FAILED(rc)) throw rc; /* Initialize our worker task */ std::auto_ptr<TaskVFSExplorer> task(new TaskVFSExplorer(TaskVFSExplorer::Delete, this, progress)); /* Add all filenames to delete as task data */ for (size_t i = 0; i < aNames.size(); ++i) task->filenames.push_back(aNames[i]); rc = task->startThread(); if (FAILED(rc)) throw rc; /* Don't destruct on success */ task.release(); } catch (HRESULT aRC) { rc = aRC; } if (SUCCEEDED(rc)) /* Return progress to the caller */ progress.queryInterfaceTo(aProgress.asOutParam()); return rc; }
void BusAssignmentManager::State::listAttachedPCIDevices(ComSafeArrayOut(IPCIDeviceAttachment*, aAttached)) { com::SafeIfaceArray<IPCIDeviceAttachment> result(mPCIMap.size()); size_t iIndex = 0; ComObjPtr<PCIDeviceAttachment> dev; for (PCIMap::const_iterator it = mPCIMap.begin(); it != mPCIMap.end(); ++it) { dev.createObject(); com::Bstr devname(it->second.szDevName); dev->init(NULL, devname, it->second.HostAddress.valid() ? it->second.HostAddress.asLong() : -1, it->first.asLong(), it->second.HostAddress.valid()); result.setElement(iIndex++, dev); } result.detachTo(ComSafeArrayOutArg(aAttached)); }
/** * Marks the operation as complete and attaches full error info. * * See VirtualBoxBase::setError(HRESULT, const GUID &, const wchar_t * *, const char *, ...) for more info. * * @param aResultCode Operation result (error) code, must not be S_OK. * @param aIID IID of the interface that defines the error. * @param aComponent Name of the component that generates the error. * @param aText Error message (must not be null), an RTStrPrintf-like * format string in UTF-8 encoding. * @param va List of arguments for the format string. */ HRESULT Progress::i_notifyCompleteV(HRESULT aResultCode, const GUID &aIID, const char *pcszComponent, const char *aText, va_list va) { Utf8Str text(aText, va); AutoCaller autoCaller(this); AssertComRCReturnRC(autoCaller.rc()); AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); AssertReturn(mCompleted == FALSE, E_FAIL); if (mCanceled && SUCCEEDED(aResultCode)) aResultCode = E_FAIL; mCompleted = TRUE; mResultCode = aResultCode; AssertReturn(FAILED(aResultCode), E_FAIL); ComObjPtr<VirtualBoxErrorInfo> errorInfo; HRESULT rc = errorInfo.createObject(); AssertComRC(rc); if (SUCCEEDED(rc)) { errorInfo->init(aResultCode, aIID, pcszComponent, text); errorInfo.queryInterfaceTo(mErrorInfo.asOutParam()); } #if !defined VBOX_COM_INPROC /* remove from the global collection of pending progress operations */ if (mParent) mParent->i_removeProgress(mId.ref()); #endif /* wake up all waiting threads */ if (mWaitersCount > 0) RTSemEventMultiSignal(mCompletedSem); return rc; }
int GuestFile::i_setFileStatus(FileStatus_T fileStatus, int fileRc) { LogFlowThisFuncEnter(); AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); LogFlowThisFunc(("oldStatus=%RU32, newStatus=%RU32, fileRc=%Rrc\n", mData.mStatus, fileStatus, fileRc)); #ifdef VBOX_STRICT if (fileStatus == FileStatus_Error) { AssertMsg(RT_FAILURE(fileRc), ("Guest rc must be an error (%Rrc)\n", fileRc)); } else AssertMsg(RT_SUCCESS(fileRc), ("Guest rc must not be an error (%Rrc)\n", fileRc)); #endif if (mData.mStatus != fileStatus) { mData.mStatus = fileStatus; mData.mLastError = fileRc; ComObjPtr<VirtualBoxErrorInfo> errorInfo; HRESULT hr = errorInfo.createObject(); ComAssertComRC(hr); if (RT_FAILURE(fileRc)) { hr = errorInfo->initEx(VBOX_E_IPRT_ERROR, fileRc, COM_IIDOF(IGuestFile), getComponentName(), i_guestErrorToString(fileRc)); ComAssertComRC(hr); } alock.release(); /* Release lock before firing off event. */ fireGuestFileStateChangedEvent(mEventSource, mSession, this, fileStatus, errorInfo); } return VINF_SUCCESS; }
UIVirtualBoxEventHandler::UIVirtualBoxEventHandler() { // RTPrintf("Self add: %RTthrd\n", RTThreadSelf()); const CVirtualBox &vbox = vboxGlobal().virtualBox(); ComObjPtr<UIMainEventListenerImpl> pListener; pListener.createObject(); pListener->init(new UIMainEventListener(), this); m_mainEventListener = CEventListener(pListener); QVector<KVBoxEventType> events; events << KVBoxEventType_OnMachineStateChanged << KVBoxEventType_OnMachineDataChanged << KVBoxEventType_OnMachineRegistered << KVBoxEventType_OnSessionStateChanged << KVBoxEventType_OnSnapshotTaken << KVBoxEventType_OnSnapshotDeleted << KVBoxEventType_OnSnapshotChanged; vbox.GetEventSource().RegisterListener(m_mainEventListener, events, TRUE); AssertWrapperOk(vbox); connect(pListener->getWrapped(), SIGNAL(sigMachineStateChange(QString, KMachineState)), this, SIGNAL(sigMachineStateChange(QString, KMachineState)), Qt::QueuedConnection); connect(pListener->getWrapped(), SIGNAL(sigMachineDataChange(QString)), this, SIGNAL(sigMachineDataChange(QString)), Qt::QueuedConnection); connect(pListener->getWrapped(), SIGNAL(sigMachineRegistered(QString, bool)), this, SIGNAL(sigMachineRegistered(QString, bool)), Qt::QueuedConnection); connect(pListener->getWrapped(), SIGNAL(sigSessionStateChange(QString, KSessionState)), this, SIGNAL(sigSessionStateChange(QString, KSessionState)), Qt::QueuedConnection); connect(pListener->getWrapped(), SIGNAL(sigSnapshotChange(QString, QString)), this, SIGNAL(sigSnapshotChange(QString, QString)), Qt::QueuedConnection); }
int createClientListener(ComNatListenerPtr& listener, const ComVirtualBoxClientPtr& vboxclientptr, NATNetworkEventAdapter *adapter, /* const */ ComEventTypeArray& events) { ComObjPtr<NATNetworkListenerImpl> obj; HRESULT hrc = obj.createObject(); AssertComRCReturn(hrc, VERR_INTERNAL_ERROR); hrc = obj->init(new NATNetworkListener(), adapter); AssertComRCReturn(hrc, VERR_INTERNAL_ERROR); ComPtr<IEventSource> esVBox; hrc = vboxclientptr->COMGETTER(EventSource)(esVBox.asOutParam()); AssertComRCReturn(hrc, VERR_INTERNAL_ERROR); listener = obj; hrc = esVBox->RegisterListener(listener, ComSafeArrayAsInParam(events), true); AssertComRCReturn(hrc, VERR_INTERNAL_ERROR); return VINF_SUCCESS; }
/** * Process any relevant changes in the attached USB devices. * * Except for the first call, this is always running on the service thread. */ void USBProxyService::processChanges(void) { LogFlowThisFunc(("\n")); /* * Get the sorted list of USB devices. */ PUSBDEVICE pDevices = getDevices(); pDevices = sortDevices(pDevices); // get a list of all running machines while we're outside the lock // (getOpenedMachines requests higher priority locks) SessionMachinesList llOpenedMachines; mHost->parent()->getOpenedMachines(llOpenedMachines); AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); /* * Compare previous list with the new list of devices * and merge in any changes while notifying Host. */ HostUSBDeviceList::iterator it = this->mDevices.begin(); while ( it != mDevices.end() || pDevices) { ComObjPtr<HostUSBDevice> pHostDevice; if (it != mDevices.end()) pHostDevice = *it; /* * Assert that the object is still alive (we still reference it in * the collection and we're the only one who calls uninit() on it. */ AutoCaller devCaller(pHostDevice.isNull() ? NULL : pHostDevice); AssertComRC(devCaller.rc()); /* * Lock the device object since we will read/write its * properties. All Host callbacks also imply the object is locked. */ AutoWriteLock devLock(pHostDevice.isNull() ? NULL : pHostDevice COMMA_LOCKVAL_SRC_POS); /* * Compare. */ int iDiff; if (pHostDevice.isNull()) iDiff = 1; else { if (!pDevices) iDiff = -1; else iDiff = pHostDevice->compare(pDevices); } if (!iDiff) { /* * The device still there, update the state and move on. The PUSBDEVICE * structure is eaten by updateDeviceState / HostUSBDevice::updateState(). */ PUSBDEVICE pCur = pDevices; pDevices = pDevices->pNext; pCur->pPrev = pCur->pNext = NULL; bool fRunFilters = false; SessionMachine *pIgnoreMachine = NULL; devLock.release(); alock.release(); if (updateDeviceState(pHostDevice, pCur, &fRunFilters, &pIgnoreMachine)) deviceChanged(pHostDevice, (fRunFilters ? &llOpenedMachines : NULL), pIgnoreMachine); alock.acquire(); it++; } else { if (iDiff > 0) { /* * Head of pDevices was attached. */ PUSBDEVICE pNew = pDevices; pDevices = pDevices->pNext; pNew->pPrev = pNew->pNext = NULL; ComObjPtr<HostUSBDevice> NewObj; NewObj.createObject(); NewObj->init(pNew, this); Log(("USBProxyService::processChanges: attached %p {%s} %s / %p:{.idVendor=%#06x, .idProduct=%#06x, .pszProduct=\"%s\", .pszManufacturer=\"%s\"}\n", (HostUSBDevice *)NewObj, NewObj->getName().c_str(), NewObj->getStateName(), pNew, pNew->idVendor, pNew->idProduct, pNew->pszProduct, pNew->pszManufacturer)); mDevices.insert(it, NewObj); devLock.release(); alock.release(); deviceAdded(NewObj, llOpenedMachines, pNew); alock.acquire(); } else { /* * Check if the device was actually detached or logically detached * as the result of a re-enumeration. */ if (!pHostDevice->wasActuallyDetached()) it++; else { it = mDevices.erase(it); devLock.release(); alock.release(); deviceRemoved(pHostDevice); Log(("USBProxyService::processChanges: detached %p {%s}\n", (HostUSBDevice *)pHostDevice, pHostDevice->getName().c_str())); /* from now on, the object is no more valid, * uninitialize to avoid abuse */ devCaller.release(); pHostDevice->uninit(); alock.acquire(); } } } } /* while */ LogFlowThisFunc(("returns void\n")); }
int NetIfCreateHostOnlyNetworkInterface(VirtualBox *pVirtualBox, IHostNetworkInterface **aHostNetworkInterface, IProgress **aProgress, const char *pcszName) { #if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) /* create a progress object */ ComObjPtr<Progress> progress; progress.createObject(); ComPtr<IHost> host; HRESULT hrc = pVirtualBox->COMGETTER(Host)(host.asOutParam()); if (SUCCEEDED(hrc)) { hrc = progress->init(pVirtualBox, host, Bstr("Creating host only network interface").raw(), FALSE /* aCancelable */); if (SUCCEEDED(hrc)) { progress.queryInterfaceTo(aProgress); char szAdpCtl[RTPATH_MAX]; int rc = RTPathExecDir(szAdpCtl, sizeof(szAdpCtl) - sizeof("/" VBOXNETADPCTL_NAME " add")); if (RT_FAILURE(rc)) { progress->i_notifyComplete(E_FAIL, COM_IIDOF(IHostNetworkInterface), HostNetworkInterface::getStaticComponentName(), "Failed to get program path, rc=%Rrc\n", rc); return rc; } strcat(szAdpCtl, "/" VBOXNETADPCTL_NAME " "); if (pcszName && strlen(pcszName) <= RTPATH_MAX - strlen(szAdpCtl) - sizeof(" add")) { strcat(szAdpCtl, pcszName); strcat(szAdpCtl, " add"); } else strcat(szAdpCtl, "add"); if (strlen(szAdpCtl) < RTPATH_MAX - sizeof(" 2>&1")) strcat(szAdpCtl, " 2>&1"); FILE *fp = popen(szAdpCtl, "r"); if (fp) { char szBuf[128]; /* We are not interested in long error messages. */ if (fgets(szBuf, sizeof(szBuf), fp)) { /* Remove trailing new line characters. */ char *pLast = szBuf + strlen(szBuf) - 1; if (pLast >= szBuf && *pLast == '\n') *pLast = 0; if (!strncmp(VBOXNETADPCTL_NAME ":", szBuf, sizeof(VBOXNETADPCTL_NAME))) { progress->i_notifyComplete(E_FAIL, COM_IIDOF(IHostNetworkInterface), HostNetworkInterface::getStaticComponentName(), "%s", szBuf); pclose(fp); return E_FAIL; } size_t cbNameLen = strlen(szBuf) + 1; PNETIFINFO pInfo = (PNETIFINFO)RTMemAllocZ(RT_OFFSETOF(NETIFINFO, szName[cbNameLen])); if (!pInfo) rc = VERR_NO_MEMORY; else { strcpy(pInfo->szShortName, szBuf); strcpy(pInfo->szName, szBuf); rc = NetIfGetConfigByName(pInfo); if (RT_FAILURE(rc)) { progress->i_notifyComplete(E_FAIL, COM_IIDOF(IHostNetworkInterface), HostNetworkInterface::getStaticComponentName(), "Failed to get config info for %s (as reported by '" VBOXNETADPCTL_NAME " add')\n", szBuf); } else { Bstr IfName(szBuf); /* create a new uninitialized host interface object */ ComObjPtr<HostNetworkInterface> iface; iface.createObject(); iface->init(IfName, HostNetworkInterfaceType_HostOnly, pInfo); iface->i_setVirtualBox(pVirtualBox); iface.queryInterfaceTo(aHostNetworkInterface); } RTMemFree(pInfo); } if ((rc = pclose(fp)) != 0) { progress->i_notifyComplete(E_FAIL, COM_IIDOF(IHostNetworkInterface), HostNetworkInterface::getStaticComponentName(), "Failed to execute '" VBOXNETADPCTL_NAME " add' (exit status: %d)", rc); rc = VERR_INTERNAL_ERROR; } } else { /* Failed to add an interface */ rc = VERR_PERMISSION_DENIED; progress->i_notifyComplete(E_FAIL, COM_IIDOF(IHostNetworkInterface), HostNetworkInterface::getStaticComponentName(), "Failed to execute '" VBOXNETADPCTL_NAME " add' (exit status: %d). Check permissions!", rc); pclose(fp); } } if (RT_SUCCESS(rc)) progress->i_notifyComplete(rc); else hrc = E_FAIL; } } return hrc; #else NOREF(pVirtualBox); NOREF(aHostNetworkInterface); NOREF(aProgress); NOREF(pcszName); return VERR_NOT_IMPLEMENTED; #endif }
static RTEXITCODE watchdogMain(HandlerArg *a) { HRESULT rc = S_OK; do { /* Initialize global weak references. */ g_pEventQ = com::NativeEventQueue::getMainEventQueue(); /* * Install signal handlers. */ signal(SIGINT, signalHandler); #ifdef SIGBREAK signal(SIGBREAK, signalHandler); #endif /* * Setup the global event listeners: * - g_pEventSource for machine events * - g_pEventSourceClient for VBoxClient events (like VBoxSVC handling) */ CHECK_ERROR_BREAK(g_pVirtualBox, COMGETTER(EventSource)(g_pEventSource.asOutParam())); CHECK_ERROR_BREAK(g_pVirtualBoxClient, COMGETTER(EventSource)(g_pEventSourceClient.asOutParam())); ComObjPtr<VirtualBoxEventListenerImpl> vboxListenerImpl; vboxListenerImpl.createObject(); vboxListenerImpl->init(new VirtualBoxEventListener()); com::SafeArray<VBoxEventType_T> eventTypes; eventTypes.push_back(VBoxEventType_OnMachineRegistered); eventTypes.push_back(VBoxEventType_OnMachineStateChanged); eventTypes.push_back(VBoxEventType_OnVBoxSVCAvailabilityChanged); /* Processed by g_pEventSourceClient. */ g_pVBoxEventListener = vboxListenerImpl; CHECK_ERROR_BREAK(g_pEventSource, RegisterListener(g_pVBoxEventListener, ComSafeArrayAsInParam(eventTypes), true /* Active listener */)); CHECK_ERROR_BREAK(g_pEventSourceClient, RegisterListener(g_pVBoxEventListener, ComSafeArrayAsInParam(eventTypes), true /* Active listener */)); /* * Set up modules. */ int vrc = watchdogStartModules(); if (RT_FAILURE(vrc)) break; for (;;) { /* * Do the actual work. */ vrc = RTCritSectEnter(&g_csMachines); if (RT_SUCCESS(vrc)) { for (unsigned j = 0; j < RT_ELEMENTS(g_aModules); j++) if (g_aModules[j].fEnabled) { int rc2 = g_aModules[j].pDesc->pfnMain(); if (RT_FAILURE(rc2)) serviceLog("Module '%s' reported an error: %Rrc\n", g_aModules[j].pDesc->pszName, rc2); /* Keep going. */ } int rc2 = RTCritSectLeave(&g_csMachines); if (RT_SUCCESS(vrc)) vrc = rc2; AssertRC(vrc); } /* * Process pending events, then wait for new ones. Note, this * processes NULL events signalling event loop termination. */ g_pEventQ->processEventQueue(50); if (g_fCanceled) { serviceLog("Signal caught, exiting ...\n"); break; } } signal(SIGINT, SIG_DFL); #ifdef SIGBREAK signal(SIGBREAK, SIG_DFL); #endif /* VirtualBox callback unregistration. */ if (g_pVBoxEventListener) { if (!g_pEventSource.isNull()) CHECK_ERROR(g_pEventSource, UnregisterListener(g_pVBoxEventListener)); g_pVBoxEventListener.setNull(); } g_pEventSource.setNull(); g_pEventSourceClient.setNull(); vrc = watchdogShutdownModules(); AssertRC(vrc); if (RT_FAILURE(vrc)) rc = VBOX_E_IPRT_ERROR; } while (0); return SUCCEEDED(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE; }
STDMETHODIMP GuestDirectory::Read(IFsObjInfo **aInfo) { #ifndef VBOX_WITH_GUEST_CONTROL ReturnComNotImplemented(); #else LogFlowThisFuncEnter(); AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); GuestProcessStreamBlock curBlock; int guestRc; int rc = mData.mProcessTool.WaitEx(GUESTPROCESSTOOL_FLAG_STDOUT_BLOCK, &curBlock, &guestRc); /* * Note: The guest process can still be around to serve the next * upcoming stream block next time. */ if ( RT_SUCCESS(rc) && !mData.mProcessTool.IsRunning()) { rc = mData.mProcessTool.TerminatedOk(NULL /* Exit code */); if (rc == VERR_NOT_EQUAL) rc = VERR_ACCESS_DENIED; } if (RT_SUCCESS(rc)) { if (curBlock.GetCount()) /* Did we get content? */ { GuestFsObjData objData; rc = objData.FromLs(curBlock); if (RT_FAILURE(rc)) rc = VERR_PATH_NOT_FOUND; if (RT_SUCCESS(rc)) { /* Create the object. */ ComObjPtr<GuestFsObjInfo> pFsObjInfo; HRESULT hr2 = pFsObjInfo.createObject(); if (FAILED(hr2)) rc = VERR_COM_UNEXPECTED; if (RT_SUCCESS(rc)) rc = pFsObjInfo->init(objData); if (RT_SUCCESS(rc)) { /* Return info object to the caller. */ hr2 = pFsObjInfo.queryInterfaceTo(aInfo); if (FAILED(hr2)) rc = VERR_COM_UNEXPECTED; } } } else { /* Nothing to read anymore. Tell the caller. */ rc = VERR_NO_MORE_FILES; } } HRESULT hr = S_OK; if (RT_FAILURE(rc)) /** @todo Add more errors here. */ { switch (rc) { case VERR_GSTCTL_GUEST_ERROR: hr = GuestProcess::setErrorExternal(this, guestRc); break; case VERR_ACCESS_DENIED: hr = setError(VBOX_E_IPRT_ERROR, tr("Reading directory \"%s\" failed: Unable to read / access denied"), mData.mName.c_str()); break; case VERR_PATH_NOT_FOUND: hr = setError(VBOX_E_IPRT_ERROR, tr("Reading directory \"%s\" failed: Path not found"), mData.mName.c_str()); break; case VERR_NO_MORE_FILES: /* See SDK reference. */ hr = setError(VBOX_E_OBJECT_NOT_FOUND, tr("No more entries for directory \"%s\""), mData.mName.c_str()); break; default: hr = setError(VBOX_E_IPRT_ERROR, tr("Error while reading directory \"%s\": %Rrc\n"), mData.mName.c_str(), rc); break; } } LogFlowThisFunc(("Returning rc=%Rrc\n", rc)); return hr; #endif /* VBOX_WITH_GUEST_CONTROL */ }
int NetIfList(std::list <ComObjPtr<HostNetworkInterface> > &list) { int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); if (sock < 0) { Log(("NetIfList: socket() -> %d\n", errno)); return NULL; } struct ifaddrs *IfAddrs, *pAddr; int rc = getifaddrs(&IfAddrs); if (rc) { close(sock); Log(("NetIfList: getifaddrs() -> %d\n", rc)); return VERR_INTERNAL_ERROR; } PDARWINETHERNIC pEtherNICs = DarwinGetEthernetControllers(); while (pEtherNICs) { size_t cbNameLen = strlen(pEtherNICs->szName) + 1; PNETIFINFO pNew = (PNETIFINFO)RTMemAllocZ(RT_OFFSETOF(NETIFINFO, szName[cbNameLen])); pNew->MACAddress = pEtherNICs->Mac; pNew->enmMediumType = NETIF_T_ETHERNET; pNew->Uuid = pEtherNICs->Uuid; Assert(sizeof(pNew->szShortName) > sizeof(pEtherNICs->szBSDName)); memcpy(pNew->szShortName, pEtherNICs->szBSDName, sizeof(pEtherNICs->szBSDName)); pNew->szShortName[sizeof(pEtherNICs->szBSDName)] = '\0'; memcpy(pNew->szName, pEtherNICs->szName, cbNameLen); struct ifreq IfReq; RTStrCopy(IfReq.ifr_name, sizeof(IfReq.ifr_name), pNew->szShortName); if (ioctl(sock, SIOCGIFFLAGS, &IfReq) < 0) { Log(("NetIfList: ioctl(SIOCGIFFLAGS) -> %d\n", errno)); pNew->enmStatus = NETIF_S_UNKNOWN; } else pNew->enmStatus = (IfReq.ifr_flags & IFF_UP) ? NETIF_S_UP : NETIF_S_DOWN; for (pAddr = IfAddrs; pAddr != NULL; pAddr = pAddr->ifa_next) { if (strcmp(pNew->szShortName, pAddr->ifa_name)) continue; struct sockaddr_in *pIPAddr, *pIPNetMask; struct sockaddr_in6 *pIPv6Addr, *pIPv6NetMask; switch (pAddr->ifa_addr->sa_family) { case AF_INET: if (pNew->IPAddress.u) break; pIPAddr = (struct sockaddr_in *)pAddr->ifa_addr; Assert(sizeof(pNew->IPAddress) == sizeof(pIPAddr->sin_addr)); pNew->IPAddress.u = pIPAddr->sin_addr.s_addr; pIPNetMask = (struct sockaddr_in *)pAddr->ifa_netmask; Assert(pIPNetMask->sin_family == AF_INET); Assert(sizeof(pNew->IPNetMask) == sizeof(pIPNetMask->sin_addr)); pNew->IPNetMask.u = pIPNetMask->sin_addr.s_addr; break; case AF_INET6: if (pNew->IPv6Address.s.Lo || pNew->IPv6Address.s.Hi) break; pIPv6Addr = (struct sockaddr_in6 *)pAddr->ifa_addr; Assert(sizeof(pNew->IPv6Address) == sizeof(pIPv6Addr->sin6_addr)); memcpy(pNew->IPv6Address.au8, pIPv6Addr->sin6_addr.__u6_addr.__u6_addr8, sizeof(pNew->IPv6Address)); pIPv6NetMask = (struct sockaddr_in6 *)pAddr->ifa_netmask; Assert(pIPv6NetMask->sin6_family == AF_INET6); Assert(sizeof(pNew->IPv6NetMask) == sizeof(pIPv6NetMask->sin6_addr)); memcpy(pNew->IPv6NetMask.au8, pIPv6NetMask->sin6_addr.__u6_addr.__u6_addr8, sizeof(pNew->IPv6NetMask)); break; } } ComObjPtr<HostNetworkInterface> IfObj; IfObj.createObject(); if (SUCCEEDED(IfObj->init(Bstr(pEtherNICs->szName), HostNetworkInterfaceType_Bridged, pNew))) list.push_back(IfObj); RTMemFree(pNew); /* next, free current */ void *pvFree = pEtherNICs; pEtherNICs = pEtherNICs->pNext; RTMemFree(pvFree); } freeifaddrs(IfAddrs); close(sock); return VINF_SUCCESS; }
/** * Initializes a file object but does *not* open the file on the guest * yet. This is done in the dedidcated openFile call. * * @return IPRT status code. * @param pConsole Pointer to console object. * @param pSession Pointer to session object. * @param uFileID Host-based file ID (part of the context ID). * @param openInfo File opening information. */ int GuestFile::init(Console *pConsole, GuestSession *pSession, ULONG uFileID, const GuestFileOpenInfo &openInfo) { LogFlowThisFunc(("pConsole=%p, pSession=%p, uFileID=%RU32, strPath=%s\n", pConsole, pSession, uFileID, openInfo.mFileName.c_str())); AssertPtrReturn(pConsole, VERR_INVALID_POINTER); AssertPtrReturn(pSession, VERR_INVALID_POINTER); /* Enclose the state transition NotReady->InInit->Ready. */ AutoInitSpan autoInitSpan(this); AssertReturn(autoInitSpan.isOk(), VERR_OBJECT_DESTROYED); int vrc = bindToSession(pConsole, pSession, uFileID /* Object ID */); if (RT_SUCCESS(vrc)) { mSession = pSession; mData.mID = uFileID; mData.mInitialSize = 0; mData.mStatus = FileStatus_Undefined; mData.mOpenInfo = openInfo; unconst(mEventSource).createObject(); HRESULT hr = mEventSource->init(); if (FAILED(hr)) vrc = VERR_COM_UNEXPECTED; } if (RT_SUCCESS(vrc)) { try { GuestFileListener *pListener = new GuestFileListener(); ComObjPtr<GuestFileListenerImpl> thisListener; HRESULT hr = thisListener.createObject(); if (SUCCEEDED(hr)) hr = thisListener->init(pListener, this); if (SUCCEEDED(hr)) { com::SafeArray <VBoxEventType_T> eventTypes; eventTypes.push_back(VBoxEventType_OnGuestFileStateChanged); eventTypes.push_back(VBoxEventType_OnGuestFileOffsetChanged); eventTypes.push_back(VBoxEventType_OnGuestFileRead); eventTypes.push_back(VBoxEventType_OnGuestFileWrite); hr = mEventSource->RegisterListener(thisListener, ComSafeArrayAsInParam(eventTypes), TRUE /* Active listener */); if (SUCCEEDED(hr)) { vrc = baseInit(); if (RT_SUCCESS(vrc)) { mLocalListener = thisListener; } } else vrc = VERR_COM_UNEXPECTED; } else vrc = VERR_COM_UNEXPECTED; } catch(std::bad_alloc &) { vrc = VERR_NO_MEMORY; } } if (RT_SUCCESS(vrc)) { /* Confirm a successful initialization when it's the case. */ autoInitSpan.setSucceeded(); } else autoInitSpan.setFailed(); LogFlowFuncLeaveRC(vrc); return vrc; }
/** * @note Locks this object for writing, together with the peer object (also * for writing) if there is one. */ void USBController::commit() { /* sanity */ AutoCaller autoCaller(this); AssertComRCReturnVoid (autoCaller.rc()); /* sanity too */ AutoCaller peerCaller(m->pPeer); AssertComRCReturnVoid (peerCaller.rc()); /* lock both for writing since we modify both (mPeer is "master" so locked * first) */ AutoMultiWriteLock2 alock(m->pPeer, this COMMA_LOCKVAL_SRC_POS); if (m->bd.isBackedUp()) { m->bd.commit(); if (m->pPeer) { /* attach new data to the peer and reshare it */ AutoWriteLock peerlock(m->pPeer COMMA_LOCKVAL_SRC_POS); m->pPeer->m->bd.attach(m->bd); } } #ifdef VBOX_WITH_USB bool commitFilters = false; if (m->llDeviceFilters.isBackedUp()) { m->llDeviceFilters.commit(); /* apply changes to peer */ if (m->pPeer) { AutoWriteLock peerlock(m->pPeer COMMA_LOCKVAL_SRC_POS); /* commit all changes to new filters (this will reshare data with * peers for those who have peers) */ DeviceFilterList *newList = new DeviceFilterList(); DeviceFilterList::const_iterator it = m->llDeviceFilters->begin(); while (it != m->llDeviceFilters->end()) { (*it)->commit(); /* look if this filter has a peer filter */ ComObjPtr<USBDeviceFilter> peer = (*it)->peer(); if (!peer) { /* no peer means the filter is a newly created one; * create a peer owning data this filter share it with */ peer.createObject(); peer->init(m->pPeer, *it, true /* aReshare */); } else { /* remove peer from the old list */ m->pPeer->m->llDeviceFilters->remove(peer); } /* and add it to the new list */ newList->push_back (peer); ++ it; } /* uninit old peer's filters that are left */ it = m->pPeer->m->llDeviceFilters->begin(); while (it != m->pPeer->m->llDeviceFilters->end()) { (*it)->uninit(); ++ it; } /* attach new list of filters to our peer */ m->pPeer->m->llDeviceFilters.attach(newList); } else { /* we have no peer (our parent is the newly created machine); * just commit changes to filters */ commitFilters = true; } } else { /* the list of filters itself is not changed, * just commit changes to filters themselves */ commitFilters = true; } if (commitFilters) { DeviceFilterList::const_iterator it = m->llDeviceFilters->begin(); while (it != m->llDeviceFilters->end()) { (*it)->commit(); ++ it; } } #endif /* VBOX_WITH_USB */ }