STDMETHODIMP USBDeviceFilters::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> pFilter;
    pFilter.createObject();
    HRESULT rc = pFilter->init(this, aName);
    ComAssertComRCRetRC(rc);
    rc = pFilter.queryInterfaceTo(aFilter);
    AssertComRCReturnRC(rc);

    return S_OK;
#else
    NOREF(aName);
    NOREF(aFilter);
    ReturnComNotImplemented();
#endif
}
HRESULT USBDeviceFilter::setRemote(const com::Utf8Str &aRemote)
{
    /* the machine needs to be mutable */
    AutoMutableOrSavedOrRunningStateDependency adep(mParent->i_getMachine());
    if (FAILED(adep.rc())) return adep.rc();
    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    Bstr bRemote = Bstr(aRemote).raw();

    if (mData->mRemote.string() != bRemote)
    {
        Data::BOOLFilter flt = bRemote;
        ComAssertRet(!flt.isNull(), E_FAIL);
        if (!flt.isValid())
            return setError(E_INVALIDARG,
                            tr("Remote state filter string '%s' is not valid (error at position %d)"),
                            aRemote.c_str(), flt.errorPosition() + 1);

        m_fModified = true;
        ComObjPtr<Machine> pMachine = mParent->i_getMachine();

        mData.backup();
        mData->mRemote = flt;

        // leave the lock before informing callbacks
        alock.release();

        AutoWriteLock mlock(pMachine COMMA_LOCKVAL_SRC_POS);
        pMachine->i_setModified(Machine::IsModified_USB);
        mlock.release();

        return mParent->i_onDeviceFilterChange(this);
    }
    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;
}
/**
 * Handle a device which state changed in some significant way.
 *
 * This means things like running filters and subsequent capturing and
 * VM attaching. This may result in IPC and temporary lock abandonment.
 *
 * @param   aDevice         The device.
 * @param   pllOpenedMachines list of running session machines (VirtualBox::getOpenedMachines()); if NULL, we don't run filters
 * @param   aIgnoreMachine  Machine to ignore when running filters.
 */
void USBProxyService::deviceChanged(ComObjPtr<HostUSBDevice> &aDevice, SessionMachinesList *pllOpenedMachines,
                                    SessionMachine *aIgnoreMachine)
{
    /*
     * Validate preconditions.
     */
    AssertReturnVoid(!isWriteLockOnCurrentThread());
    AssertReturnVoid(!aDevice->isWriteLockOnCurrentThread());
    AutoReadLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
    LogFlowThisFunc(("aDevice=%p name={%s} state=%s id={%RTuuid} aRunFilters=%RTbool aIgnoreMachine=%p\n",
                     (HostUSBDevice *)aDevice,
                     aDevice->i_getName().c_str(),
                     aDevice->i_getStateName(),
                     aDevice->i_getId().raw(),
                     (pllOpenedMachines != NULL),       // used to be "bool aRunFilters"
                     aIgnoreMachine));
    devLock.release();

    /*
     * Run filters if requested to do so.
     */
    if (pllOpenedMachines)
    {
        HRESULT rc = runAllFiltersOnDevice(aDevice, *pllOpenedMachines, aIgnoreMachine);
        AssertComRC(rc);
    }
}
/**
 * Apply filters for the machine to all eligible USB devices.
 *
 * This is in an interface for SessionMachine::CaptureUSBDevice(), which
 * is an internal worker used by Console::AutoCaptureUSBDevices() from the
 * VM process at VM startup.
 *
 * Matching devices will be attached to the VM and may result IPC back
 * to the VM process via SessionMachine::onUSBDeviceAttach() depending
 * on whether the device needs to be captured or not. If capture is
 * required, SessionMachine::onUSBDeviceAttach() will be called
 * asynchronously by the USB proxy service thread.
 *
 * @param   aMachine        The machine to capture devices for.
 *
 * @returns COM status code, perhaps with error info.
 *
 * @remarks Temporarily locks this object, the machine object and some USB
 *          device, and the called methods will lock similar objects.
 */
