VirtualBox

Changeset 60107 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Mar 19, 2016 10:22:46 AM (9 years ago)
Author:
vboxsync
Message:

Main/USBProxyService: Save any additional USB device sources in the global configuration and load them during startup

Location:
trunk/src/VBox/Main
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r60089 r60107  
    571571      <!--
    572572          Machine changes: NVMe storage controller.
     573          VirtualBox.xml: Add support for additional USB device sources (e.g. USB/IP)
    573574      -->
    574575    </const>
  • trunk/src/VBox/Main/include/USBProxyBackend.h

    r60089 r60107  
    2626#include <iprt/poll.h>
    2727#include <iprt/semaphore.h>
     28#include <iprt/cpp/utils.h>
    2829
    2930#include "VirtualBoxBase.h"
     
    5253    bool isActive(void);
    5354    const com::Utf8Str &i_getId();
     55    const com::Utf8Str &i_getAddress();
     56    virtual const com::Utf8Str &i_getBackend();
    5457    uint32_t i_getRefCount();
    5558
     
    117120    /** Id of the instance. */
    118121    const com::Utf8Str m_strId;
     122    /** Address of the instance. */
     123    const com::Utf8Str m_strAddress;
     124    /** Backend identifier as used in the settings. */
     125    const com::Utf8Str m_strBackend;
    119126    /** Reference counter which prevents the backend instance from being removed. */
    120127    uint32_t           m_cRefs;
     
    140147    int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId, const com::Utf8Str &strAddress);
    141148    void uninit();
     149
     150    const com::Utf8Str &i_getBackend();
    142151
    143152    virtual void *insertFilter(PCUSBFILTER aFilter);
  • trunk/src/VBox/Main/include/USBProxyService.h

    r60089 r60107  
    2222#include <VBox/usb.h>
    2323#include <VBox/usbfilter.h>
     24#include <VBox/settings.h>
    2425
    2526#include "VirtualBoxBase.h"
     
    8586    void i_getUSBFilters(USBDeviceFilterList *pGlobalFilters);
    8687
     88    HRESULT i_loadSettings(const settings::USBDeviceSourcesList &llUSBDeviceSources);
     89    HRESULT i_saveSettings(settings::USBDeviceSourcesList &llUSBDeviceSources);
     90
    8791protected:
    8892    ComObjPtr<HostUSBDevice> findDeviceById(IN_GUID aId);
     
    9195
    9296    USBProxyBackend *findUsbProxyBackendById(const com::Utf8Str &strId);
     97
     98    HRESULT createUSBDeviceSource(const com::Utf8Str &aBackend, const com::Utf8Str &aId,
     99                                  const com::Utf8Str &aAddress, const std::vector<com::Utf8Str> &aPropertyNames,
     100                                  const std::vector<com::Utf8Str> &aPropertyValues);
    93101
    94102private:
  • trunk/src/VBox/Main/src-server/HostImpl.cpp

    r60089 r60107  
    17611761        }
    17621762    }
     1763
     1764    rc = m->pUSBProxyService->i_loadSettings(data.llUSBDeviceSources);
    17631765#else
    17641766    NOREF(data);
     
    17911793#endif /* VBOX_WITH_USB */
    17921794
    1793     return S_OK;
     1795    return m->pUSBProxyService->i_saveSettings(data.llUSBDeviceSources);
    17941796}
    17951797
  • trunk/src/VBox/Main/src-server/USBProxyBackend.cpp

    r60089 r60107  
    3333#include <iprt/mem.h>
    3434#include <iprt/string.h>
    35 #include <iprt/cpp/utils.h>
    3635
    3736
     
    6968int USBProxyBackend::init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId, const com::Utf8Str &strAddress)
    7069{
    71     NOREF(strAddress);
    72 
    73     m_pUsbProxyService = pUsbProxyService;
    74     mThread            = NIL_RTTHREAD;
    75     mTerminate         = false;
    76     unconst(m_strId)   = strId;
    77     m_cRefs            = 0;
     70    m_pUsbProxyService    = pUsbProxyService;
     71    mThread               = NIL_RTTHREAD;
     72    mTerminate            = false;
     73    unconst(m_strId)      = strId;
     74    m_cRefs               = 0;
     75    unconst(m_strAddress) = strAddress;
     76
     77    unconst(m_strBackend) = Utf8Str::Empty;
    7878
    7979    return VINF_SUCCESS;
     
    111111}
    112112
     113
     114/**
     115 * Returns the address of the instance.
     116 *
     117 * @returns ID string for the instance.
     118 */
     119const com::Utf8Str &USBProxyBackend::i_getAddress()
     120{
     121    return m_strAddress;
     122}
     123
     124
     125/**
     126 * Returns the backend of the instance.
     127 *
     128 * @returns ID string for the instance.
     129 */
     130const com::Utf8Str &USBProxyBackend::i_getBackend()
     131{
     132    return m_strBackend;
     133}
    113134
    114135/**
  • trunk/src/VBox/Main/src-server/USBProxyService.cpp

    r60089 r60107  
    210210                                            const std::vector<com::Utf8Str> &aPropertyNames, const std::vector<com::Utf8Str> &aPropertyValues)
    211211{
    212     HRESULT hrc = S_OK;
    213 
    214     /* Check whether the ID is used first. */
     212    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     213
     214    HRESULT hrc = createUSBDeviceSource(aBackend, aId, aAddress, aPropertyNames, aPropertyValues);
     215    if (SUCCEEDED(hrc))
     216    {
     217        alock.release();
     218        AutoWriteLock vboxLock(mHost->i_parent() COMMA_LOCKVAL_SRC_POS);
     219        return mHost->i_parent()->i_saveSettings();
     220    }
     221
     222    return hrc;
     223}
     224
     225HRESULT USBProxyService::removeUSBDeviceSource(const com::Utf8Str &aId)
     226{
     227    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     228
    215229    for (USBProxyBackendList::iterator it = mBackends.begin();
    216230         it != mBackends.end();
    217231         ++it)
    218232    {
    219         USBProxyBackend *pUsbProxyBackend = *it;
    220 
    221         if (aId.equals(pUsbProxyBackend->i_getId()))
    222             return setError(VBOX_E_OBJECT_IN_USE,
    223                             tr("The USB device source \"%s\" exists already"), aId.c_str());
    224     }
    225 
    226     /* Create appropriate proxy backend. */
    227     if (aBackend.equalsIgnoreCase("USBIP"))
    228     {
    229         ComObjPtr<USBProxyBackendUsbIp> UsbProxyBackend;
    230 
    231         UsbProxyBackend.createObject();
    232         int vrc = UsbProxyBackend->init(this, aId, aAddress);
    233         if (RT_FAILURE(vrc))
    234             hrc = setError(E_FAIL,
    235                            tr("Creating the USB device source \"%s\" using backend \"%s\" failed with %Rrc"),
    236                            aId.c_str(), aBackend.c_str(), vrc);
    237         else
    238             mBackends.push_back(static_cast<ComObjPtr<USBProxyBackend> >(UsbProxyBackend));
    239     }
    240     else
    241         hrc = setError(VBOX_E_OBJECT_NOT_FOUND,
    242                        tr("The USB backend \"%s\" is not supported"), aBackend.c_str());
    243 
    244     return hrc;
    245 }
    246 
    247 HRESULT USBProxyService::removeUSBDeviceSource(const com::Utf8Str &aId)
    248 {
    249     for (USBProxyBackendList::iterator it = mBackends.begin();
    250          it != mBackends.end();
    251          ++it)
    252     {
    253233        ComObjPtr<USBProxyBackend> UsbProxyBackend = *it;
    254234
     
    257237            mBackends.erase(it);
    258238            UsbProxyBackend->uninit();
    259             return S_OK;
     239
     240            alock.release();
     241            AutoWriteLock vboxLock(mHost->i_parent() COMMA_LOCKVAL_SRC_POS);
     242            return mHost->i_parent()->i_saveSettings();
    260243        }
    261244    }
     
    712695
    713696/**
     697 * Loads the given settings and constructs the additional USB device sources.
     698 *
     699 * @returns COM status code.
     700 * @param   llUSBDeviceSources    The list of additional device sources.
     701 */
     702HRESULT USBProxyService::i_loadSettings(const settings::USBDeviceSourcesList &llUSBDeviceSources)
     703{
     704    HRESULT hrc = S_OK;
     705
     706    for (settings::USBDeviceSourcesList::const_iterator it = llUSBDeviceSources.begin();
     707         it != llUSBDeviceSources.end() && SUCCEEDED(hrc);
     708         ++it)
     709    {
     710        std::vector<com::Utf8Str> vecPropNames, vecPropValues;
     711        const settings::USBDeviceSource &src = *it;
     712        hrc = createUSBDeviceSource(src.strBackend, src.strName, src.strAddress, vecPropNames, vecPropValues);
     713    }
     714
     715    return hrc;
     716}
     717
     718/**
     719 * Saves the additional device sources in the given settings.
     720 *
     721 * @returns COM status code.
     722 * @param   llUSBDeviceSources    The list of additional device sources.
     723 */
     724HRESULT USBProxyService::i_saveSettings(settings::USBDeviceSourcesList &llUSBDeviceSources)
     725{
     726    for (USBProxyBackendList::iterator it = mBackends.begin();
     727         it != mBackends.end();
     728         ++it)
     729    {
     730        USBProxyBackend *pUsbProxyBackend = *it;
     731
     732        /* Host backends are not saved as they are always created during startup. */
     733        if (!pUsbProxyBackend->i_getBackend().equals("host"))
     734        {
     735            settings::USBDeviceSource src;
     736
     737            src.strBackend = pUsbProxyBackend->i_getBackend();
     738            src.strName    = pUsbProxyBackend->i_getId();
     739            src.strAddress = pUsbProxyBackend->i_getAddress();
     740
     741            llUSBDeviceSources.push_back(src);
     742        }
     743    }
     744
     745    return S_OK;
     746}
     747
     748/**
    714749 * Searches the list of devices (mDevices) for the given device.
    715750 *
     
    732767
    733768    return Dev;
     769}
     770
     771/**
     772 * Creates a new USB device source.
     773 *
     774 * @returns COM status code.
     775 * @param   aBackend          The backend to use.
     776 * @param   aId               The ID of the source.
     777 * @param   aAddress          The backend specific address.
     778 * @param   aPropertyNames    Vector of optional property keys the backend supports.
     779 * @param   aPropertyValues   Vector of optional property values the backend supports.
     780 */
     781HRESULT USBProxyService::createUSBDeviceSource(const com::Utf8Str &aBackend, const com::Utf8Str &aId,
     782                                               const com::Utf8Str &aAddress, const std::vector<com::Utf8Str> &aPropertyNames,
     783                                               const std::vector<com::Utf8Str> &aPropertyValues)
     784{
     785    HRESULT hrc = S_OK;
     786
     787    AssertReturn(isWriteLockOnCurrentThread(), E_FAIL);
     788
     789    /* Check whether the ID is used first. */
     790    for (USBProxyBackendList::iterator it = mBackends.begin();
     791         it != mBackends.end();
     792         ++it)
     793    {
     794        USBProxyBackend *pUsbProxyBackend = *it;
     795
     796        if (aId.equals(pUsbProxyBackend->i_getId()))
     797            return setError(VBOX_E_OBJECT_IN_USE,
     798                            tr("The USB device source \"%s\" exists already"), aId.c_str());
     799    }
     800
     801    /* Create appropriate proxy backend. */
     802    if (aBackend.equalsIgnoreCase("USBIP"))
     803    {
     804        ComObjPtr<USBProxyBackendUsbIp> UsbProxyBackend;
     805
     806        UsbProxyBackend.createObject();
     807        int vrc = UsbProxyBackend->init(this, aId, aAddress);
     808        if (RT_FAILURE(vrc))
     809            hrc = setError(E_FAIL,
     810                           tr("Creating the USB device source \"%s\" using backend \"%s\" failed with %Rrc"),
     811                           aId.c_str(), aBackend.c_str(), vrc);
     812        else
     813            mBackends.push_back(static_cast<ComObjPtr<USBProxyBackend> >(UsbProxyBackend));
     814    }
     815    else
     816        hrc = setError(VBOX_E_OBJECT_NOT_FOUND,
     817                       tr("The USB backend \"%s\" is not supported"), aBackend.c_str());
     818
     819    return hrc;
    734820}
    735821
  • trunk/src/VBox/Main/src-server/darwin/USBProxyBackendDarwin.cpp

    r60089 r60107  
    5757    USBProxyBackend::init(pUsbProxyService, strId, strAddress);
    5858
     59    unconst(m_strBackend) = Utf8Str("host");
     60
    5961    /*
    6062     * Initialize the USB library.
  • trunk/src/VBox/Main/src-server/freebsd/USBProxyBackendFreeBSD.cpp

    r60089 r60107  
    7272 * @returns S_OK on success and non-fatal failures, some COM error otherwise.
    7373 */
    74 int USBProxyBackendFreeBSD::init(const com::Utf8Str &strAddress)
    75 {
    76     NOREF(strAddress);
     74int USBProxyBackendFreeBSD::init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId, const com::Utf8Str &strAddresss)
     75{
     76    USBProxyBackend::init(pUsbProxyService, strId, strAddress);
     77
     78    unconst(m_strBackend) = Utf8Str("host");
    7779
    7880    /*
  • trunk/src/VBox/Main/src-server/generic/USBProxyBackendUsbIp.cpp

    r60089 r60107  
    286286    USBProxyBackend::init(aUsbProxyService, strId, strAddress);
    287287
     288    unconst(m_strBackend) = Utf8Str("USBIP");
     289
    288290    m = new Data;
    289291
     
    327329                    int rc2 = RTPollSetDestroy(m->hPollSet);
    328330                    AssertRC(rc2);
     331                    m->hPollSet = NIL_RTPOLLSET;
    329332                }
    330333            }
     
    336339                rc2 = RTPipeClose(m->hWakeupPipeW);
    337340                AssertRC(rc2);
     341                m->hWakeupPipeR = m->hWakeupPipeW = NIL_RTPIPE;
    338342            }
    339343        }
    340344        if (RT_FAILURE(rc))
     345        {
    341346            RTSemFastMutexDestroy(m->hMtxDevices);
     347            m->hMtxDevices = NIL_RTSEMFASTMUTEX;
     348        }
    342349    }
    343350
     
    888895    /* Make sure the Bus id is 0 terminated. */
    889896    pDev->szBusId[31] = '\0';
    890     RTStrAPrintf((char **)&pNew->pszAddress, "usbip://%s:%u:%s", m->pszHost, m->uPort, &pDev->szBusId[0]);
    891 
    892     pNew->idVendor           = pDev->u16VendorId;
    893     pNew->idProduct          = pDev->u16ProductId;
    894     pNew->bcdDevice          = pDev->u16BcdDevice;
    895     pNew->bDeviceClass       = pDev->bDeviceClass;
    896     pNew->bDeviceSubClass    = pDev->bDeviceSubClass;
    897     pNew->bDeviceProtocol    = pDev->bDeviceProtocol;
    898     pNew->bNumConfigurations = pDev->bNumConfigurations;
    899     pNew->enmState           = USBDEVICESTATE_USED_BY_HOST_CAPTURABLE;
    900     pNew->u64SerialHash      = 0;
    901     pNew->bBus               = (uint8_t)pDev->u32BusNum;
    902     pNew->bPort              = (uint8_t)pDev->u32DevNum;
    903 
    904     switch (pDev->u32Speed)
    905     {
    906         case USBIP_SPEED_LOW:
    907             pNew->enmSpeed = USBDEVICESPEED_LOW;
    908             pNew->bcdUSB = 1 << 8;
    909             break;
    910         case USBIP_SPEED_FULL:
    911             pNew->enmSpeed = USBDEVICESPEED_FULL;
    912             pNew->bcdUSB = 1 << 8;
    913             break;
    914         case USBIP_SPEED_HIGH:
    915             pNew->enmSpeed = USBDEVICESPEED_HIGH;
    916             pNew->bcdUSB = 2 << 8;
    917             break;
    918         case USBIP_SPEED_WIRELESS:
    919             pNew->enmSpeed = USBDEVICESPEED_VARIABLE;
    920             pNew->bcdUSB = 1 << 8;
    921             break;
    922         case USBIP_SPEED_SUPER:
    923             pNew->enmSpeed = USBDEVICESPEED_SUPER;
    924             pNew->bcdUSB = 3 << 8;
    925             break;
    926         case USBIP_SPEED_UNKNOWN:
    927         default:
    928             pNew->bcdUSB = 1 << 8;
    929             pNew->enmSpeed = USBDEVICESPEED_UNKNOWN;
    930     }
    931 
    932     /* link it */
    933     pNew->pNext = NULL;
    934     pNew->pPrev = *m->ppNext;
    935     *m->ppNext = pNew;
    936     m->ppNext = &pNew->pNext;
    937     m->cDevicesCur++;
    938 
    939     return VINF_SUCCESS;
     897    int rc = RTStrAPrintf((char **)&pNew->pszAddress, "usbip://%s:%u:%s", m->pszHost, m->uPort, &pDev->szBusId[0]);
     898    if (RT_SUCCESS(rc))
     899    {
     900        pNew->idVendor           = pDev->u16VendorId;
     901        pNew->idProduct          = pDev->u16ProductId;
     902        pNew->bcdDevice          = pDev->u16BcdDevice;
     903        pNew->bDeviceClass       = pDev->bDeviceClass;
     904        pNew->bDeviceSubClass    = pDev->bDeviceSubClass;
     905        pNew->bDeviceProtocol    = pDev->bDeviceProtocol;
     906        pNew->bNumConfigurations = pDev->bNumConfigurations;
     907        pNew->enmState           = USBDEVICESTATE_USED_BY_HOST_CAPTURABLE;
     908        pNew->u64SerialHash      = 0;
     909        pNew->bBus               = (uint8_t)pDev->u32BusNum;
     910        pNew->bPort              = (uint8_t)pDev->u32DevNum;
     911
     912        switch (pDev->u32Speed)
     913        {
     914            case USBIP_SPEED_LOW:
     915                pNew->enmSpeed = USBDEVICESPEED_LOW;
     916                pNew->bcdUSB = 1 << 8;
     917                break;
     918            case USBIP_SPEED_FULL:
     919                pNew->enmSpeed = USBDEVICESPEED_FULL;
     920                pNew->bcdUSB = 1 << 8;
     921                break;
     922            case USBIP_SPEED_HIGH:
     923                pNew->enmSpeed = USBDEVICESPEED_HIGH;
     924                pNew->bcdUSB = 2 << 8;
     925                break;
     926            case USBIP_SPEED_WIRELESS:
     927                pNew->enmSpeed = USBDEVICESPEED_VARIABLE;
     928                pNew->bcdUSB = 1 << 8;
     929                break;
     930            case USBIP_SPEED_SUPER:
     931                pNew->enmSpeed = USBDEVICESPEED_SUPER;
     932                pNew->bcdUSB = 3 << 8;
     933                break;
     934            case USBIP_SPEED_UNKNOWN:
     935            default:
     936                pNew->bcdUSB = 1 << 8;
     937                pNew->enmSpeed = USBDEVICESPEED_UNKNOWN;
     938        }
     939
     940        /* link it */
     941        pNew->pNext = NULL;
     942        pNew->pPrev = *m->ppNext;
     943        *m->ppNext = pNew;
     944        m->ppNext = &pNew->pNext;
     945        m->cDevicesCur++;
     946    }
     947
     948    if (RT_FAILURE(rc))
     949    {
     950        if (pNew->pszManufacturer)
     951            RTStrFree((char *)pNew->pszManufacturer);
     952        if (pNew->pszProduct)
     953            RTStrFree((char *)pNew->pszProduct);
     954        if (pNew->pszBackend)
     955            RTStrFree((char *)pNew->pszBackend);
     956        if (pNew->pszAddress)
     957            RTStrFree((char *)pNew->pszAddress);
     958        RTMemFree(pNew);
     959    }
     960
     961    return rc;
    940962}
    941963
  • trunk/src/VBox/Main/src-server/linux/USBProxyBackendLinux.cpp

    r60106 r60107  
    8484    USBProxyBackend::init(pUsbProxyService, strId, strAddress);
    8585
     86    unconst(m_strBackend) = Utf8Str("host");
     87
    8688    const char *pcszDevicesRoot;
    8789    int rc = USBProxyLinuxChooseMethod(&mUsingUsbfsDevices, &pcszDevicesRoot);
     
    118120    USBProxyBackend::uninit();
    119121}
     122
    120123
    121124/**
  • trunk/src/VBox/Main/src-server/solaris/USBProxyBackendSolaris.cpp

    r60089 r60107  
    7373{
    7474    USBProxyBackend::init(aUsbProxyService, strId, strAddress);
     75
     76    unconst(m_strBackend) = Utf8Str("host");
    7577
    7678    /*
  • trunk/src/VBox/Main/src-server/win/USBProxyBackendWindows.cpp

    r60089 r60107  
    5757    USBProxyBackend::init(aUsbProxyService, strId, strAddress);
    5858
     59    unconst(m_strBackend) = Utf8Str("host");
     60
    5961    /*
    6062     * Create the semaphore (considered fatal).
  • trunk/src/VBox/Main/xml/Settings.cpp

    r58437 r60107  
    15061506
    15071507/**
     1508 * Creates \<USBDeviceSource\> nodes under the given parent element according to
     1509 * the contents of the given USBDeviceSourcesList.
     1510 *
     1511 * @param elmParent
     1512 * @param ll
     1513 */
     1514void MainConfigFile::buildUSBDeviceSources(xml::ElementNode &elmParent,
     1515                                           const USBDeviceSourcesList &ll)
     1516{
     1517    for (USBDeviceSourcesList::const_iterator it = ll.begin();
     1518         it != ll.end();
     1519         ++it)
     1520    {
     1521        const USBDeviceSource &src = *it;
     1522        xml::ElementNode *pelmSource = elmParent.createChild("USBDeviceSource");
     1523        pelmSource->setAttribute("name", src.strName);
     1524        pelmSource->setAttribute("backend", src.strBackend);
     1525        pelmSource->setAttribute("address", src.strAddress);
     1526
     1527        /* Write the properties. */
     1528        for (StringsMap::const_iterator itProp = src.properties.begin();
     1529             itProp != src.properties.end();
     1530             ++itProp)
     1531        {
     1532            xml::ElementNode *pelmProp = pelmSource->createChild("Property");
     1533            pelmProp->setAttribute("name", itProp->first);
     1534            pelmProp->setAttribute("value", itProp->second);
     1535        }
     1536    }
     1537}
     1538
     1539/**
     1540 * Reads \<USBDeviceFilter\> entries from under the given elmDeviceFilters node and
     1541 * stores them in the given linklist. This is in ConfigFileBase because it's used
     1542 * from both MainConfigFile (for host filters) and MachineConfigFile (for machine
     1543 * filters).
     1544 * @param elmDeviceFilters
     1545 * @param ll
     1546 */
     1547void MainConfigFile::readUSBDeviceSources(const xml::ElementNode &elmDeviceSources,
     1548                                          USBDeviceSourcesList &ll)
     1549{
     1550    xml::NodesLoop nl1(elmDeviceSources, "USBDeviceSource");
     1551    const xml::ElementNode *pelmChild;
     1552    while ((pelmChild = nl1.forAllNodes()))
     1553    {
     1554        USBDeviceSource src;
     1555
     1556        if (   pelmChild->getAttributeValue("name", src.strName)
     1557            && pelmChild->getAttributeValue("backend", src.strBackend)
     1558            && pelmChild->getAttributeValue("address", src.strAddress))
     1559        {
     1560            // handle medium properties
     1561            xml::NodesLoop nl2(*pelmChild, "Property");
     1562            const xml::ElementNode *pelmSrcChild;
     1563            while ((pelmSrcChild = nl2.forAllNodes()))
     1564            {
     1565                Utf8Str strPropName, strPropValue;
     1566                if (   pelmSrcChild->getAttributeValue("name", strPropName)
     1567                    && pelmSrcChild->getAttributeValue("value", strPropValue) )
     1568                    src.properties[strPropName] = strPropValue;
     1569                else
     1570                    throw ConfigFileError(this, pelmSrcChild, N_("Required USBDeviceSource/Property/@name or @value attribute is missing"));
     1571            }
     1572
     1573            ll.push_back(src);
     1574        }
     1575    }
     1576}
     1577
     1578/**
    15081579 * Constructor.
    15091580 *
     
    15741645                    else if (pelmGlobalChild->nameEquals("USBDeviceFilters"))
    15751646                        readUSBDeviceFilters(*pelmGlobalChild, host.llUSBDeviceFilters);
     1647                    else if (pelmGlobalChild->nameEquals("USBDeviceSources"))
     1648                        readUSBDeviceSources(*pelmGlobalChild, host.llUSBDeviceSources);
    15761649                }
    15771650            } // end if (pelmRootChild->nameEquals("Global"))
     
    16081681void MainConfigFile::bumpSettingsVersionIfNeeded()
    16091682{
     1683    if (m->sv < SettingsVersion_v1_16)
     1684    {
     1685        // VirtualBox 5.1 add support for additional USB device sources.
     1686        if (!host.llUSBDeviceSources.empty())
     1687            m->sv = SettingsVersion_v1_16;
     1688    }
     1689
    16101690    if (m->sv < SettingsVersion_v1_14)
    16111691    {
     
    17801860                          host.llUSBDeviceFilters,
    17811861                          true);               // fHostMode
     1862
     1863    if (!host.llUSBDeviceSources.empty())
     1864        buildUSBDeviceSources(*pelmGlobal->createChild("USBDeviceSources"),
     1865                              host.llUSBDeviceSources);
    17821866
    17831867    // now go write the XML
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette