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 (bd->mData.ulMaskedInterfaces != aMaskedIfs)
    {
        m_fModified = true;
        ComObjPtr<Machine> pMachine = mParent->i_getMachine();

        bd.backup();
        bd->mData.ulMaskedInterfaces = 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;
}
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;
}
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 (bd->mRemote.string() != bRemote)
    {
        BackupableUSBDeviceFilterData::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();

        bd.backup();
        bd->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 USBDeviceFilter::setName(const com::Utf8Str &aName)
{
    /* 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->mName != aName)
    {
        m_fModified = true;
        ComObjPtr<Machine> pMachine = mParent->i_getMachine();

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

        // 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;
}
/**
 *  Generic USB filter field setter, expects UTF-8 input.
 *
 *  @param  aIdx    The field index.
 *  @param  aStr    The new value.
 *
 *  @return COM status.
 */
HRESULT USBDeviceFilter::i_usbFilterFieldSetter(USBFILTERIDX aIdx,
                                                const com::Utf8Str &strNew)
{
    /* 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);


    com::Utf8Str strOld;
    i_usbFilterFieldToString(&bd->mUSBFilter, aIdx, strOld);
    if (strOld != strNew)
    {
        m_fModified = true;
        ComObjPtr<Machine> pMachine = mParent->i_getMachine();

        bd.backup();

        com::Utf8Str errStr;
        HRESULT rc = i_usbFilterFieldFromString(&bd->mUSBFilter, aIdx, strNew, errStr);
        if (FAILED(rc))
        {
            bd.rollback();
            return setError(rc, "%s", errStr.c_str());
        }

        // 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;
}