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
}
Exemple #2
0
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;
}
Exemple #6
0
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
}
Exemple #8
0
/**
 * @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;
}
Exemple #12
0
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;
}
Exemple #18
0
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));
}
Exemple #20
0
/**
 * 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);
}
Exemple #23
0
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;
}
Exemple #24
0
/**
 * 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 */
}