VirtualBox

Changeset 60089 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Mar 18, 2016 10:51:02 AM (9 years ago)
Author:
vboxsync
Message:

Main,VBoxManage: Add API to IHost for adding and removing USB device sources in addition to the default host one (only USB/IP backend supported so far which will be used in the future for automatic USB testing). Add support for it in VBoxManage

Location:
trunk/src/VBox
Files:
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp

    r60068 r60089  
    159159    { "convertfromraw",     USAGE_CONVERTFROMRAW,   VBMG_CMD_TODO, handleConvertFromRaw,       VBMG_CMD_F_NO_COM },
    160160    { "convertdd",          USAGE_CONVERTFROMRAW,   VBMG_CMD_TODO, handleConvertFromRaw,       VBMG_CMD_F_NO_COM },
     161    { "usbdevsource",       USAGE_USBDEVSOURCE,     VBMG_CMD_TODO, handleUSBDevSource,         0 }
    161162};
    162163
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h

    r60068 r60089  
    112112#define USAGE_ENCRYPTMEDIUM         RT_BIT_64(61)
    113113#define USAGE_MEDIUMENCCHKPWD       RT_BIT_64(62)
     114#define USAGE_USBDEVSOURCE          RT_BIT_64(63)
    114115#define USAGE_ALL                   (~(uint64_t)0)
    115116/** @} */
     
    308309/* VBoxManageUSB.cpp */
    309310RTEXITCODE handleUSBFilter(HandlerArg *a);
     311RTEXITCODE handleUSBDevSource(HandlerArg *a);
    310312
    311313/* VBoxManageHostonly.cpp */
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp

    r60068 r60089  
    13801380    }
    13811381
     1382    if (fCategory & USAGE_USBDEVSOURCE)
     1383    {
     1384        RTStrmPrintf(pStrm,
     1385                           "%s usbdevsource %s    add <source name>\n"
     1386                     "                            --backend <backend>\n"
     1387                     "                            --address <address>\n"
     1388                           "%s usbdevsource %s    remove <source name>\n"
     1389                     "\n", SEP, SEP);
     1390    }
     1391
    13821392#ifndef VBOX_ONLY_DOCS /* Converted to man page, not needed. */
    13831393    if (fCategory == USAGE_ALL)
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageUSB.cpp

    r60068 r60089  
    547547    return SUCCEEDED(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
    548548}
     549
     550RTEXITCODE handleUSBDevSource(HandlerArg *a)
     551{
     552    HRESULT rc = S_OK;
     553
     554    /* at least: 0: command, 1: source id */
     555    if (a->argc < 2)
     556        return errorSyntax(USAGE_USBDEVSOURCE, "Not enough parameters");
     557
     558    ComPtr<IHost> host;
     559    if (!strcmp(a->argv[0], "add"))
     560    {
     561        Bstr strBackend;
     562        Bstr strAddress;
     563        if (a->argc != 6)
     564            return errorSyntax(USAGE_USBDEVSOURCE, "Invalid number of parameters");
     565
     566        for (int i = 2; i < a->argc; i++)
     567        {
     568            if (!strcmp(a->argv[i], "--backend"))
     569            {
     570                i++;
     571                strBackend = a->argv[i];
     572            }
     573            else if (!strcmp(a->argv[i], "--address"))
     574            {
     575                i++;
     576                strAddress = a->argv[i];
     577            }
     578            else
     579                return errorSyntax(USAGE_USBDEVSOURCE, "Parameter \"%s\" is invalid", a->argv[i]);
     580        }
     581
     582        SafeArray<BSTR> usbSourcePropNames;
     583        SafeArray<BSTR> usbSourcePropValues;
     584
     585        CHECK_ERROR_RET(a->virtualBox, COMGETTER(Host)(host.asOutParam()), RTEXITCODE_FAILURE);
     586        CHECK_ERROR_RET(host, AddUSBDeviceSource(strBackend.raw(), Bstr(a->argv[1]).raw(), strAddress.raw(),
     587                                                 ComSafeArrayAsInParam(usbSourcePropNames), ComSafeArrayAsInParam(usbSourcePropValues)),
     588                        RTEXITCODE_FAILURE);
     589    }
     590    else if (!strcmp(a->argv[0], "remove"))
     591    {
     592        CHECK_ERROR_RET(a->virtualBox, COMGETTER(Host)(host.asOutParam()), RTEXITCODE_FAILURE);
     593        CHECK_ERROR_RET(host, RemoveUSBDeviceSource(Bstr(a->argv[1]).raw()), RTEXITCODE_FAILURE);
     594    }
     595
     596    return SUCCEEDED(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
     597}
     598
    549599/* vi: set tabstop=4 shiftwidth=4 expandtab: */
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r60068 r60089  
    86008600    uuid="afca788c-4477-787d-60b2-3fa70e56fbbc"
    86018601    wsmap="managed"
    8602     reservedMethods="2" reservedAttributes="12"
     8602    reservedMethods="0" reservedAttributes="12"
    86038603    >
    86048604    <desc>
     
    90629062      <desc>List of currently available host video capture devices.</desc>
    90639063    </attribute>
     9064
     9065    <method name="addUSBDeviceSource">
     9066      <desc>
     9067        Adds a new USB device source.
     9068      </desc>
     9069      <param name="backend" type="wstring" dir="in">
     9070        <desc>The backend to use as the new device source.</desc>
     9071      </param>
     9072      <param name="id" type="wstring" dir="in">
     9073        <desc>Unique ID to identify the source.</desc>
     9074      </param>
     9075      <param name="address" type="wstring" dir="in">
     9076        <desc>
     9077          Address to use, the format is dependent on the backend.
     9078          For USB/IP backends for example the notation is host[:port].
     9079        </desc>
     9080      </param>
     9081      <param name="propertyNames" type="wstring" safearray="yes" dir="in">
     9082        <desc>Array of property names for more detailed configuration. Not used at the moment.</desc>
     9083      </param>
     9084      <param name="propertyValues" type="wstring" safearray="yes" dir="in">
     9085        <desc>Array of property values for more detailed configuration. Not used at the moment.</desc>
     9086      </param>
     9087    </method>
     9088
     9089    <method name="removeUSBDeviceSource">
     9090      <desc>
     9091        Removes a previously added USB device source.
     9092      </desc>
     9093      <param name="id" type="wstring" dir="in">
     9094        <desc>The identifier used when the source was added.</desc>
     9095      </param>
     9096    </method>
    90649097
    90659098  </interface>
     
    1846018493        Action performed by the host when an attached USB device
    1846118494        matches this filter.
     18495      </desc>
     18496    </attribute>
     18497
     18498  </interface>
     18499
     18500
     18501  <!--
     18502  // IUSBProxyBackend
     18503  /////////////////////////////////////////////////////////////////////////
     18504  -->
     18505
     18506  <interface
     18507    name="IUSBProxyBackend" extends="$unknown"
     18508    uuid="dfe56449-6989-4002-80cf-3607f377d40c"
     18509    wsmap="managed"
     18510    reservedMethods="4" reservedAttributes="8"
     18511    >
     18512    <desc>
     18513      The USBProxyBackend interface represents a source for USB devices available
     18514      to the host for attaching to the VM.
     18515    </desc>
     18516
     18517    <attribute name="name" type="wstring" readonly="yes">
     18518      <desc>
     18519        The unique name of the proxy backend.
     18520      </desc>
     18521    </attribute>
     18522
     18523    <attribute name="type" type="wstring" readonly="yes">
     18524      <desc>
     18525        The type of the backend.
    1846218526      </desc>
    1846318527    </attribute>
  • trunk/src/VBox/Main/include/HostImpl.h

    r60068 r60089  
    145145    HRESULT generateMACAddress(com::Utf8Str &aAddress);
    146146
     147    HRESULT addUSBDeviceSource(const com::Utf8Str &aBackend, const com::Utf8Str &aId, const com::Utf8Str &aAddress,
     148                               const std::vector<com::Utf8Str> &aPropertyNames, const std::vector<com::Utf8Str> &aPropertyValues);
     149
     150    HRESULT removeUSBDeviceSource(const com::Utf8Str &aId);
     151
    147152    // Internal Methods.
    148153
  • trunk/src/VBox/Main/include/USBProxyBackend.h

    r60068 r60089  
    3030#include "VirtualBoxImpl.h"
    3131#include "HostUSBDeviceImpl.h"
     32#include "USBProxyBackendWrap.h"
    3233class USBProxyService;
    3334
     
    3536 * Base class for the USB Proxy Backend.
    3637 */
    37 class USBProxyBackend
    38     : public VirtualBoxTranslatable
    39 {
    40 public:
    41     USBProxyBackend(USBProxyService *pUsbProxyService);
    42     virtual int init(void);
    43     virtual ~USBProxyBackend();
    44 
    45     /**
    46      * Override of the default locking class to be used for validating lock
    47      * order with the standard member lock handle.
    48      */
    49     virtual VBoxLockingClass getLockingClass() const
    50     {
    51         // the USB proxy service uses the Host object lock, so return the
    52         // same locking class as the host
    53         return LOCKCLASS_HOSTOBJECT;
    54     }
     38class ATL_NO_VTABLE USBProxyBackend
     39    : public USBProxyBackendWrap
     40{
     41public:
     42
     43    DECLARE_EMPTY_CTOR_DTOR (USBProxyBackend)
     44
     45    HRESULT FinalConstruct();
     46    void FinalRelease();
     47
     48    // public initializer/uninitializer for internal purposes only
     49    virtual int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId, const com::Utf8Str &strAddress);
     50    virtual void uninit();
    5551
    5652    bool isActive(void);
    57 
    58     RWLockHandle *lockHandle() const;
     53    const com::Utf8Str &i_getId();
     54    uint32_t i_getRefCount();
    5955
    6056    /** @name Interface for the USBController and the Host object.
     
    9692    virtual PUSBDEVICE getDevices(void);
    9793    bool updateDeviceStateFake(HostUSBDevice *aDevice, PUSBDEVICE aUSBDevice, bool *aRunFilters, SessionMachine **aIgnoreMachine);
     94    uint32_t incRef();
     95    uint32_t decRef();
    9896
    9997    static HRESULT setError(HRESULT aResultCode, const char *aText, ...);
     
    104102private:
    105103
     104    // wrapped IUSBProxyBackend properties
     105    HRESULT getName(com::Utf8Str &aName);
     106    HRESULT getType(com::Utf8Str &aType);
     107
    106108    static DECLCALLBACK(int) serviceThread(RTTHREAD Thread, void *pvUser);
    107109
    108110protected:
    109111    /** Pointer to the owning USB Proxy Service object. */
    110     USBProxyService *m_pUsbProxyService;
     112    USBProxyService   *m_pUsbProxyService;
    111113    /** Thread handle of the service thread. */
    112     RTTHREAD         mThread;
     114    RTTHREAD           mThread;
    113115    /** Flag which stop() sets to cause serviceThread to return. */
    114     bool volatile    mTerminate;
     116    bool volatile      mTerminate;
     117    /** Id of the instance. */
     118    const com::Utf8Str m_strId;
     119    /** Reference counter which prevents the backend instance from being removed. */
     120    uint32_t           m_cRefs;
    115121};
    116122
     
    130136{
    131137public:
    132     USBProxyBackendDarwin(USBProxyService *pUsbProxyService);
    133     int init(void);
    134     ~USBProxyBackendDarwin();
     138    DECLARE_EMPTY_CTOR_DTOR (USBProxyBackendDarwin)
     139
     140    int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId, const com::Utf8Str &strAddress);
     141    void uninit();
    135142
    136143    virtual void *insertFilter(PCUSBFILTER aFilter);
     
    179186{
    180187public:
    181     USBProxyBackendLinux(USBProxyService *pUsbProxyService);
    182     int init(void);
    183     ~USBProxyBackendLinux();
     188    DECLARE_EMPTY_CTOR_DTOR (USBProxyBackendLinux)
     189
     190    int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId, const com::Utf8Str &strAddress);
     191    void uninit();
    184192
    185193    virtual int captureDevice(HostUSBDevice *aDevice);
     
    230238{
    231239public:
    232     USBProxyBackendOs2 (USBProxyService *pUsbProxyService);
    233     /// @todo virtual int init(void);
    234     ~USBProxyBackendOs2();
     240    DECLARE_EMPTY_CTOR_DTOR (USBProxyBackend)
    235241
    236242    virtual int captureDevice (HostUSBDevice *aDevice);
     
    272278{
    273279public:
    274     USBProxyBackendSolaris(USBProxyService *pUsbProxyService);
    275     int init(void);
    276     ~USBProxyBackendSolaris();
     280    DECLARE_EMPTY_CTOR_DTOR (USBProxyBackendSolaris)
     281
     282    int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId, const com::Utf8Str &strAddress);
     283    void uninit();
    277284
    278285    virtual void *insertFilter (PCUSBFILTER aFilter);
     
    305312{
    306313public:
    307     USBProxyBackendWindows(USBProxyService *pUsbProxyService);
    308     int init(void);
    309     ~USBProxyBackendWindows();
     314    DECLARE_EMPTY_CTOR_DTOR (USBProxyBackendWindows)
     315
     316    int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId, const com::Utf8Str &strAddress);
     317    void uninit();
    310318
    311319    virtual void *insertFilter (PCUSBFILTER aFilter);
     
    334342{
    335343public:
    336     USBProxyBackendFreeBSD(USBProxyService *pUsbProxyService);
    337     int init(void);
    338     ~USBProxyBackendFreeBSD();
     344    DECLARE_EMPTY_CTOR_DTOR (USBProxyBackendFreeBSD)
     345
     346    int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId, const com::Utf8Str &strAddress);
     347    void uninit();
    339348
    340349    virtual int captureDevice(HostUSBDevice *aDevice);
     
    369378    /** Waiting for the complete reception of a UsbIpExportedDevice structure. */
    370379    kUsbIpRecvState_ExportedDevice,
    371     /** Waiting for a complete reception a UsbIpDeviceInterface strucutre to skip. */
     380    /** Waiting for a complete reception of a UsbIpDeviceInterface structure to skip. */
    372381    kUsbIpRecvState_DeviceInterface,
    373382    /** 32bit hack. */
     
    385394{
    386395public:
    387     USBProxyBackendUsbIp(USBProxyService *pUsbProxyService);
    388     int init(void);
    389     ~USBProxyBackendUsbIp();
     396    DECLARE_EMPTY_CTOR_DTOR (USBProxyBackendUsbIp)
     397
     398    int init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId, const com::Utf8Str &strAddress);
     399    void uninit();
    390400
    391401    virtual int captureDevice(HostUSBDevice *aDevice);
  • trunk/src/VBox/Main/include/USBProxyService.h

    r60068 r60089  
    5151    }
    5252
     53    void uninit(void);
     54
    5355    bool isActive(void);
    5456    int getLastError(void);
     
    6567     * @{ */
    6668    HRESULT getDeviceCollection(std::vector<ComPtr<IHostUSBDevice> > &aUSBDevices);
     69    HRESULT addUSBDeviceSource(const com::Utf8Str &aBackend, const com::Utf8Str &aId, const com::Utf8Str &aAddress,
     70                               const std::vector<com::Utf8Str> &aPropertyNames, const std::vector<com::Utf8Str> &aPropertyValues);
     71    HRESULT removeUSBDeviceSource(const com::Utf8Str &aId);
    6772    /** @} */
    6873
     
    7883
    7984    void i_updateDeviceList(USBProxyBackend *pUsbProxyBackend, PUSBDEVICE pDevices);
    80     void i_getUSBFilters(USBDeviceFilterList *pGlobalFiltes);
     85    void i_getUSBFilters(USBDeviceFilterList *pGlobalFilters);
    8186
    8287protected:
     
    8489
    8590    static HRESULT setError(HRESULT aResultCode, const char *aText, ...);
     91
     92    USBProxyBackend *findUsbProxyBackendById(const com::Utf8Str &strId);
    8693
    8794private:
     
    94101    HostUSBDeviceList mDevices;
    95102    /** List of USBProxyBackend pointers. */
    96     typedef std::list<USBProxyBackend *> USBProxyBackendList;
     103    typedef std::list<ComObjPtr<USBProxyBackend> > USBProxyBackendList;
    97104    /** List of active USB backends. */
    98105    USBProxyBackendList mBackends;
  • trunk/src/VBox/Main/src-server/HostImpl.cpp

    r60068 r60089  
    17041704
    17051705    return S_OK;
     1706}
     1707
     1708HRESULT Host::addUSBDeviceSource(const com::Utf8Str &aBackend, const com::Utf8Str &aId, const com::Utf8Str &aAddress,
     1709                                 const std::vector<com::Utf8Str> &aPropertyNames, const std::vector<com::Utf8Str> &aPropertyValues)
     1710{
     1711#ifdef VBOX_WITH_USB
     1712    /* The USB proxy service will do the locking. */
     1713    return m->pUSBProxyService->addUSBDeviceSource(aBackend, aId, aAddress, aPropertyNames, aPropertyValues);
     1714#else
     1715    ReturnComNotImplemented();
     1716#endif
     1717}
     1718
     1719HRESULT Host::removeUSBDeviceSource(const com::Utf8Str &aId)
     1720{
     1721#ifdef VBOX_WITH_USB
     1722    /* The USB proxy service will do the locking. */
     1723    return m->pUSBProxyService->removeUSBDeviceSource(aId);
     1724#else
     1725    ReturnComNotImplemented();
     1726#endif
    17061727}
    17071728
  • trunk/src/VBox/Main/src-server/USBProxyBackend.cpp

    r60068 r60089  
    3333#include <iprt/mem.h>
    3434#include <iprt/string.h>
    35 
    36 
    37 /**
    38  * Initialize data members.
    39  */
    40 USBProxyBackend::USBProxyBackend(USBProxyService *pUsbProxyService)
    41     : m_pUsbProxyService(pUsbProxyService), mThread(NIL_RTTHREAD), mTerminate(false)
    42 {
    43     LogFlowThisFunc(("pUsbProxyService=%p\n", pUsbProxyService));
    44 }
    45 
     35#include <iprt/cpp/utils.h>
     36
     37
     38/**
     39 * Empty constructor.
     40 */
     41USBProxyBackend::USBProxyBackend()
     42{
     43    LogFlowThisFunc(("\n"));
     44}
     45
     46
     47/**
     48 * Empty destructor.
     49 */
     50USBProxyBackend::~USBProxyBackend()
     51{
     52}
     53
     54
     55HRESULT USBProxyBackend::FinalConstruct()
     56{
     57    return BaseFinalConstruct();
     58}
     59
     60void USBProxyBackend::FinalRelease()
     61{
     62    uninit();
     63    BaseFinalRelease();
     64}
    4665
    4766/**
    4867 * Stub needed as long as the class isn't virtual
    4968 */
    50 int USBProxyBackend::init(void)
    51 {
     69int USBProxyBackend::init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId, const com::Utf8Str &strAddress)
     70{
     71    NOREF(strAddress);
     72
     73    m_pUsbProxyService = pUsbProxyService;
     74    mThread            = NIL_RTTHREAD;
     75    mTerminate         = false;
     76    unconst(m_strId)   = strId;
     77    m_cRefs            = 0;
     78
    5279    return VINF_SUCCESS;
    5380}
    5481
    5582
    56 /**
    57  * Empty destructor.
    58  */
    59 USBProxyBackend::~USBProxyBackend()
     83void USBProxyBackend::uninit()
    6084{
    6185    LogFlowThisFunc(("\n"));
     
    6589}
    6690
    67 
    6891/**
    6992 * Query if the service is active and working.
     
    79102
    80103/**
    81  * We're using the Host object lock.
    82  *
    83  * This is just a temporary measure until all the USB refactoring is
    84  * done, probably... For now it help avoiding deadlocks we don't have
    85  * time to fix.
    86  *
    87  * @returns Lock handle.
    88  */
    89 RWLockHandle *USBProxyBackend::lockHandle() const
    90 {
    91     return m_pUsbProxyService->lockHandle();
     104 * Returns the ID of the instance.
     105 *
     106 * @returns ID string for the instance.
     107 */
     108const com::Utf8Str &USBProxyBackend::i_getId()
     109{
     110    return m_strId;
     111}
     112
     113
     114/**
     115 * Returns the current reference counter for the backend.
     116 */
     117uint32_t USBProxyBackend::i_getRefCount()
     118{
     119    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     120    return m_cRefs;
    92121}
    93122
     
    125154    AssertReturn(!isWriteLockOnCurrentThread(), E_FAIL);
    126155    AssertReturn(!aDevice->isWriteLockOnCurrentThread(), E_FAIL);
     156
     157    /*
     158     * Get the lists we'll iterate.
     159     */
     160    Host::USBDeviceFilterList globalFilters;
     161    m_pUsbProxyService->i_getUSBFilters(&globalFilters);
     162
    127163    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    128164    AutoWriteLock devLock(aDevice COMMA_LOCKVAL_SRC_POS);
    129165    AssertMsgReturn(aDevice->i_isCapturableOrHeld(), ("{%s} %s\n", aDevice->i_getName().c_str(),
    130166                                                      aDevice->i_getStateName()), E_FAIL);
    131 
    132     /*
    133      * Get the lists we'll iterate.
    134      */
    135     Host::USBDeviceFilterList globalFilters;
    136 
    137     m_pUsbProxyService->i_getUSBFilters(&globalFilters);
    138167
    139168    /*
     
    308337    NOREF(aDevice);
    309338    NOREF(aSuccess);
     339
     340    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     341    incRef();
    310342}
    311343
     
    350382    NOREF(aDevice);
    351383    NOREF(aSuccess);
     384
     385    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     386    decRef();
    352387}
    353388
     
    430465        LogFlowThisFunc(("not active\n"));
    431466
     467    /* Make sure there is no device from us in the list anymore. */
     468    m_pUsbProxyService->i_updateDeviceList(this, NULL);
     469
    432470    return rc;
    433471}
     
    621659}
    622660
     661/**
     662 * Increments the reference counter.
     663 *
     664 * @returns New reference count value.
     665 */
     666uint32_t USBProxyBackend::incRef()
     667{
     668    Assert(isWriteLockOnCurrentThread());
     669
     670    return ++m_cRefs;
     671}
     672
     673/**
     674 * Decrements the reference counter.
     675 *
     676 * @returns New reference count value.
     677 */
     678uint32_t USBProxyBackend::decRef()
     679{
     680    Assert(isWriteLockOnCurrentThread());
     681
     682    return --m_cRefs;
     683}
    623684
    624685/**
     
    764825}
    765826
    766 
    767 /*static*/
    768 HRESULT USBProxyBackend::setError(HRESULT aResultCode, const char *aText, ...)
    769 {
    770     va_list va;
    771     va_start(va, aText);
    772     HRESULT rc = VirtualBoxBase::setErrorInternal(aResultCode,
    773                                                     COM_IIDOF(IHost),
    774                                                     "USBProxyBackend",
    775                                                     Utf8StrFmt(aText, va),
    776                                                     false /* aWarning*/,
    777                                                     true /* aLogIt*/);
    778     va_end(va);
    779     return rc;
     827HRESULT USBProxyBackend::getName(com::Utf8Str &aName)
     828{
     829    /* strId is constant during life time, no need to lock */
     830    aName = m_strId;
     831    return S_OK;
     832}
     833
     834HRESULT USBProxyBackend::getType(com::Utf8Str &aType)
     835{
     836    aType = Utf8Str("");
     837    return S_OK;
    780838}
    781839
  • trunk/src/VBox/Main/src-server/USBProxyService.cpp

    r60068 r60089  
    3434
    3535/** Pair of a USB proxy backend and the opaque filter data assigned by the backend. */
    36 typedef std::pair<USBProxyBackend *, void *> USBFilterPair;
     36typedef std::pair<ComObjPtr<USBProxyBackend> , void *> USBFilterPair;
    3737/** List of USB filter pairs. */
    3838typedef std::list<USBFilterPair> USBFilterList;
     
    6565HRESULT USBProxyService::init(void)
    6666{
    67     USBProxyBackend *pUsbProxyBackendHost;
    6867# if defined(RT_OS_DARWIN)
    69     pUsbProxyBackendHost = new USBProxyBackendDarwin(this);
     68    ComObjPtr<USBProxyBackendDarwin> UsbProxyBackendHost;
    7069# elif defined(RT_OS_LINUX)
    71     pUsbProxyBackendHost = new USBProxyBackendLinux(this);
     70    ComObjPtr<USBProxyBackendLinux> UsbProxyBackendHost;
    7271# elif defined(RT_OS_OS2)
    73     pUsbProxyBackendHost = new USBProxyBackendOs2(this);
     72    ComObjPtr<USBProxyBackendOs2> UsbProxyBackendHost;
    7473# elif defined(RT_OS_SOLARIS)
    75     pUsbProxyBackendHost = new USBProxyBackendSolaris(this);
     74    ComObjPtr<USBProxyBackendSolaris> UsbProxyBackendHost;
    7675# elif defined(RT_OS_WINDOWS)
    77     pUsbProxyBackendHost = new USBProxyBackendWindows(this);
     76    ComObjPtr<USBProxyBackendWindows> UsbProxyBackendHost;
    7877# elif defined(RT_OS_FREEBSD)
    79     pUsbProxyBackendHost = new USBProxyBackendFreeBSD(this);
     78    ComObjPtr<USBProxyBackendFreeBSD> UsbProxyBackendHost;
    8079# else
    81     pUsbProxyBackendHost = new USBProxyBackend(this);
     80    ComObjPtr<USBProxyBackend> UsbProxyBackendHost;
    8281# endif
    83     int vrc = pUsbProxyBackendHost->init();
     82    UsbProxyBackendHost.createObject();
     83    int vrc = UsbProxyBackendHost->init(this, Utf8Str("host"), Utf8Str(""));
    8484    if (RT_FAILURE(vrc))
    8585    {
    86         delete pUsbProxyBackendHost;
    8786        mLastError = vrc;
    8887    }
    8988    else
    90         mBackends.push_back(pUsbProxyBackendHost);
    91 
    92 #if 0 /** @todo: Pass in the config. */
    93     pUsbProxyBackendHost = new USBProxyBackendUsbIp(this);
    94     hrc = pUsbProxyBackendHost->init();
    95     if (FAILED(hrc))
    96     {
    97         delete pUsbProxyBackendHost;
    98         return hrc;
    99     }
    100 #endif
     89        mBackends.push_back(static_cast<ComObjPtr<USBProxyBackend> >(UsbProxyBackendHost));
    10190
    10291    return S_OK;
     
    111100    LogFlowThisFunc(("\n"));
    112101    while (!mBackends.empty())
    113     {
    114         USBProxyBackend *pUsbProxyBackend = mBackends.front();
    115102        mBackends.pop_front();
    116         delete pUsbProxyBackend;
    117     }
    118103
    119104    mDevices.clear();
     
    221206}
    222207
     208
     209HRESULT USBProxyService::addUSBDeviceSource(const com::Utf8Str &aBackend, const com::Utf8Str &aId, const com::Utf8Str &aAddress,
     210                                            const std::vector<com::Utf8Str> &aPropertyNames, const std::vector<com::Utf8Str> &aPropertyValues)
     211{
     212    HRESULT hrc = S_OK;
     213
     214    /* Check whether the ID is used first. */
     215    for (USBProxyBackendList::iterator it = mBackends.begin();
     216         it != mBackends.end();
     217         ++it)
     218    {
     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
     247HRESULT USBProxyService::removeUSBDeviceSource(const com::Utf8Str &aId)
     248{
     249    for (USBProxyBackendList::iterator it = mBackends.begin();
     250         it != mBackends.end();
     251         ++it)
     252    {
     253        ComObjPtr<USBProxyBackend> UsbProxyBackend = *it;
     254
     255        if (aId.equals(UsbProxyBackend->i_getId()))
     256        {
     257            mBackends.erase(it);
     258            UsbProxyBackend->uninit();
     259            return S_OK;
     260        }
     261    }
     262
     263    return setError(VBOX_E_OBJECT_NOT_FOUND,
     264                    tr("The USB device source \"%s\" could not be found"), aId.c_str());
     265}
    223266
    224267/**
  • trunk/src/VBox/Main/src-server/darwin/USBProxyBackendDarwin.cpp

    r60068 r60089  
    3939 * Initialize data members.
    4040 */
    41 USBProxyBackendDarwin::USBProxyBackendDarwin(USBProxyService *aUsbProxyService)
    42     : USBProxyBackend(aUsbProxyService), mServiceRunLoopRef(NULL), mNotifyOpaque(NULL), mWaitABitNextTime(false), mUSBLibInitialized(false)
    43 {
    44     LogFlowThisFunc(("aUsbProxyService=%p\n", aUsbProxyService));
    45 }
    46 
     41USBProxyBackendDarwin::USBProxyBackendDarwin()
     42    : USBProxyBackend(), mServiceRunLoopRef(NULL), mNotifyOpaque(NULL), mWaitABitNextTime(false), mUSBLibInitialized(false)
     43{
     44}
     45
     46USBProxyBackendDarwin::~USBProxyBackendDarwin()
     47{
     48}
    4749
    4850/**
     
    5153 * @returns VBox status code.
    5254 */
    53 int USBProxyBackendDarwin::init(void)
    54 {
     55int USBProxyBackendDarwin::init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId, const com::Utf8Str &strAddress)
     56{
     57    USBProxyBackend::init(pUsbProxyService, strId, strAddress);
     58
    5559    /*
    5660     * Initialize the USB library.
     
    7377 * Stop all service threads and free the device chain.
    7478 */
    75 USBProxyBackendDarwin::~USBProxyBackendDarwin()
     79void USBProxyBackendDarwin::uninit()
    7680{
    7781    LogFlowThisFunc(("\n"));
     
    9195        mUSBLibInitialized = false;
    9296    }
     97
     98    USBProxyBackend::uninit();
    9399}
    94100
     
    155161        USBLibRemoveFilter(aDevice->i_getBackendUserData());
    156162    aDevice->i_setBackendUserData(NULL);
     163    USBProxyBackend::captureDeviceCompleted(aDevice, aSuccess);
    157164}
    158165
     
    209216        USBLibRemoveFilter(aDevice->i_getBackendUserData());
    210217    aDevice->i_setBackendUserData(NULL);
     218    USBProxyBackend::releaseDeviceCompleted(aDevice, aSuccess);
    211219}
    212220
  • trunk/src/VBox/Main/src-server/freebsd/USBProxyBackendFreeBSD.cpp

    r60068 r60089  
    6060 * Initialize data members.
    6161 */
    62 USBProxyBackendFreeBSD::USBProxyBackendFreeBSD(USBProxyService *aUsbProxyService)
    63     : USBProxyBackend(aHost)
     62USBProxyBackendFreeBSD::USBProxyBackendFreeBSD(USBProxyService *aUsbProxyService, const com::Utf8Str &strId)
     63    : USBProxyBackend(aUsbProxyService, strId)
    6464{
    6565    LogFlowThisFunc(("aUsbProxyService=%p\n", aUsbProxyService));
     
    7272 * @returns S_OK on success and non-fatal failures, some COM error otherwise.
    7373 */
    74 int USBProxyBackendFreeBSD::init(void)
    75 {
     74int USBProxyBackendFreeBSD::init(const com::Utf8Str &strAddress)
     75{
     76    NOREF(strAddress);
     77
    7678    /*
    7779     * Create semaphore.
  • trunk/src/VBox/Main/src-server/generic/USBProxyBackendUsbIp.cpp

    r60068 r60089  
    265265 * Initialize data members.
    266266 */
    267 USBProxyBackendUsbIp::USBProxyBackendUsbIp(USBProxyService *aUsbProxyService)
    268     : USBProxyBackend(aUsbProxyService)
    269 {
    270     LogFlowThisFunc(("aUsbProxyService=%p\n", aUsbProxyService));
     267USBProxyBackendUsbIp::USBProxyBackendUsbIp()
     268    : USBProxyBackend()
     269{
     270}
     271
     272USBProxyBackendUsbIp::~USBProxyBackendUsbIp()
     273{
     274
    271275}
    272276
     
    276280 * @returns S_OK on success and non-fatal failures, some COM error otherwise.
    277281 */
    278 int USBProxyBackendUsbIp::init(void)
     282int USBProxyBackendUsbIp::init(USBProxyService *aUsbProxyService, const com::Utf8Str &strId, const com::Utf8Str &strAddress)
    279283{
    280284    int rc = VINF_SUCCESS;
    281285
     286    USBProxyBackend::init(aUsbProxyService, strId, strAddress);
     287
    282288    m = new Data;
    283289
    284     /** @todo: Pass in some config like host and port to connect to. */
     290    /* Split address into hostname and port. */
     291    RTCList<RTCString> lstAddress = strAddress.split(":");
     292    if (lstAddress.size() < 1)
     293        return VERR_INVALID_PARAMETER;
     294    m->pszHost = RTStrDup(lstAddress[0].c_str());
     295    if (!m->pszHost)
     296        return VERR_NO_STR_MEMORY;
     297    if (lstAddress.size() == 2)
     298    {
     299        m->uPort = lstAddress[1].toUInt32();
     300        if (!m->uPort)
     301            return VERR_INVALID_PARAMETER;
     302    }
    285303
    286304    /* Setup wakeup pipe and poll set first. */
     
    330348 * Stop all service threads and free the device chain.
    331349 */
    332 USBProxyBackendUsbIp::~USBProxyBackendUsbIp()
     350void USBProxyBackendUsbIp::uninit()
    333351{
    334352    LogFlowThisFunc(("\n"));
     
    363381
    364382    delete m;
     383    USBProxyBackend::uninit();
    365384}
    366385
  • trunk/src/VBox/Main/src-server/linux/USBProxyBackendLinux.cpp

    r60068 r60089  
    6060 * Initialize data members.
    6161 */
    62 USBProxyBackendLinux::USBProxyBackendLinux(USBProxyService *aUsbProxyService)
    63     : USBProxyBackend(aUsbProxyService), mhFile(NIL_RTFILE), mhWakeupPipeR(NIL_RTPIPE),
    64       mhWakeupPipeW(NIL_RTPIPE), mUsingUsbfsDevices(true /* see init */),
    65       mUdevPolls(0), mpWaiter(NULL)
    66 {
    67     LogFlowThisFunc(("aUsbProxyService=%p\n", aUsbProxyService));
     62USBProxyBackendLinux::USBProxyBackendLinux()
     63    : USBProxyBackend(), mhWakeupPipeR(NIL_RTPIPE), mhWakeupPipeW(NIL_RTPIPE)
     64{
     65    LogFlowThisFunc(("\n"));
     66}
     67
     68
     69/**
     70 * Stop all service threads and free the device chain.
     71 */
     72USBProxyBackendLinux::~USBProxyBackendLinux()
     73{
     74    LogFlowThisFunc(("\n"));
    6875}
    6976
     
    7380 * @returns VBox status code.
    7481 */
    75 int USBProxyBackendLinux::init(void)
    76 {
     82int USBProxyBackendLinux::init(USBProxyService *pUsbProxyService, const com::Utf8Str &strId, const com::Utf8Str &strAddress)
     83{
     84    USBProxyBackend::init(pUsbProxyService, strId, strAddress);
     85
    7786    const char *pcszDevicesRoot;
    7887    int rc = USBProxyLinuxChooseMethod(&mUsingUsbfsDevices, &pcszDevicesRoot);
     
    8897
    8998    return rc;
     99}
     100
     101void USBProxyBackendLinux::uninit()
     102{
     103    /*
     104     * Stop the service.
     105     */
     106    if (isActive())
     107        stop();
     108
     109    /*
     110     * Free resources.
     111     */
     112    doUsbfsCleanupAsNeeded();
     113#ifdef VBOX_USB_WITH_SYSFS
     114    if (mpWaiter)
     115        delete mpWaiter;
     116#endif
     117
     118    USBProxyBackend::uninit();
    90119}
    91120
     
    179208
    180209/**
    181  * Stop all service threads and free the device chain.
    182  */
    183 USBProxyBackendLinux::~USBProxyBackendLinux()
    184 {
    185     LogFlowThisFunc(("\n"));
    186 
    187     /*
    188      * Stop the service.
    189      */
    190     if (isActive())
    191         stop();
    192 
    193     /*
    194      * Free resources.
    195      */
    196     doUsbfsCleanupAsNeeded();
    197 #ifdef VBOX_USB_WITH_SYSFS
    198     if (mpWaiter)
    199         delete mpWaiter;
    200 #endif
    201 }
    202 
    203 
    204 /**
    205210 * If any Usbfs-related resources are currently allocated, then free them
    206211 * and mark them as freed.
     
    211216     * Free resources.
    212217     */
    213     RTFileClose(mhFile);
     218    if (mhFile != NIL_RTFILE)
     219        RTFileClose(mhFile);
    214220    mhFile = NIL_RTFILE;
    215221
    216     RTPipeClose(mhWakeupPipeR);
    217     RTPipeClose(mhWakeupPipeW);
     222    if (mhWakeupPipeR != NIL_RTPIPE)
     223        RTPipeClose(mhWakeupPipeR);
     224    if (mhWakeupPipeW != NIL_RTPIPE)
     225        RTPipeClose(mhWakeupPipeW);
    218226    mhWakeupPipeW = mhWakeupPipeR = NIL_RTPIPE;
    219227}
  • trunk/src/VBox/Main/src-server/os2/USBProxyBackendOs2.cpp

    r60068 r60089  
    3838 * Initialize data members.
    3939 */
    40 USBProxyBackendOs2::USBProxyBackendOs2(USBProxyService *aUsbProxyService)
    41     : USBProxyBackend(aUsbProxyService), mhev(NULLHANDLE), mhmod(NULLHANDLE),
     40USBProxyBackendOs2::USBProxyBackendOs2(USBProxyService *aUsbProxyService, const com::Utf8Str &strId)
     41    : USBProxyBackend(aUsbProxyService, strId), mhev(NULLHANDLE), mhmod(NULLHANDLE),
    4242    mpfnUsbRegisterChangeNotification(NULL), mpfnUsbDeregisterNotification(NULL),
    4343    mpfnUsbQueryNumberDevices(NULL), mpfnUsbQueryDeviceReport(NULL)
  • trunk/src/VBox/Main/src-server/solaris/USBProxyBackendSolaris.cpp

    r60068 r60089  
    5555 * Initialize data members.
    5656 */
    57 USBProxyBackendSolaris::USBProxyBackendSolaris(USBProxyService *aUsbProxyService)
    58     : USBProxyBackend(aUsbProxyService), mUSBLibInitialized(false)
    59 {
    60     LogFlowThisFunc(("aUsbProxyService=%p\n", aUsbProxyService));
    61 }
    62 
     57USBProxyBackendSolaris::USBProxyBackendSolaris()
     58    : USBProxyBackend(), mUSBLibInitialized(false)
     59{
     60    LogFlowThisFunc(("\n"));
     61}
     62
     63USBProxyBackendSolaris::~USBProxyBackendSolaris()
     64{
     65}
    6366
    6467/**
     
    6770 * @returns VBox status code.
    6871 */
    69 int USBProxyBackendSolaris::init(void)
    70 {
     72int USBProxyBackendSolaris::init(USBProxyService *aUsbProxyService, const com::Utf8Str &strId, const com::Utf8Str &strAddress)
     73{
     74    USBProxyBackend::init(aUsbProxyService, strId, strAddress);
     75
    7176    /*
    7277     * Create semaphore.
     
    99104 * Stop all service threads and free the device chain.
    100105 */
    101 USBProxyBackendSolaris::~USBProxyBackendSolaris()
     106void USBProxyBackendSolaris::uninit()
    102107{
    103108    LogFlowThisFunc(("destruct\n"));
     
    384389        USBLibRemoveFilter(aDevice->i_getBackendUserData());
    385390    aDevice->i_setBackendUserData(NULL);
     391    USBProxyBackend::captureDeviceCompleted(aDevice, aSuccess);
    386392}
    387393
     
    439445        USBLibRemoveFilter(aDevice->i_getBackendUserData());
    440446    aDevice->i_setBackendUserData(NULL);
     447    USBProxyBackend::releaseDeviceCompleted(aDevice, aSuccess);
    441448}
    442449
  • trunk/src/VBox/Main/src-server/win/USBProxyBackendWindows.cpp

    r60068 r60089  
    3838 * Initialize data members.
    3939 */
    40 USBProxyBackendWindows::USBProxyBackendWindows(USBProxyService *aUsbProxyService)
    41     : USBProxyBackend(aUsbProxyService), mhEventInterrupt(INVALID_HANDLE_VALUE)
    42 {
    43     LogFlowThisFunc(("aUsbProxyService=%p\n", aUsbProxyService));
    44 }
    45 
     40USBProxyBackendWindows::USBProxyBackendWindows()
     41    : USBProxyBackend(), mhEventInterrupt(INVALID_HANDLE_VALUE)
     42{
     43    LogFlowThisFunc(("\n"));
     44}
     45
     46USBProxyBackendWindows::~USBProxyBackendWindows()
     47{
     48}
    4649
    4750/**
     
    5053 * @returns S_OK on success and non-fatal failures, some COM error otherwise.
    5154 */
    52 int USBProxyBackendWindows::init(void)
    53 {
     55int USBProxyBackendWindows::init(USBProxyService *aUsbProxyService, const com::Utf8Str &strId, const com::Utf8Str &strAddress)
     56{
     57    USBProxyBackend::init(aUsbProxyService, strId, strAddress);
     58
    5459    /*
    5560     * Create the semaphore (considered fatal).
     
    8893 * Stop all service threads and free the device chain.
    8994 */
    90 USBProxyBackendWindows::~USBProxyBackendWindows()
     95void USBProxyBackendWindows::uninit()
    9196{
    9297    LogFlowThisFunc(("\n"));
     
    107112    int rc = USBLibTerm();
    108113    AssertRC(rc);
     114    USBProxyBackend::uninit();
    109115}
    110116
  • trunk/src/VBox/Main/testcase/Makefile.kmk

    r60068 r60089  
    208208tstUSBProxyLinux_SOURCES   = \
    209209        tstUSBProxyLinux.cpp \
    210         ../src-server/linux/USBProxyBackendLinux.cpp \
    211210        ../src-server/linux/USBGetDevices.cpp
    212211tstUSBProxyLinux_INCS      = \
  • trunk/src/VBox/Main/testcase/tstUSBProxyLinux.cpp

    r60068 r60089  
    2121*********************************************************************************************************************************/
    2222
    23 #include "USBProxyBackend.h"
    2423#include "USBGetDevices.h"
    2524
     
    3130
    3231/*** BEGIN STUBS ***/
    33 
    34 USBProxyBackend::USBProxyBackend(USBProxyService*) {}
    35 USBProxyBackend::~USBProxyBackend() {}
    36 int USBProxyBackend::init() { return VINF_SUCCESS; }
    37 int USBProxyBackend::start() { return VINF_SUCCESS; }
    38 int USBProxyBackend::stop() { return VINF_SUCCESS; }
    39 RWLockHandle *USBProxyBackend::lockHandle() const { return NULL; }
    40 void *USBProxyBackend::insertFilter(USBFILTER const*) { return NULL; }
    41 void USBProxyBackend::removeFilter(void*) {}
    42 int USBProxyBackend::captureDevice(HostUSBDevice*) { return VINF_SUCCESS; }
    43 void USBProxyBackend::captureDeviceCompleted(HostUSBDevice*, bool) {}
    44 void USBProxyBackend::detachingDevice(HostUSBDevice*) {}
    45 int USBProxyBackend::releaseDevice(HostUSBDevice*) { return VINF_SUCCESS; }
    46 void USBProxyBackend::releaseDeviceCompleted(HostUSBDevice*, bool) {}
    47 void USBProxyBackend::serviceThreadInit() {}
    48 void USBProxyBackend::serviceThreadTerm() {}
    49 int USBProxyBackend::wait(unsigned int) { return VINF_SUCCESS; }
    50 int USBProxyBackend::interruptWait() { return VINF_SUCCESS; }
    51 PUSBDEVICE USBProxyBackend::getDevices() { return NULL; }
    52 void USBProxyBackend::deviceAdded(ComObjPtr<HostUSBDevice> &aDevice, SessionMachinesList &llOpenedMachines, PUSBDEVICE aUSBDevice) {}
    53 void USBProxyBackend::deviceRemoved(ComObjPtr<HostUSBDevice> &aDevice) {}
    54 void USBProxyBackend::deviceChanged(ComObjPtr<HostUSBDevice> &aDevice, SessionMachinesList*, SessionMachine*) {}
    55 bool USBProxyBackend::updateDeviceState(HostUSBDevice*, USBDEVICE*, bool*, SessionMachine**) { return true; }
    56 bool USBProxyBackend::updateDeviceStateFake(HostUSBDevice*, USBDEVICE*, bool*, SessionMachine**) { return true; }
    57 bool USBProxyBackend::isActive() { return true; }
    58 
    59 VBoxMainHotplugWaiter::VBoxMainHotplugWaiter(char const*) {}
    60 
    61 com::Utf8Str HostUSBDevice::i_getName()
    62 {
    63     return Utf8Str();
    64 }
    65 
    66 void SysFreeString(BSTR bstr)
    67 {
    68     Assert(0);
    69 }
    7032
    7133static struct
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