HRESULT USBProxyService::autoCaptureDevicesForVM(SessionMachine *aMachine)
{
    LogFlowThisFunc(("aMachine=%p{%s}\n",
                     aMachine,
                     aMachine->i_getName().c_str()));

    /*
     * Make a copy of the list because we cannot hold the lock protecting it.
     * (This will not make copies of any HostUSBDevice objects, only reference them.)
     */
    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    HostUSBDeviceList ListCopy = mDevices;
    alock.release();

    for (HostUSBDeviceList::iterator it = ListCopy.begin();
         it != ListCopy.end();
         ++it)
    {
        ComObjPtr<HostUSBDevice> device = *it;
        AutoReadLock devLock(device COMMA_LOCKVAL_SRC_POS);
        if (   device->i_getUnistate() == kHostUSBDeviceState_HeldByProxy
            || device->i_getUnistate() == kHostUSBDeviceState_Unused
            || device->i_getUnistate() == kHostUSBDeviceState_Capturable)
        {
            devLock.release();
            runMachineFilters(aMachine, device);
        }
    }

    return S_OK;
}
HRESULT USBDeviceFilter::setActive(const BOOL aActive)
{
    /* the machine needs to be mutable */
    AutoMutableOrSavedOrRunningStateDependency adep(mParent->i_getMachine());
    if (FAILED(adep.rc())) return adep.rc();

    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);

    if (bd->mData.fActive != RT_BOOL(aActive))
    {
        m_fModified = true;
        ComObjPtr<Machine> pMachine = mParent->i_getMachine();

        bd.backup();
        bd->mData.fActive = RT_BOOL(aActive);

        // leave the lock before informing callbacks
        alock.release();

        AutoWriteLock mlock(pMachine COMMA_LOCKVAL_SRC_POS);
        pMachine->i_setModified(Machine::IsModified_USB);
        mlock.release();

        return mParent->i_onDeviceFilterChange(this, TRUE /* aActiveChanged */);
    }

    return S_OK;
}
/**
 * Performs the required actions when a device has been added.
 *
 * This means things like running filters and subsequent capturing and
 * VM attaching. This may result in IPC and temporary lock abandonment.
 *
 * @param   aDevice     The device in question.
 * @param   aUSBDevice  The USB device structure.
 */
void USBProxyService::deviceAdded(ComObjPtr<HostUSBDevice> &aDevice,
                                  SessionMachinesList &llOpenedMachines,
                                  PUSBDEVICE aUSBDevice)
{
    /*
     * Validate preconditions.
     */
    AssertReturnVoid(!isWriteLockOnCurrentThread());
    AssertReturnVoid(!aDevice->isWriteLockOnCurrentThread());
    AutoReadLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
    LogFlowThisFunc(("aDevice=%p name={%s} state=%s id={%RTuuid}\n",
                     (HostUSBDevice *)aDevice,
                     aDevice->i_getName().c_str(),
                     aDevice->i_getStateName(),
                     aDevice->i_getId().raw()));

    /*
     * Run filters on the device.
     */
    if (aDevice->i_isCapturableOrHeld())
    {
        devLock.release();
        HRESULT rc = runAllFiltersOnDevice(aDevice, llOpenedMachines, NULL /* aIgnoreMachine */);
        AssertComRC(rc);
    }

    NOREF(aUSBDevice);
}
Example #8
0
STDMETHODIMP USBDeviceFilter::COMSETTER(MaskedInterfaces) (ULONG aMaskedIfs)
{
    AutoCaller autoCaller(this);
    if (FAILED(autoCaller.rc())) return autoCaller.rc();

    /* the machine needs to be mutable */
    AutoMutableStateDependency adep(mParent->getMachine());
    if (FAILED(adep.rc())) return adep.rc();

    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);

    if (mData->mMaskedIfs != aMaskedIfs)
    {
        m_fModified = true;
        ComObjPtr<Machine> pMachine = mParent->getMachine();

        mData.backup();
        mData->mMaskedIfs = aMaskedIfs;

        // leave the lock before informing callbacks
        alock.release();

        AutoWriteLock mlock(pMachine COMMA_LOCKVAL_SRC_POS);
        pMachine->setModified(Machine::IsModified_USB);
        mlock.release();

        return mParent->onDeviceFilterChange(this);
    }

    return S_OK;
}
Example #9
0
STDMETHODIMP USBDeviceFilter::COMSETTER(Name) (IN_BSTR aName)
{
    CheckComArgStrNotEmptyOrNull(aName);

    AutoCaller autoCaller(this);
    if (FAILED(autoCaller.rc())) return autoCaller.rc();

    /* the machine needs to be mutable */
    AutoMutableStateDependency adep(mParent->getMachine());
    if (FAILED(adep.rc())) return adep.rc();

    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);

    if (mData->mName != aName)
    {
        m_fModified = true;
        ComObjPtr<Machine> pMachine = mParent->getMachine();

        mData.backup();
        mData->mName = aName;

        // leave the lock before informing callbacks
        alock.release();

        AutoWriteLock mlock(pMachine COMMA_LOCKVAL_SRC_POS);
        pMachine->setModified(Machine::IsModified_USB);
        mlock.release();

        return mParent->onDeviceFilterChange(this);
    }

    return S_OK;
}
Example #10
0
// implementation of public methods
/////////////////////////////////////////////////////////////////////////////
HRESULT Guest::createSession(const com::Utf8Str &aUser, const com::Utf8Str &aPassword, const com::Utf8Str &aDomain,
                             const com::Utf8Str &aSessionName, ComPtr<IGuestSession> &aGuestSession)

{
#ifndef VBOX_WITH_GUEST_CONTROL
    ReturnComNotImplemented();
#else /* VBOX_WITH_GUEST_CONTROL */

    LogFlowFuncEnter();

    /* Do not allow anonymous sessions (with system rights) with public API. */
    if (RT_UNLIKELY(!aUser.length()))
        return setError(E_INVALIDARG, tr("No user name specified"));

    GuestSessionStartupInfo startupInfo;
    startupInfo.mName = aSessionName;

    GuestCredentials guestCreds;
    guestCreds.mUser = aUser;
    guestCreds.mPassword = aPassword;
    guestCreds.mDomain = aDomain;

    ComObjPtr<GuestSession> pSession;
    int rc = i_sessionCreate(startupInfo, guestCreds, pSession);
    if (RT_SUCCESS(rc))
    {
        /* Return guest session to the caller. */
        HRESULT hr2 = pSession.queryInterfaceTo(aGuestSession.asOutParam());
        if (FAILED(hr2))
            rc = VERR_COM_OBJECT_NOT_FOUND;
    }

    if (RT_SUCCESS(rc))
        /* Start (fork) the session asynchronously
         * on the guest. */
        rc = pSession->i_startSessionAsync();

    HRESULT hr = S_OK;

    if (RT_FAILURE(rc))
    {
        switch (rc)
        {
            case VERR_MAX_PROCS_REACHED:
                hr = setError(VBOX_E_IPRT_ERROR, tr("Maximum number of concurrent guest sessions (%ld) reached"),
                              VBOX_GUESTCTRL_MAX_SESSIONS);
                break;

            /** @todo Add more errors here. */

            default:
                hr = setError(VBOX_E_IPRT_ERROR, tr("Could not create guest session: %Rrc"), rc);
                break;
        }
    }

    LogFlowThisFunc(("Returning rc=%Rhrc\n", hr));
    return hr;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
/**
 * Runs the USB filters of the machine on the device.
 *
 * If a match is found we will request capture for VM. This may cause
 * us to temporary abandon locks while doing IPC.
 *
 * @param   aMachine    Machine whose filters are to be run.
 * @param   aDevice     The USB device in question.
 * @returns @c true if the device has been or is being attached to the VM, @c false otherwise.
 *
 * @note    Locks several objects temporarily for reading or writing.
 */
bool USBProxyService::runMachineFilters(SessionMachine *aMachine, ComObjPtr<HostUSBDevice> &aDevice)
{
    LogFlowThisFunc(("{%s} aMachine=%p \n", aDevice->i_getName().c_str(), aMachine));

    /*
     * Validate preconditions.
     */
    AssertReturn(aMachine, false);
    AssertReturn(!isWriteLockOnCurrentThread(), false);
    AssertReturn(!aMachine->isWriteLockOnCurrentThread(), false);
    AssertReturn(!aDevice->isWriteLockOnCurrentThread(), false);
    /* Let HostUSBDevice::requestCaptureToVM() validate the state. */

    /*
     * Do the job.
     */
    ULONG ulMaskedIfs;
    if (aMachine->i_hasMatchingUSBFilter(aDevice, &ulMaskedIfs))
    {
        /* try to capture the device */
        HRESULT hrc = aDevice->i_requestCaptureForVM(aMachine, false /* aSetError */, Utf8Str(), ulMaskedIfs);
        return SUCCEEDED(hrc)
            || hrc == E_UNEXPECTED /* bad device state, give up */;
    }

    return false;
}
Example #12
0
STDMETHODIMP NetworkAdapter::COMGETTER(BandwidthGroup)(IBandwidthGroup **aBwGroup)
{
    LogFlowThisFuncEnter();
    CheckComArgOutPointerValid(aBwGroup);

    HRESULT hrc = S_OK;

    AutoCaller autoCaller(this);
    if (FAILED(autoCaller.rc())) return autoCaller.rc();

    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);

    if (mData->mBandwidthGroup.isNotEmpty())
    {
        ComObjPtr<BandwidthGroup> pBwGroup;
        hrc = mParent->getBandwidthGroup(mData->mBandwidthGroup, pBwGroup, true /* fSetError */);

        Assert(SUCCEEDED(hrc)); /* This is not allowed to fail because the existence of the group was checked when it was attached. */

        if (SUCCEEDED(hrc))
            pBwGroup.queryInterfaceTo(aBwGroup);
    }

    LogFlowThisFuncLeave();
    return hrc;
}
HRESULT USBDeviceFilter::setMaskedInterfaces(ULONG aMaskedIfs)
{
    /* the machine needs to be mutable */
    AutoMutableOrSavedOrRunningStateDependency adep(mParent->i_getMachine());
    if (FAILED(adep.rc())) return adep.rc();

    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);

    if (mData->mMaskedIfs != aMaskedIfs)
    {
        m_fModified = true;
        ComObjPtr<Machine> pMachine = mParent->i_getMachine();

        mData.backup();
        mData->mMaskedIfs = aMaskedIfs;
        // leave the lock before informing callbacks
        alock.release();

        AutoWriteLock mlock(pMachine COMMA_LOCKVAL_SRC_POS);
        pMachine->i_setModified(Machine::IsModified_USB);
        mlock.release();

        return mParent->i_onDeviceFilterChange(this);
    }

    return S_OK;
}
Example #14
0
int GuestObject::sendCommand(uint32_t uFunction,
                             uint32_t uParms, PVBOXHGCMSVCPARM paParms)
{
    LogFlowThisFuncEnter();

#ifndef VBOX_GUESTCTRL_TEST_CASE
    ComObjPtr<Console> pConsole = mObject.mConsole;
    Assert(!pConsole.isNull());

    /* Forward the information to the VMM device. */
    VMMDev *pVMMDev = pConsole->getVMMDev();
    AssertPtr(pVMMDev);

    LogFlowThisFunc(("uFunction=%RU32, uParms=%RU32\n", uFunction, uParms));
    int vrc = pVMMDev->hgcmHostCall(HGCMSERVICE_NAME, uFunction, uParms, paParms);
    if (RT_FAILURE(vrc))
    {
        /** @todo What to do here? */
    }
#else
    /* Not needed within testcases. */
    int vrc = VINF_SUCCESS;
#endif
    LogFlowFuncLeaveRC(vrc);
    return vrc;
}
Example #15
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));
    }
}
/**
 * Removes a guest control session from the internal list and destroys the session.
 *
 * @returns VBox status code.
 * @param   uSessionID          ID of the guest control session to remove.
 */
