VirtualBox

Changeset 48631 in vbox for trunk/src/VBox/Main/src-client


Ignore:
Timestamp:
Sep 23, 2013 10:46:00 AM (11 years ago)
Author:
vboxsync
Message:

Main: EmulatedUSB callback, detach device.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-client/EmulatedUSBImpl.cpp

    r48423 r48631  
    1717 */
    1818
     19#define LOG_GROUP_MAIN_OVERRIDE LOG_GROUP_MAIN_EMULATEDUSB
     20
    1921#include "EmulatedUSBImpl.h"
    2022#include "ConsoleImpl.h"
     
    4143        int32_t volatile mcRefs;
    4244
     45        EmulatedUSB *mpEmulatedUSB;
     46
    4347        RTUUID mUuid;
     48        char mszUuid[RTUUID_STR_LENGTH];
    4449
    4550        Utf8Str mPath;
     
    6267            :
    6368            mcRefs(1),
     69            mpEmulatedUSB(NULL),
    6470            enmStatus(EUSBDEVICE_CREATED)
    6571        {
    6672            RT_ZERO(mUuid);
     73            RT_ZERO(mszUuid);
    6774        }
    6875
     
    8289
    8390        HRESULT Initialize(Console *pConsole,
     91                           EmulatedUSB *pEmulatedUSB,
    8492                           const com::Utf8Str *aPath,
    8593                           const com::Utf8Str *aSettings);
     
    8997                       PUVM pUVM);
    9098
     99        bool HasId(const char *pszId) { return RTStrCmp(pszId, mszUuid) == 0;}
     100
    91101        EUSBDEVICESTATUS enmStatus;
    92102};
     
    102112    for (it = pThis->mDevSettings.begin(); it != pThis->mDevSettings.end(); ++it)
    103113        CFGMR3InsertString(pConfig, it->first.c_str(), it->second.c_str());
     114    PCFGMNODE pEUSB;
     115    CFGMR3InsertNode(pConfig,       "EmulatedUSB", &pEUSB);
     116    CFGMR3InsertString(pEUSB,         "Id", pThis->mszUuid);
     117    CFGMR3InsertInteger(pEUSB,        "pfnCallback", (uintptr_t)EmulatedUSB::eusbCallback);
     118    CFGMR3InsertInteger(pEUSB,        "pvCallback", (uintptr_t)pThis->mpEmulatedUSB);
    104119
    105120    PCFGMNODE pLunL0;
     
    112127
    113128    int rc = PDMR3UsbCreateEmulatedDevice(pUVM, "Webcam", pInstance, &pThis->mUuid);
    114     LogRel(("PDMR3UsbCreateEmulatedDevice %Rrc\n", rc));
     129    LogRelFlowFunc(("PDMR3UsbCreateEmulatedDevice %Rrc\n", rc));
    115130    if (RT_FAILURE(rc) && pInstance)
    116131        CFGMR3RemoveNode(pInstance);
     
    124139
    125140HRESULT EUSBWEBCAM::Initialize(Console *pConsole,
     141                               EmulatedUSB *pEmulatedUSB,
    126142                               const com::Utf8Str *aPath,
    127143                               const com::Utf8Str *aSettings)
     
    132148    if (RT_SUCCESS(vrc))
    133149    {
     150        RTStrPrintf(mszUuid, sizeof(mszUuid), "%RTuuid", &mUuid);
    134151        hrc = mPath.assignEx(*aPath);
    135152        if (SUCCEEDED(hrc))
     
    141158        {
    142159            hrc = settingsParse();
     160
     161            if (SUCCEEDED(hrc))
     162            {
     163                mpEmulatedUSB = pEmulatedUSB;
     164            }
    143165        }
    144166    }
     
    311333        if (p)
    312334        {
    313             hrc = p->Initialize(m.pConsole, &path, &aSettings);
     335            hrc = p->Initialize(m.pConsole, this, &path, &aSettings);
    314336            if (SUCCEEDED(hrc))
    315337            {
     
    414436}
    415437
     438/* static */ DECLCALLBACK(int) EmulatedUSB::eusbCallbackEMT(EmulatedUSB *pThis, char *pszId, uint32_t iEvent,
     439                                                            void *pvData, uint32_t cbData)
     440{
     441    LogRelFlowFunc(("id %s event %d, data %p %d\n", pszId, iEvent, pvData, cbData));
     442
     443    NOREF(cbData);
     444
     445    int rc = VINF_SUCCESS;
     446    if (iEvent == 0)
     447    {
     448        com::Utf8Str path;
     449        HRESULT hr = pThis->webcamPathFromId(&path, pszId);
     450        if (SUCCEEDED(hr))
     451        {
     452            hr = pThis->webcamDetach(path);
     453            if (FAILED(hr))
     454            {
     455                rc = VERR_INVALID_STATE;
     456            }
     457        }
     458        else
     459        {
     460            rc = VERR_NOT_FOUND;
     461        }
     462    }
     463    else
     464    {
     465        rc = VERR_INVALID_PARAMETER;
     466    }
     467
     468    RTMemFree(pszId);
     469    RTMemFree(pvData);
     470
     471    LogRelFlowFunc(("rc %Rrc\n", rc));
     472    return rc;
     473}
     474
     475/* static */ DECLCALLBACK(int) EmulatedUSB::eusbCallback(void *pv, const char *pszId, uint32_t iEvent,
     476                                                         const void *pvData, uint32_t cbData)
     477{
     478    /* Make a copy of parameters, forward to EMT and leave the callback to not hold any lock in the device. */
     479    int rc = VINF_SUCCESS;
     480
     481    void *pvIdCopy = NULL;
     482    void *pvDataCopy = NULL;
     483    if (cbData > 0)
     484    {
     485       pvDataCopy = RTMemDup(pvData, cbData);
     486       if (!pvDataCopy)
     487       {
     488           rc = VERR_NO_MEMORY;
     489       }
     490    }
     491
     492    if (RT_SUCCESS(rc))
     493    {
     494        pvIdCopy = RTMemDup(pszId, strlen(pszId) + 1);
     495        if (!pvIdCopy)
     496        {
     497            rc = VERR_NO_MEMORY;
     498        }
     499    }
     500
     501    if (RT_SUCCESS(rc))
     502    {
     503        EmulatedUSB *pThis = (EmulatedUSB *)pv;
     504        Console::SafeVMPtr ptrVM(pThis->m.pConsole);
     505        if (ptrVM.isOk())
     506        {
     507            /* No wait. */
     508            rc = VMR3ReqCallNoWaitU(ptrVM.rawUVM(), 0 /* idDstCpu */,
     509                                    (PFNRT)EmulatedUSB::eusbCallbackEMT, 5,
     510                                    pThis, pvIdCopy, iEvent, pvDataCopy, cbData);
     511        }
     512        else
     513        {
     514            rc = VERR_INVALID_STATE;
     515        }
     516    }
     517
     518    if (RT_FAILURE(rc))
     519    {
     520        RTMemFree(pvIdCopy);
     521        RTMemFree(pvDataCopy);
     522    }
     523
     524    return rc;
     525}
     526
     527HRESULT EmulatedUSB::webcamPathFromId(com::Utf8Str *pPath, const char *pszId)
     528{
     529    HRESULT hr = S_OK;
     530
     531    Console::SafeVMPtr ptrVM(m.pConsole);
     532    if (ptrVM.isOk())
     533    {
     534        AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     535        WebcamsMap::const_iterator it;
     536        for (it = m.webcams.begin(); it != m.webcams.end(); ++it)
     537        {
     538            EUSBWEBCAM *p = it->second;
     539            if (p->HasId(pszId))
     540            {
     541                *pPath = it->first;
     542                break;
     543            }
     544        }
     545
     546        if (it == m.webcams.end())
     547        {
     548            hr = E_FAIL;
     549        }
     550        alock.release();
     551    }
     552    else
     553    {
     554        hr = VBOX_E_INVALID_VM_STATE;
     555    }
     556
     557    return hr;
     558}
     559
    416560/* vi: set tabstop=4 shiftwidth=4 expandtab: */
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