int Guest::i_sessionRemove(uint32_t uSessionID)
{
    LogFlowThisFuncEnter();

    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);

    int rc = VERR_NOT_FOUND;

    LogFlowThisFunc(("Removing session (ID=%RU32) ...\n", uSessionID));

    GuestSessions::iterator itSessions = mData.mGuestSessions.find(uSessionID);
    if (itSessions == mData.mGuestSessions.end())
        return VERR_NOT_FOUND;

    /* Make sure to consume the pointer before the one of the
     * iterator gets released. */
    ComObjPtr<GuestSession> pSession = itSessions->second;

    LogFlowThisFunc(("Removing session %RU32 (now total %ld sessions)\n",
                     uSessionID, mData.mGuestSessions.size() ? mData.mGuestSessions.size() - 1 : 0));

    rc = pSession->i_onRemove();
    mData.mGuestSessions.erase(itSessions);

    alock.release(); /* Release lock before firing off event. */

    fireGuestSessionRegisteredEvent(mEventSource, pSession, false /* Unregistered */);
    pSession.setNull();

    LogFlowFuncLeaveRC(rc);
    return rc;
}
Example #17
0
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
}
Example #18
0
/**
 *  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;
}
Example #19
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;
}
Example #20
0
/**
 *  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;
}
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;
}
int GuestDirectory::init(GuestSession *aSession,
                         const Utf8Str &strPath, const Utf8Str &strFilter /*= ""*/, uint32_t uFlags /*= 0*/)
{
    LogFlowThisFunc(("strPath=%s, strFilter=%s, uFlags=%x\n",
                     strPath.c_str(), strFilter.c_str(), uFlags));

    /* Enclose the state transition NotReady->InInit->Ready. */
    AutoInitSpan autoInitSpan(this);
    AssertReturn(autoInitSpan.isOk(), E_FAIL);

    mData.mSession = aSession;
    mData.mName    = strPath;
    mData.mFilter  = strFilter;
    mData.mFlags   = uFlags;

    /* Start the directory process on the guest. */
    GuestProcessStartupInfo procInfo;
    procInfo.mName      = Utf8StrFmt(tr("Reading directory \"%s\"", strPath.c_str()));
    procInfo.mCommand   = Utf8Str(VBOXSERVICE_TOOL_LS);
    procInfo.mTimeoutMS = 0; /* No timeout. */
    procInfo.mFlags     = ProcessCreateFlag_Hidden | ProcessCreateFlag_WaitForStdOut;

    procInfo.mArguments.push_back(Utf8Str("--machinereadable"));
    /* We want the long output format which contains all the object details. */
    procInfo.mArguments.push_back(Utf8Str("-l"));
#if 0 /* Flags are not supported yet. */
    if (uFlags & DirectoryOpenFlag_NoSymlinks)
        procInfo.mArguments.push_back(Utf8Str("--nosymlinks")); /** @todo What does GNU here? */
#endif
    /** @todo Recursion support? */
    procInfo.mArguments.push_back(strPath); /* The directory we want to open. */

    /*
     * Start the process asynchronously and keep it around so that we can use
     * it later in subsequent read() calls.
     */
    ComObjPtr<GuestProcess> pProcess;
    int rc = mData.mSession->processCreateExInteral(procInfo, pProcess);
    if (RT_SUCCESS(rc))
        rc = pProcess->startProcessAsync();

    LogFlowThisFunc(("rc=%Rrc\n", rc));

    if (RT_SUCCESS(rc))
    {
        mData.mProcess = pProcess;

        /* Confirm a successful initialization when it's the case. */
        autoInitSpan.setSucceeded();
        return rc;
    }

    autoInitSpan.setFailed();
    return rc;
}
Example #23
0
int GuestObject::callbackAdd(GuestCtrlCallback *pCallback, uint32_t *puContextID)
{
    const ComObjPtr<GuestSession> pSession(mObject.mSession);
    Assert(!pSession.isNull());
    ULONG uSessionID = 0;
    pSession->COMGETTER(Id)(&uSessionID);

    /* Create a new context ID and assign it. */
    int vrc = VERR_NOT_FOUND;

    ULONG uCount = mObject.mNextContextID++;
    ULONG uNewContextID = 0;
    ULONG uTries = 0;
    for (;;)
    {
        if (uCount == VBOX_GUESTCTRL_MAX_CONTEXTS)
            uCount = 0;

        /* Create a new context ID ... */
        uNewContextID = VBOX_GUESTCTRL_CONTEXTID_MAKE(uSessionID, mObject.mObjectID, uCount);

        /* Is the context ID already used?  Try next ID ... */
        if (!callbackExists(uCount))
        {
            /* Callback with context ID was not found. This means
             * we can use this context ID for our new callback we want
             * to add below. */
            vrc = VINF_SUCCESS;
            break;
        }

        uCount++;
        if (++uTries == UINT32_MAX)
            break; /* Don't try too hard. */
    }

    if (RT_SUCCESS(vrc))
    {
        /* Add callback with new context ID to our callback map.
         * Note: This is *not* uNewContextID (which also includes
         *       the session + process ID), just the context count
         *       will be used here. */
        mObject.mCallbacks[uCount] = pCallback;
        Assert(mObject.mCallbacks.size());

        /* Report back new context ID. */
        if (puContextID)
            *puContextID = uNewContextID;

        LogFlowThisFunc(("Added new callback (Session: %RU32, Object: %RU32, Count: %RU32) CID=%RU32\n",
                         uSessionID, mObject.mObjectID, uCount, uNewContextID));
    }

    return vrc;
}
Example #24
0
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
}
/**
 * List extension packs.
 *
 * @returns See produceList.
 * @param   pVirtualBox         Reference to the IVirtualBox smart pointer.
 */
static HRESULT listExtensionPacks(const ComPtr<IVirtualBox> &pVirtualBox)
{
    ComObjPtr<IExtPackManager> ptrExtPackMgr;
    CHECK_ERROR2_RET(pVirtualBox, COMGETTER(ExtensionPackManager)(ptrExtPackMgr.asOutParam()), hrcCheck);

    SafeIfaceArray<IExtPack> extPacks;
    CHECK_ERROR2_RET(ptrExtPackMgr, COMGETTER(InstalledExtPacks)(ComSafeArrayAsOutParam(extPacks)), hrcCheck);
    RTPrintf("Extension Packs: %u\n", extPacks.size());

    HRESULT hrc = S_OK;
    for (size_t i = 0; i < extPacks.size(); i++)
    {
        /* Read all the properties. */
        Bstr bstrName;
        CHECK_ERROR2_STMT(extPacks[i], COMGETTER(Name)(bstrName.asOutParam()),          hrc = hrcCheck; bstrName.setNull());
        Bstr bstrDesc;
        CHECK_ERROR2_STMT(extPacks[i], COMGETTER(Description)(bstrDesc.asOutParam()),   hrc = hrcCheck; bstrDesc.setNull());
        Bstr bstrVersion;
        CHECK_ERROR2_STMT(extPacks[i], COMGETTER(Version)(bstrVersion.asOutParam()),    hrc = hrcCheck; bstrVersion.setNull());
        ULONG uRevision;
        CHECK_ERROR2_STMT(extPacks[i], COMGETTER(Revision)(&uRevision),                 hrc = hrcCheck; uRevision = 0);
        Bstr bstrEdition;
        CHECK_ERROR2_STMT(extPacks[i], COMGETTER(Edition)(bstrEdition.asOutParam()),    hrc = hrcCheck; bstrEdition.setNull());
        Bstr bstrVrdeModule;
        CHECK_ERROR2_STMT(extPacks[i], COMGETTER(VRDEModule)(bstrVrdeModule.asOutParam()),hrc=hrcCheck; bstrVrdeModule.setNull());
        BOOL fUsable;
        CHECK_ERROR2_STMT(extPacks[i], COMGETTER(Usable)(&fUsable),                     hrc = hrcCheck; fUsable = FALSE);
        Bstr bstrWhy;
        CHECK_ERROR2_STMT(extPacks[i], COMGETTER(WhyUnusable)(bstrWhy.asOutParam()),    hrc = hrcCheck; bstrWhy.setNull());

        /* Display them. */
        if (i)
            RTPrintf("\n");
        RTPrintf("Pack no.%2zu:   %ls\n"
                 "Version:      %ls\n"
                 "Revision:     %u\n"
                 "Edition:      %ls\n"
                 "Description:  %ls\n"
                 "VRDE Module:  %ls\n"
                 "Usable:       %RTbool\n"
                 "Why unusable: %ls\n",
                 i, bstrName.raw(),
                 bstrVersion.raw(),
                 uRevision,
                 bstrEdition.raw(),
                 bstrDesc.raw(),
                 bstrVrdeModule.raw(),
                 fUsable != FALSE,
                 bstrWhy.raw());

        /* Query plugins and display them. */
    }
    return hrc;
}
Example #26
0
STDMETHODIMP Guest::CreateSession(IN_BSTR aUser, IN_BSTR aPassword, IN_BSTR aDomain, IN_BSTR aSessionName, IGuestSession **aGuestSession)
{
#ifndef VBOX_WITH_GUEST_CONTROL
    ReturnComNotImplemented();
#else /* VBOX_WITH_GUEST_CONTROL */

    LogFlowFuncEnter();

    /* Do not allow anonymous sessions (with system rights) with official API. */
    if (RT_UNLIKELY((aUser) == NULL || *(aUser) == '\0'))
        return setError(E_INVALIDARG, tr("No user name specified"));
    CheckComArgOutPointerValid(aGuestSession);
    /* Rest is optional. */

    AutoCaller autoCaller(this);
    if (FAILED(autoCaller.rc())) return autoCaller.rc();

    HRESULT hr = S_OK;

    ComObjPtr<GuestSession> pSession;
    int rc = sessionCreate(aUser, aPassword, aDomain, aSessionName, pSession);
    if (RT_SUCCESS(rc))
    {
        /* Return guest session to the caller. */
        HRESULT hr2 = pSession.queryInterfaceTo(aGuestSession);
        if (FAILED(hr2))
            rc = VERR_COM_OBJECT_NOT_FOUND;

        if (RT_SUCCESS(rc))
            rc = pSession->queryInfo();
    }

    if (RT_FAILURE(rc))
    {
        switch (rc)
        {
            case VERR_MAX_PROCS_REACHED:
                hr = setError(VBOX_E_IPRT_ERROR, tr("Maximum number of guest sessions (%ld) reached"),
                              VBOX_GUESTCTRL_MAX_SESSIONS);
                break;

            /** @todo Add more errors here. */

           default:
                hr = setError(VBOX_E_IPRT_ERROR, tr("Could not create guest session, rc=%Rrc"), rc);
                break;
        }
    }

    LogFlowFuncLeaveRC(rc);
    return hr;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
/**
 * 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;
}
Example #28
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 GuestDnD::hostCall(uint32_t u32Function, uint32_t cParms, PVBOXHGCMSVCPARM paParms) const
{
    Assert(!m_pGuest.isNull());
    ComObjPtr<Console> pConsole = m_pGuest->i_getConsole();

    /* Forward the information to the VMM device. */
    Assert(!pConsole.isNull());
    VMMDev *pVMMDev = pConsole->i_getVMMDev();
    if (!pVMMDev)
        return VERR_COM_OBJECT_NOT_FOUND;

    return pVMMDev->hgcmHostCall("VBoxDragAndDropSvc", u32Function, cParms, paParms);
}
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;
}