/* In some case (like compiz which doesn't provide us with clipping regions) we
 * have to make sure that *all* open OpenGL windows are clipped to the main
 * application window. This is done here when called from the event handler
 * which monitor bounding changes of the main window. */
static void crClipRootHelper(unsigned long key, void *data1, void *data2)
{
    /* The window with id zero is the base window, which isn't displayed at
     * all. So ignore it. */
    if (key > 0)
    {
        /* Fetch the actually window info & the user data */
        WindowInfo *pWin = (WindowInfo *) data1;
        /* We need to assign the context with this window */
        ContextInfo *context = renderspuGetWindowContext(pWin);
        if (context &&
            context->context)
        {
            RTSemFastMutexRequest(render_spu.syncMutex);
            GLboolean result = render_spu.ws.aglSetCurrentContext(context->context);
            CHECK_AGL_RC (result, "Render SPU (crClipRootHelper): SetCurrentContext Failed");
            if (result)
            {
                result = render_spu.ws.aglUpdateContext(context->context);
                CHECK_AGL_RC (result, "Render SPU (crClipRootHelper): UpdateContext Failed");
                /* Update the clipping region */
                renderspu_SystemWindowApplyVisibleRegion(pWin);
            }
            RTSemFastMutexRelease(render_spu.syncMutex);
            /* Make sure that the position is updated relative to the Qt main
             * view */
            renderspu_SystemWindowPosition(pWin, pWin->x, pWin->y);
        }
    }
}
示例#2
0
VBOXDDU_DECL(int) VDDbgIoLogReqTypeGetNext(VDIOLOGGER hIoLogger, PVDDBGIOLOGREQ penmReq)
{
    int rc = VINF_SUCCESS;
    PVDIOLOGGERINT pIoLogger = hIoLogger;

    AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
    AssertPtrReturn(penmReq, VERR_INVALID_POINTER);

    rc = RTSemFastMutexRequest(pIoLogger->hMtx);
    AssertRCReturn(rc, rc);

    if (pIoLogger->offReadNext == pIoLogger->offWriteNext)
    {
        *penmReq = VDDBGIOLOGREQ_INVALID;
        RTSemFastMutexRelease(pIoLogger->hMtx);
        return VERR_INVALID_STATE;
    }

    if (RT_SUCCESS(rc))
    {
        Assert(pIoLogger->enmReqTypeNext != VDDBGIOLOGREQ_INVALID);
        *penmReq = pIoLogger->enmReqTypeNext;
    }

    RTSemFastMutexRelease(pIoLogger->hMtx);
    return rc;
}
示例#3
0
DECLINLINE(int) vbglHandleHeapEnter (void)
{
    int rc = RTSemFastMutexRequest(g_vbgldata.mutexHGCMHandle);

    VBGL_HGCM_ASSERTMsg(RT_SUCCESS(rc),
                        ("Failed to request handle heap mutex, rc = %Rrc\n", rc));

    return rc;
}
DECLINLINE(int) vboxPciDevLock(PVBOXRAWPCIINS pThis)
{
#ifdef VBOX_WITH_SHARED_PCI_INTERRUPTS
    RTSpinlockAcquire(pThis->hSpinlock);
    return VINF_SUCCESS;
#else
    int rc = RTSemFastMutexRequest(pThis->hFastMtx);

    AssertRC(rc);
    return rc;
#endif
}
示例#5
0
VBOXDDU_DECL(int) VDDbgIoLogEventGetStart(VDIOLOGGER hIoLogger, uint64_t *pidEvent, bool *pfAsync,
                                          uint64_t *poff, size_t *pcbIo, size_t cbBuf, void *pvBuf)
{
    int rc = VINF_SUCCESS;
    PVDIOLOGGERINT pIoLogger = hIoLogger;

    AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
    AssertPtrReturn(pidEvent, VERR_INVALID_POINTER);
    AssertPtrReturn(pfAsync, VERR_INVALID_POINTER);
    AssertPtrReturn(poff, VERR_INVALID_POINTER);
    AssertPtrReturn(pcbIo, VERR_INVALID_POINTER);

    rc = RTSemFastMutexRequest(pIoLogger->hMtx);
    AssertRCReturn(rc, rc);

    if (pIoLogger->u32EventTypeNext == VDIOLOG_EVENT_START)
    {
        IoLogEntryStart Entry;
        rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext, &Entry, sizeof(Entry), NULL);
        if (RT_SUCCESS(rc))
        {
            *pfAsync   = RT_BOOL(Entry.u8AsyncIo);
            *pidEvent  = RT_LE2H_U64(Entry.u64Id);
            *poff      = RT_LE2H_U64(Entry.Io.u64Off);
            *pcbIo     = RT_LE2H_U64(Entry.Io.u64IoSize);

            if (   pIoLogger->enmReqTypeNext == VDDBGIOLOGREQ_WRITE
                && (pIoLogger->fFlags & VDDBG_IOLOG_LOG_DATA_WRITTEN))
            {
                /* Read data. */
                if (cbBuf < *pcbIo)
                    rc = VERR_BUFFER_OVERFLOW;
                else
                    rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext + sizeof(Entry), pvBuf, *pcbIo, NULL);

                if (rc != VERR_BUFFER_OVERFLOW)
                    pIoLogger->offReadNext += *pcbIo + sizeof(Entry);
            }
            else
                pIoLogger->offReadNext += sizeof(Entry);
        }
    }
    else
        rc = VERR_INVALID_STATE;

    if (RT_SUCCESS(rc))
        pIoLogger->u32EventTypeNext = 0;

    RTSemFastMutexRelease(pIoLogger->hMtx);
    return rc;
}
示例#6
0
VBOXDDU_DECL(int) VDDbgIoLogEventTypeGetNext(VDIOLOGGER hIoLogger, VDIOLOGEVENT *penmEvent)
{
    int rc = VINF_SUCCESS;
    PVDIOLOGGERINT pIoLogger = hIoLogger;

    AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
    AssertPtrReturn(penmEvent, VERR_INVALID_POINTER);

    rc = RTSemFastMutexRequest(pIoLogger->hMtx);
    AssertRCReturn(rc, rc);

    if (pIoLogger->offReadNext == pIoLogger->offWriteNext)
    {
        *penmEvent = VDIOLOGEVENT_END;
        RTSemFastMutexRelease(pIoLogger->hMtx);
        return VINF_SUCCESS;
    }

    if (!pIoLogger->u32EventTypeNext)
    {
        uint32_t abBuf[2];
        rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext, &abBuf, sizeof(abBuf), NULL);
        if (RT_SUCCESS(rc))
        {
            pIoLogger->u32EventTypeNext = abBuf[0];
            pIoLogger->enmReqTypeNext   = (VDDBGIOLOGREQ)abBuf[1];
        }
    }

    if (RT_SUCCESS(rc))
    {
        Assert(pIoLogger->u32EventTypeNext != VDIOLOGEVENT_INVALID);

        switch (pIoLogger->u32EventTypeNext)
        {
            case VDIOLOG_EVENT_START:
                *penmEvent = VDIOLOGEVENT_START;
                break;
            case VDIOLOG_EVENT_COMPLETE:
                *penmEvent = VDIOLOGEVENT_COMPLETE;
                break;
            default:
                AssertMsgFailed(("Invalid event type %d\n", pIoLogger->u32EventTypeNext));
        }
    }

    RTSemFastMutexRelease(pIoLogger->hMtx);
    return rc;
}
示例#7
0
VBOXDDU_DECL(int) VDDbgIoLogEventGetComplete(VDIOLOGGER hIoLogger, uint64_t *pidEvent, int *pRc,
                                             uint64_t *pmsDuration, size_t *pcbIo, size_t cbBuf, void *pvBuf)
{
    int rc = VINF_SUCCESS;
    PVDIOLOGGERINT pIoLogger = hIoLogger;

    AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
    AssertPtrReturn(pidEvent, VERR_INVALID_POINTER);
    AssertPtrReturn(pmsDuration, VERR_INVALID_POINTER);
    AssertPtrReturn(pcbIo, VERR_INVALID_POINTER);

    rc = RTSemFastMutexRequest(pIoLogger->hMtx);
    AssertRCReturn(rc, rc);

    if (pIoLogger->u32EventTypeNext == VDIOLOG_EVENT_COMPLETE)
    {
        IoLogEntryComplete Entry;
        rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext, &Entry, sizeof(Entry), NULL);
        if (RT_SUCCESS(rc))
        {
            *pidEvent    = RT_LE2H_U64(Entry.u64Id);
            *pRc         = (int)RT_LE2H_U32((int32_t)Entry.i32Rc);
            *pmsDuration = RT_LE2H_U64(Entry.msDuration);
            *pcbIo       = RT_LE2H_U64(Entry.u64IoBuffer);

            if (*pcbIo)
            {
                /* Read data. */
                if (cbBuf < *pcbIo)
                    rc = VERR_BUFFER_OVERFLOW;
                else
                    rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext + sizeof(Entry), pvBuf, *pcbIo, NULL);

                if (rc != VERR_BUFFER_OVERFLOW)
                    pIoLogger->offReadNext += *pcbIo + sizeof(Entry);
            }
            else
                pIoLogger->offReadNext += sizeof(Entry);
        }
    }
    else
        rc = VERR_INVALID_STATE;

    if (RT_SUCCESS(rc))
        pIoLogger->u32EventTypeNext = 0;

    RTSemFastMutexRelease(pIoLogger->hMtx);
    return rc;
}
示例#8
0
/**
 * Destroys the given VUSB sniffer instance.
 *
 * @returns nothing.
 * @param   hSniffer              The sniffer instance to destroy.
 */
DECLHIDDEN(void) VUSBSnifferDestroy(VUSBSNIFFER hSniffer)
{
    PVUSBSNIFFERINT pThis = hSniffer;

    int rc = RTSemFastMutexRequest(pThis->hMtx);
    AssertRC(rc);

    if (pThis->hFile != NIL_RTFILE)
        RTFileClose(pThis->hFile);
    if (pThis->pbBlockData)
        RTMemFree(pThis->pbBlockData);

    RTSemFastMutexRelease(pThis->hMtx);
    RTSemFastMutexDestroy(pThis->hMtx);
    RTMemFree(pThis);
}
示例#9
0
PUSBDEVICE USBProxyBackendUsbIp::getDevices(void)
{
    PUSBDEVICE pFirst = NULL;
    PUSBDEVICE *ppNext = &pFirst;

    /* Create a deep copy of the device list. */
    RTSemFastMutexRequest(m->hMtxDevices);
    PUSBDEVICE pCur = m->pUsbDevicesCur;
    while (pCur)
    {
        PUSBDEVICE pNew = (PUSBDEVICE)RTMemAllocZ(sizeof(USBDEVICE));
        if (pNew)
        {
            pNew->pszManufacturer    = RTStrDup(pCur->pszManufacturer);
            pNew->pszProduct         = RTStrDup(pCur->pszProduct);
            if (pCur->pszSerialNumber)
                pNew->pszSerialNumber = RTStrDup(pCur->pszSerialNumber);
            pNew->pszBackend         = RTStrDup(pCur->pszBackend);
            pNew->pszAddress         = RTStrDup(pCur->pszAddress);

            pNew->idVendor           = pCur->idVendor;
            pNew->idProduct          = pCur->idProduct;
            pNew->bcdDevice          = pCur->bcdDevice;
            pNew->bcdUSB             = pCur->bcdUSB;
            pNew->bDeviceClass       = pCur->bDeviceClass;
            pNew->bDeviceSubClass    = pCur->bDeviceSubClass;
            pNew->bDeviceProtocol    = pCur->bDeviceProtocol;
            pNew->bNumConfigurations = pCur->bNumConfigurations;
            pNew->enmState           = pCur->enmState;
            pNew->u64SerialHash      = pCur->u64SerialHash;
            pNew->bBus               = pCur->bBus;
            pNew->bPort              = pCur->bPort;
            pNew->enmSpeed           = pCur->enmSpeed;

            /* link it */
            pNew->pNext = NULL;
            pNew->pPrev = *ppNext;
            *ppNext = pNew;
            ppNext = &pNew->pNext;
        }

        pCur = pCur->pNext;
    }
    RTSemFastMutexRelease(m->hMtxDevices);

    return pFirst;
}
示例#10
0
VBOXDDU_DECL(int) VDDbgIoLogComplete(VDIOLOGGER hIoLogger, VDIOLOGENT hIoLogEntry, int rcReq, PCRTSGBUF pSgBuf)
{
    int rc = VINF_SUCCESS;
    PVDIOLOGGERINT pIoLogger = hIoLogger;
    PVDIOLOGENTINT pIoLogEntry = hIoLogEntry;

    AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
    AssertPtrReturn(pIoLogEntry, VERR_INVALID_HANDLE);

    rc = RTSemFastMutexRequest(pIoLogger->hMtx);
    AssertRCReturn(rc, rc);

    IoLogEntryComplete Entry;

    Entry.u32Type     = VDIOLOG_EVENT_COMPLETE;
    Entry.u64Id       = RT_H2LE_U64(pIoLogEntry->idStart);
    Entry.msDuration  = RTTimeProgramMilliTS() - RT_H2LE_U64(pIoLogEntry->tsStart);
    Entry.i32Rc       = (int32_t)RT_H2LE_U32((uint32_t)rcReq);
    Entry.u64IoBuffer = RT_H2LE_U64(pIoLogEntry->cbIo);

    /* Write new entry. */
    rc = RTFileWriteAt(pIoLogger->hFile, pIoLogger->offWriteNext, &Entry, sizeof(Entry), NULL);
    if (RT_SUCCESS(rc))
    {
        pIoLogger->offWriteNext += sizeof(Entry);

        if (pIoLogEntry->cbIo)
        {
            rc = vddbgIoLogWriteSgBuf(pIoLogger, pIoLogger->offWriteNext, pSgBuf, pIoLogEntry->cbIo);
            if (RT_SUCCESS(rc))
                pIoLogger->offWriteNext += pIoLogEntry->cbIo;
            else
            {
                pIoLogger->offWriteNext -= sizeof(Entry);
                rc = RTFileSetSize(pIoLogger->hFile, pIoLogger->offWriteNext);
            }
        }
    }

    RTMemCacheFree(pIoLogger->hMemCacheIoLogEntries, pIoLogEntry);
    RTSemFastMutexRelease(pIoLogger->hMtx);
    return rc;
}
/**
 * Detach entry point, to detach a device to the system or suspend it.
 *
 * @param   pDip            The module structure instance.
 * @param   enmCmd          Operation type (detach/suspend).
 *
 * @return  corresponding solaris error code.
 */
static int VBoxDrvSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
{
    LogFlowFunc(("VBoxDrvSolarisDetach\n"));
    switch (enmCmd)
    {
        case DDI_DETACH:
        {
#ifndef USE_SESSION_HASH
            ddi_remove_minor_node(pDip, NULL);
#else
            int instance = ddi_get_instance(pDip);
            vbox_devstate_t *pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, instance);
            ddi_remove_minor_node(pDip, NULL);
            ddi_soft_state_free(g_pVBoxDrvSolarisState, instance);
#endif
            ddi_prop_remove_all(pDip);
            return DDI_SUCCESS;
        }

        case DDI_SUSPEND:
        {
#if 0
            RTSemFastMutexRequest(g_DevExt.mtxGip);
            if (g_DevExt.pGipTimer && g_DevExt.cGipUsers > 0)
                RTTimerStop(g_DevExt.pGipTimer);

            RTSemFastMutexRelease(g_DevExt.mtxGip);
#endif
            RTPowerSignalEvent(RTPOWEREVENT_SUSPEND);
            LogFlow(("vboxdrv: Falling to suspend mode.\n"));
            return DDI_SUCCESS;

        }

        default:
            return DDI_FAILURE;
    }
}
示例#12
0
void
renderspu_SystemSwapBuffers(WindowInfo *window, GLint flags)
{
    CRASSERT(window);
    CRASSERT(window->window);

    ContextInfo *context = renderspuGetWindowContext(window);

    if(!context)
        crError("Render SPU (renderspu_SystemSwapBuffers): SwapBuffers got a null context from the window");

    RTSemFastMutexRequest(render_spu.syncMutex);
//    DEBUG_MSG_POETZSCH (("Swapped %d context %x visible: %d\n", window->BltInfo.Base.id, context->context, IsWindowVisible (window->window)));
    if (context->visual &&
        context->visual->visAttribs & CR_DOUBLE_BIT)
        render_spu.ws.aglSwapBuffers(context->context);
    else
        glFlush();
    RTSemFastMutexRelease(render_spu.syncMutex);

    /* This method seems called very often. To prevent the dock using all free
     * resources we update the dock only two times per second. */
    uint64_t curTS = RTTimeMilliTS();
    if ((curTS - render_spu.uiDockUpdateTS) > 500)
    {
        OSStatus status = noErr;
        /* Send a event to the main thread, cause some function of Carbon aren't
         * thread safe */
        EventRef evt;
        status = CreateEvent(NULL, kEventClassVBox, kEventVBoxUpdateDock, 0, kEventAttributeNone, &evt);
        CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemSwapBuffers): CreateEvent Failed");
        status = PostEventToQueue(GetMainEventQueue(), evt, kEventPriorityStandard);
        CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemSwapBuffers): PostEventToQueue Failed");

        render_spu.uiDockUpdateTS = curTS;
    }
}
示例#13
0
VBOXDDU_DECL(int) VDDbgIoLogStart(VDIOLOGGER hIoLogger, bool fAsync, VDDBGIOLOGREQ enmTxDir, uint64_t off, size_t cbIo, PCRTSGBUF pSgBuf,
                                  PVDIOLOGENT phIoLogEntry)
{
    int rc = VINF_SUCCESS;
    PVDIOLOGGERINT pIoLogger = hIoLogger;
    PVDIOLOGENTINT pIoLogEntry = NULL;

    AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
    AssertPtrReturn(phIoLogEntry, VERR_INVALID_POINTER);
    AssertReturn(enmTxDir > VDDBGIOLOGREQ_INVALID && enmTxDir <= VDDBGIOLOGREQ_FLUSH, VERR_INVALID_PARAMETER);

    rc = RTSemFastMutexRequest(pIoLogger->hMtx);
    AssertRCReturn(rc, rc);

    pIoLogEntry = (PVDIOLOGENTINT)RTMemCacheAlloc(pIoLogger->hMemCacheIoLogEntries);
    if (pIoLogEntry)
    {
        IoLogEntryStart Entry;

        pIoLogEntry->idStart = pIoLogger->idNext++;

        Entry.u32Type       = VDIOLOG_EVENT_START;
        Entry.u8AsyncIo    = fAsync ? 1 : 0;
        Entry.u32ReqType   = enmTxDir;
        Entry.u64Id        = RT_H2LE_U64(pIoLogEntry->idStart);
        Entry.Io.u64Off    = RT_H2LE_U64(off);
        Entry.Io.u64IoSize = RT_H2LE_U64(cbIo);

        /* Write new entry. */
        rc = RTFileWriteAt(pIoLogger->hFile, pIoLogger->offWriteNext, &Entry, sizeof(Entry), NULL);
        if (RT_SUCCESS(rc))
        {
            pIoLogger->offWriteNext += sizeof(Entry);

            if (   enmTxDir == VDDBGIOLOGREQ_WRITE
                && (pIoLogger->fFlags & VDDBG_IOLOG_LOG_DATA_WRITTEN))
            {
                /* Write data. */
                rc = vddbgIoLogWriteSgBuf(pIoLogger, pIoLogger->offWriteNext, pSgBuf, cbIo);
                if (RT_FAILURE(rc))
                {
                    pIoLogger->offWriteNext -= sizeof(Entry);
                    rc = RTFileSetSize(pIoLogger->hFile, pIoLogger->offWriteNext);
                }
                else
                    pIoLogger->offWriteNext += cbIo;
            }
        }

        if (RT_SUCCESS(rc))
        {
            pIoLogEntry->tsStart = RTTimeProgramMilliTS();

            if (   enmTxDir == VDDBGIOLOGREQ_READ
                && (pIoLogger->fFlags & VDDBG_IOLOG_LOG_DATA_READ))
                pIoLogEntry->cbIo = cbIo;
            else
                pIoLogEntry->cbIo = 0;

            *phIoLogEntry = pIoLogEntry;
        }
        else
        {
            pIoLogger->idNext--;
            RTMemCacheFree(pIoLogger->hMemCacheIoLogEntries, pIoLogEntry);
        }
    }
    else
        rc = VERR_NO_MEMORY;

    RTSemFastMutexRelease(pIoLogger->hMtx);
    return rc;
}
/**
 * Attach entry point, to attach a device to the system or resume it.
 *
 * @param   pDip            The module structure instance.
 * @param   enmCmd          Operation type (attach/resume).
 *
 * @return  corresponding solaris error code.
 */
static int VBoxDrvSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
{
    LogFlowFunc(("VBoxDrvSolarisAttach\n"));

    switch (enmCmd)
    {
        case DDI_ATTACH:
        {
            int rc;
#ifdef USE_SESSION_HASH
            int instance = ddi_get_instance(pDip);
            vbox_devstate_t *pState;

            if (ddi_soft_state_zalloc(g_pVBoxDrvSolarisState, instance) != DDI_SUCCESS)
            {
                LogRel(("VBoxDrvSolarisAttach: state alloc failed\n"));
                return DDI_FAILURE;
            }

            pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, instance);
#endif

            /*
             * Register for suspend/resume notifications
             */
            rc = ddi_prop_create(DDI_DEV_T_NONE, pDip, DDI_PROP_CANSLEEP /* kmem alloc can sleep */,
                                "pm-hardware-state", "needs-suspend-resume", sizeof("needs-suspend-resume"));
            if (rc != DDI_PROP_SUCCESS)
                LogRel(("vboxdrv: Suspend/Resume notification registration failed.\n"));

            /*
             * Register ourselves as a character device, pseudo-driver
             */
#ifdef VBOX_WITH_HARDENING
            rc = ddi_create_priv_minor_node(pDip, DEVICE_NAME_SYS, S_IFCHR, 0 /*minor*/, DDI_PSEUDO,
                                            0, NULL, NULL, 0600);
#else
            rc = ddi_create_priv_minor_node(pDip, DEVICE_NAME_SYS, S_IFCHR, 0 /*minor*/, DDI_PSEUDO,
                                            0, "none", "none", 0666);
#endif
            if (rc == DDI_SUCCESS)
            {
                rc = ddi_create_priv_minor_node(pDip, DEVICE_NAME_USR, S_IFCHR, 1 /*minor*/, DDI_PSEUDO,
                                                0, "none", "none", 0666);
                if (rc == DDI_SUCCESS)
                {
#ifdef USE_SESSION_HASH
                    pState->pDip = pDip;
#endif
                    ddi_report_dev(pDip);
                    return DDI_SUCCESS;
                }
                ddi_remove_minor_node(pDip, NULL);
            }

            return DDI_FAILURE;
        }

        case DDI_RESUME:
        {
#if 0
            RTSemFastMutexRequest(g_DevExt.mtxGip);
            if (g_DevExt.pGipTimer)
                RTTimerStart(g_DevExt.pGipTimer, 0);

            RTSemFastMutexRelease(g_DevExt.mtxGip);
#endif
            RTPowerSignalEvent(RTPOWEREVENT_RESUME);
            LogFlow(("vboxdrv: Awakened from suspend.\n"));
            return DDI_SUCCESS;
        }

        default:
            return DDI_FAILURE;
    }

    return DDI_FAILURE;
}
示例#15
0
/* Window event handler */
pascal OSStatus
windowEvtHndlr(EventHandlerCallRef myHandler, EventRef event, void* userData)
{
    WindowRef   window = NULL;
    OSStatus    eventResult = eventNotHandledErr;
    UInt32      class = GetEventClass (event);
    UInt32      kind = GetEventKind (event);

    /* If we aren't initialized or even deinitialized already (as on VM
     * shutdown) do nothing. */
    if (!render_spu.fInit)
        return eventNotHandledErr;

    /* Fetch the sender of the event */
    GetEventParameter(event, kEventParamDirectObject, typeWindowRef,
                      NULL, sizeof(WindowRef), NULL, &window);
    switch (class)
    {
        case kEventClassVBox:
        {
            switch (kind)
            {
                case kEventVBoxUpdateContext:
                {
#ifndef __LP64__ /** @todo port to 64-bit darwin! Need to check if this event is generated or not (it probably isn't). */
                    WindowInfo *wi1;
                    GetEventParameter(event, kEventParamUserData, typeVoidPtr,
                                      NULL, sizeof(wi1), NULL, &wi1);
                    ContextInfo *context = renderspuGetWindowContext(wi1);
                    if (context &&
                        context->context)
                    {
                        AGLContext tmpContext = render_spu.ws.aglGetCurrentContext();
                        DEBUG_MSG_POETZSCH (("kEventVBoxUpdateContext %x %x\n", wi1, context->context));
                        RTSemFastMutexRequest(render_spu.syncMutex);
                        GLboolean result = render_spu.ws.aglSetCurrentContext(context->context);
                        if (result)
                        {
                            result = render_spu.ws.aglUpdateContext(context->context);
                            CHECK_AGL_RC (result, "Render SPU (windowEvtHndlr): UpdateContext Failed");
                            renderspu_SystemWindowApplyVisibleRegion(wi1);
                            /* Reapply the last active context */
                            if (tmpContext)
                            {
                                result = render_spu.ws.aglSetCurrentContext(tmpContext);
                                CHECK_AGL_RC (result, "Render SPU (windowEvtHndlr): SetCurrentContext Failed");
                                if (result)
                                {
                                    result = render_spu.ws.aglUpdateContext(tmpContext);
                                    CHECK_AGL_RC (result, "Render SPU (windowEvtHndlr): UpdateContext Failed");
                                }
                            }
                        }
                        RTSemFastMutexRelease(render_spu.syncMutex);
                    }
                    eventResult = noErr;
#endif
                    break;
                }
                case kEventVBoxBoundsChanged:
                {
#ifndef __LP64__ /** @todo port to 64-bit darwin! Need to check if this event is generated or not (it probably isn't). */
                    HIPoint p;
                    GetEventParameter(event, kEventParamOrigin, typeHIPoint,
                                      NULL, sizeof(p), NULL, &p);
                    HISize s;
                    GetEventParameter(event, kEventParamDimensions, typeHISize,
                                      NULL, sizeof(s), NULL, &s);
                    HIRect r = CGRectMake (0, 0, s.width, s.height);
                    DEBUG_MSG_POETZSCH (("kEventVBoxBoundsChanged %f %f %f %f\n", p.x, p.y, s.width, s.height));
                    GLint l[4] = { 0,
                                   0,
                                   r.size.width,
                                   r.size.height };
                    /* Update the root window clip region */
                    renderspu_SystemSetRootVisibleRegion(1, l);
                    /* Temporary save the current active context */
                    AGLContext tmpContext = render_spu.ws.aglGetCurrentContext();
                    crHashtableWalk(render_spu.windowTable, crClipRootHelper, NULL);
                    /* Reapply the last active context */
                    if (tmpContext)
                    {
                        RTSemFastMutexRequest(render_spu.syncMutex);
                        GLboolean result = render_spu.ws.aglSetCurrentContext(tmpContext);
                        CHECK_AGL_RC (result, "Render SPU (windowEvtHndlr): SetCurrentContext Failed");
                        /* Doesn't work with DirectX; Anyway doesn't  */
/*                        if (result)*/
/*                        {*/
/*                            result = render_spu.ws.aglUpdateContext(tmpContext);*/
/*                            CHECK_AGL_RC (result, "Render SPU (windowEvtHndlr): UpdateContext Failed");*/
/*                        }*/
                        RTSemFastMutexRelease(render_spu.syncMutex);
                    }
                    eventResult = noErr;
#endif
                    break;
                }
            };
            break;
        }
        break;
    };

    return eventResult;
}
示例#16
0
GLboolean
renderspuWindowAttachContext(WindowInfo *wi, WindowRef window,
                             ContextInfo *context)
{
    GLboolean result;

    if(!context || !wi)
        return render_spu.ws.aglSetCurrentContext( NULL );

/*    DEBUG_MSG_POETZSCH (("WindowAttachContext %d\n", wi->BltInfo.Base.id));*/

    /* Flush old context first */
    if (context->currentWindow->window != window)
        render_spu.self.Flush();
    /* If the window buffer name is uninitialized we have to create a new
     * dummy context. */
    if (wi->bufferName == -1)
    {
        DEBUG_MSG_POETZSCH (("WindowAttachContext: create context %d\n", wi->BltInfo.Base.id));
        /* Use the same visual bits as those in the context structure */
        AGLPixelFormat pix;
        if( !renderspuChoosePixelFormat(context, &pix) )
        {
            crError( "Render SPU (renderspuWindowAttachContext): Unable to create pixel format" );
            return GL_FALSE;
        }
        /* Create the dummy context */
        wi->dummyContext = render_spu.ws.aglCreateContext( pix, NULL );
        renderspuDestroyPixelFormat( context, &pix );
        if( !wi->dummyContext )
        {
            crError( "Render SPU (renderspuWindowAttachContext): Could not create rendering context" );
            return GL_FALSE;
        }
        AGLDrawable drawable;
#ifdef __LP64__ /** @todo port to 64-bit darwin. */
        drawable = NULL;
#else
        drawable = (AGLDrawable) GetWindowPort(window);
#endif
        /* New global buffer name */
        wi->bufferName = render_spu.currentBufferName++;
        /* Set the new buffer name to the dummy context. This enable the
         * sharing of the same hardware buffer afterwards. */
        result = render_spu.ws.aglSetInteger(wi->dummyContext, AGL_BUFFER_NAME, &wi->bufferName);
        CHECK_AGL_RC (result, "Render SPU (renderspuWindowAttachContext): SetInteger Failed");
        /* Assign the dummy context to the window */
        result = render_spu.ws.aglSetDrawable(wi->dummyContext, drawable);
        CHECK_AGL_RC (result, "Render SPU (renderspuWindowAttachContext): SetDrawable Failed");
    }

    AGLDrawable oldDrawable;
    AGLDrawable newDrawable;

    oldDrawable = render_spu.ws.aglGetDrawable(context->context);
#ifdef __LP64__ /** @todo port to 64-bit darwin. */
    newDrawable = oldDrawable;
#else
    newDrawable = (AGLDrawable) GetWindowPort(window);
#endif
    RTSemFastMutexRequest(render_spu.syncMutex);
    /* Only switch the context if the drawable has changed */
    if (oldDrawable != newDrawable)
    {
        /* Reset the current context */
        result = render_spu.ws.aglSetDrawable(context->context, NULL);
        CHECK_AGL_RC (result, "Render SPU (renderspuWindowAttachContext): SetDrawable Failed");
        /* Set the buffer name of the dummy context to the current context
         * also. After that both share the same hardware buffer. */
        render_spu.ws.aglSetInteger (context->context, AGL_BUFFER_NAME, &wi->bufferName);
        CHECK_AGL_RC (result, "Render SPU (renderspuWindowAttachContext): SetInteger Failed");
        /* Set the new drawable */
#ifdef __LP64__ /** @todo port to 64-bit darwin. */
        result = -1;
#else
        result = render_spu.ws.aglSetDrawable(context->context, newDrawable);
#endif
        CHECK_AGL_RC (result, "Render SPU (renderspuWindowAttachContext): SetDrawable Failed");
        renderspuSetWindowContext(window, context);
    }
    result = render_spu.ws.aglSetCurrentContext(context->context);
    CHECK_AGL_RC (result, "Render SPU (renderspuWindowAttachContext): SetCurrentContext Failed");
    result = render_spu.ws.aglUpdateContext(context->context);
    CHECK_AGL_RC (result, "Render SPU (renderspuWindowAttachContext): UpdateContext Failed");
    RTSemFastMutexRelease(render_spu.syncMutex);

    return result;
}
示例#17
0
VBOXDDU_DECL(int) VDDbgIoLogEventGetStartDiscard(VDIOLOGGER hIoLogger, uint64_t *pidEvent, bool *pfAsync,
                                                 PRTRANGE *ppaRanges, unsigned *pcRanges)
{
    int rc = VINF_SUCCESS;
    PVDIOLOGGERINT pIoLogger = hIoLogger;

    AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
    AssertPtrReturn(pidEvent, VERR_INVALID_POINTER);
    AssertPtrReturn(pfAsync, VERR_INVALID_POINTER);

    rc = RTSemFastMutexRequest(pIoLogger->hMtx);
    AssertRCReturn(rc, rc);

    if (   pIoLogger->u32EventTypeNext == VDIOLOG_EVENT_START
        && pIoLogger->enmReqTypeNext == VDDBGIOLOGREQ_DISCARD)
    {
        IoLogEntryStart Entry;
        rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext, &Entry, sizeof(Entry), NULL);
        if (RT_SUCCESS(rc))
        {
            PRTRANGE paRanges = NULL;
            IoLogEntryDiscard DiscardRange;

            pIoLogger->offReadNext += sizeof(Entry);
            *pfAsync   = RT_BOOL(Entry.u8AsyncIo);
            *pidEvent  = RT_LE2H_U64(Entry.u64Id);
            *pcRanges  = RT_LE2H_U32(Entry.Discard.cRanges);

            paRanges = (PRTRANGE)RTMemAllocZ(*pcRanges * sizeof(RTRANGE));
            if (paRanges)
            {
                for (unsigned i = 0; i < *pcRanges; i++)
                {
                    rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext + i*sizeof(DiscardRange),
                                      &DiscardRange, sizeof(DiscardRange), NULL);
                    if (RT_FAILURE(rc))
                        break;

                    paRanges[i].offStart = RT_LE2H_U64(DiscardRange.u64Off);
                    paRanges[i].cbRange  = RT_LE2H_U32(DiscardRange.u32Discard);
                }

                if (RT_SUCCESS(rc))
                {
                    pIoLogger->offReadNext += *pcRanges * sizeof(DiscardRange);
                    *ppaRanges = paRanges;
                }
                else
                {
                    pIoLogger->offReadNext -= sizeof(Entry);
                    RTMemFree(paRanges);
                }
            }
            else
                rc = VERR_NO_MEMORY;
        }
    }
    else
        rc = VERR_INVALID_STATE;

    if (RT_SUCCESS(rc))
        pIoLogger->u32EventTypeNext = 0;

    RTSemFastMutexRelease(pIoLogger->hMtx);
    return rc;

}
示例#18
0
int USBProxyBackendUsbIp::wait(RTMSINTERVAL aMillies)
{
    int rc = VINF_SUCCESS;
    bool fDeviceListChangedOrWokenUp = false;

    /* Try to reconnect once when we enter if we lost the connection earlier. */
    if (m->hSocket == NIL_RTSOCKET)
        rc = reconnect();

    /* Query a new device list upon entering. */
    if (m->enmRecvState == kUsbIpRecvState_None)
    {
        rc = startListExportedDevicesReq();
        if (RT_FAILURE(rc))
            disconnect();
    }

    /*
     * Because the USB/IP protocol doesn't specify a way to get notified about
     * new or removed exported devices we have to poll the host periodically for
     * a new device list and compare it with the previous one notifying the proxy
     * service about changes.
     */
    while (   !fDeviceListChangedOrWokenUp
           && (aMillies == RT_INDEFINITE_WAIT || aMillies > 0)
           && RT_SUCCESS(rc))
    {
        RTMSINTERVAL msWait = aMillies;
        uint64_t msPollStart = RTTimeMilliTS();
        uint32_t uIdReady = 0;
        uint32_t fEventsRecv = 0;

        /* Limit the waiting time to 1sec so we can either reconnect or get a new device list. */
        if (m->hSocket == NIL_RTSOCKET || m->enmRecvState == kUsbIpRecvState_None)
            msWait = RT_MIN(1000, aMillies);

        rc = RTPoll(m->hPollSet, msWait, &fEventsRecv, &uIdReady);
        if (RT_SUCCESS(rc))
        {
            if (uIdReady == USBIP_POLL_ID_PIPE)
            {
                /* Drain the wakeup pipe. */
                char bRead = 0;
                size_t cbRead = 0;

                rc = RTPipeRead(m->hWakeupPipeR, &bRead, 1, &cbRead);
                Assert(RT_SUCCESS(rc) && cbRead == 1);
                fDeviceListChangedOrWokenUp = true;
            }
            else if (uIdReady == USBIP_POLL_ID_SOCKET)
            {
                if (fEventsRecv & RTPOLL_EVT_ERROR)
                    rc = VERR_NET_SHUTDOWN;
                else
                    rc = receiveData();
                if (RT_SUCCESS(rc))
                {
                    /*
                     * If we are in the none state again we received the previous request
                     * and have a new device list to compare the old against.
                     */
                    if (m->enmRecvState == kUsbIpRecvState_None)
                    {
                        if (hasDevListChanged(m->pHead))
                            fDeviceListChangedOrWokenUp = true;

                        /* Update to the new list in any case now that we have it anyway. */
                        RTSemFastMutexRequest(m->hMtxDevices);
                        freeDeviceList(m->pUsbDevicesCur);
                        m->cUsbDevicesCur = m->cDevicesCur;
                        m->pUsbDevicesCur = m->pHead;
                        RTSemFastMutexRelease(m->hMtxDevices);

                        m->pHead = NULL;
                        resetRecvState();
                    }
                }
                else if (rc == VERR_NET_SHUTDOWN || rc == VERR_BROKEN_PIPE)
                {
                    LogRelMax(10, ("USB/IP: Lost connection to host \"%s\", trying to reconnect...\n", m->pszHost));
                    disconnect();
                    rc = VINF_SUCCESS;
                }
            }
            else
            {
                AssertMsgFailed(("Invalid poll ID returned\n"));
                rc = VERR_INVALID_STATE;
            }
            aMillies -= (RTTimeMilliTS() - msPollStart);
        }
        else if (rc == VERR_TIMEOUT)
        {
            aMillies -= msWait;
            if (aMillies)
            {
                /* Try to reconnect and start a new request if we lost the connection before. */
                if (m->hSocket == NIL_RTSOCKET)
                    rc = reconnect();

                if (RT_SUCCESS(rc))
                    rc = startListExportedDevicesReq();
            }
        }
    }

    return rc;
}
示例#19
0
DECLINLINE(int) vboxPciVmLock(PVBOXRAWPCIDRVVM pThis)
{
    int rc = RTSemFastMutexRequest(pThis->hFastMtx);
    AssertRC(rc);
    return rc;
}
示例#20
0
DECLINLINE(int) vboxPciGlobalsLock(PVBOXRAWPCIGLOBALS pGlobals)
{
    int rc = RTSemFastMutexRequest(pGlobals->hFastMtx);
    AssertRC(rc);
    return rc;
}
示例#21
0
VBOXDDU_DECL(int) VDDbgIoLogStartDiscard(VDIOLOGGER hIoLogger, bool fAsync, PCRTRANGE paRanges, unsigned cRanges,
                                         PVDIOLOGENT phIoLogEntry)
{
    int rc = VINF_SUCCESS;
    PVDIOLOGGERINT pIoLogger = hIoLogger;
    PVDIOLOGENTINT pIoLogEntry = NULL;

    AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
    AssertPtrReturn(phIoLogEntry, VERR_INVALID_POINTER);

    rc = RTSemFastMutexRequest(pIoLogger->hMtx);
    AssertRCReturn(rc, rc);

    pIoLogEntry = (PVDIOLOGENTINT)RTMemCacheAlloc(pIoLogger->hMemCacheIoLogEntries);
    if (pIoLogEntry)
    {
        IoLogEntryStart Entry;

        pIoLogEntry->idStart = pIoLogger->idNext++;

        Entry.u32Type         = VDIOLOG_EVENT_START;
        Entry.u8AsyncIo       = fAsync ? 1 : 0;
        Entry.u32ReqType      = VDDBGIOLOGREQ_DISCARD;
        Entry.u64Id           = RT_H2LE_U64(pIoLogEntry->idStart);
        Entry.Discard.cRanges = RT_H2LE_U32(cRanges);

        /* Write new entry. */
        rc = RTFileWriteAt(pIoLogger->hFile, pIoLogger->offWriteNext, &Entry, sizeof(Entry), NULL);
        if (RT_SUCCESS(rc))
        {
            pIoLogger->offWriteNext += sizeof(Entry);

            IoLogEntryDiscard DiscardRange;

            for (unsigned i = 0; i < cRanges; i++)
            {
                DiscardRange.u64Off = RT_H2LE_U64(paRanges[i].offStart);
                DiscardRange.u32Discard = RT_H2LE_U32((uint32_t)paRanges[i].cbRange);
                rc = RTFileWriteAt(pIoLogger->hFile, pIoLogger->offWriteNext + i*sizeof(DiscardRange),
                                   &DiscardRange, sizeof(DiscardRange), NULL);
                if (RT_FAILURE(rc))
                    break;
            }

            if (RT_FAILURE(rc))
            {
                pIoLogger->offWriteNext -= sizeof(Entry);
                rc = RTFileSetSize(pIoLogger->hFile, pIoLogger->offWriteNext);
            }
            else
                pIoLogger->offWriteNext += cRanges * sizeof(DiscardRange);
        }

        if (RT_SUCCESS(rc))
        {
            pIoLogEntry->tsStart = RTTimeProgramMilliTS();
            pIoLogEntry->cbIo = 0;

            *phIoLogEntry = pIoLogEntry;
        }
        else
        {
            pIoLogger->idNext--;
            RTMemCacheFree(pIoLogger->hMemCacheIoLogEntries, pIoLogEntry);
        }
    }
    else
        rc = VERR_NO_MEMORY;

    RTSemFastMutexRelease(pIoLogger->hMtx);
    return rc;
}
示例#22
0
/**
 * Records an VUSB event.
 *
 * @returns VBox status code.
 * @param   hSniffer              The sniffer instance.
 * @param   pUrb                  The URB triggering the event.
 * @param   enmEvent              The type of event to record.
 */
DECLHIDDEN(int) VUSBSnifferRecordEvent(VUSBSNIFFER hSniffer, PVUSBURB pUrb, VUSBSNIFFEREVENT enmEvent)
{
    int rc = VINF_SUCCESS;
    PVUSBSNIFFERINT pThis = hSniffer;
    DumpFileEpb Epb;
    DumpFileUsbHeaderLnxMmapped UsbHdr;
    DumpFileUsbSetup UsbSetup;
    RTTIMESPEC TimeNow;
    uint64_t u64TimestampEvent;
    size_t cbUrbLength = 0;
    uint32_t cbDataLength = 0;
    uint32_t cbCapturedLength = sizeof(UsbHdr);
    uint32_t cIsocPkts = 0;
    uint8_t *pbData = NULL;

    RTTimeNow(&TimeNow);
    u64TimestampEvent = RTTimeSpecGetNano(&TimeNow);

    /* Start with the enhanced packet block. */
    Epb.Hdr.u32BlockType        = DUMPFILE_EPB_BLOCK_TYPE;
    Epb.Hdr.u32BlockTotalLength = 0;
    Epb.u32InterfaceId          = 0;
    Epb.u32TimestampHigh        = (u64TimestampEvent >> 32) & UINT32_C(0xffffffff);
    Epb.u32TimestampLow         = u64TimestampEvent & UINT32_C(0xffffffff);

    UsbHdr.u64Id = (uint64_t)pUrb; /** @todo: check whether the pointer is a good ID. */
    switch (enmEvent)
    {
        case VUSBSNIFFEREVENT_SUBMIT:
            UsbHdr.u8EventType = DUMPFILE_USB_EVENT_TYPE_SUBMIT;
            cbUrbLength = pUrb->cbData;
            break;
        case VUSBSNIFFEREVENT_COMPLETE:
            UsbHdr.u8EventType = DUMPFILE_USB_EVENT_TYPE_COMPLETE;
            cbUrbLength = pUrb->cbData;
            break;
        case VUSBSNIFFEREVENT_ERROR_SUBMIT:
        case VUSBSNIFFEREVENT_ERROR_COMPLETE:
            UsbHdr.u8EventType = DUMPFILE_USB_EVENT_TYPE_ERROR;
            break;
        default:
            AssertMsgFailed(("Invalid event type %d\n", enmEvent));
    }
    cbDataLength = cbUrbLength;
    pbData = &pUrb->abData[0];

    switch (pUrb->enmType)
    {
        case VUSBXFERTYPE_ISOC:
        {
                int32_t i32ErrorCount = 0;

                UsbHdr.u8TransferType = 0;
                cIsocPkts = pUrb->cIsocPkts;
                for (unsigned i = 0; i < cIsocPkts; i++)
                    if (   pUrb->aIsocPkts[i].enmStatus != VUSBSTATUS_OK
                        && pUrb->aIsocPkts[i].enmStatus != VUSBSTATUS_NOT_ACCESSED)
                        i32ErrorCount++;

                UsbHdr.u.IsoRec.i32ErrorCount = i32ErrorCount;
                UsbHdr.u.IsoRec.i32NumDesc    = pUrb->cIsocPkts;
                cbCapturedLength += cIsocPkts * sizeof(DumpFileUsbIsoDesc);
                break;
        }
        case VUSBXFERTYPE_BULK:
                UsbHdr.u8TransferType = 3;
                break;
        case VUSBXFERTYPE_INTR:
                UsbHdr.u8TransferType = 1;
                break;
        case VUSBXFERTYPE_CTRL:
        case VUSBXFERTYPE_MSG:
                UsbHdr.u8TransferType = 2;
                break;
        default:
            AssertMsgFailed(("invalid transfer type %d\n", pUrb->enmType));
    }

    if (pUrb->enmDir == VUSBDIRECTION_IN)
    {
        if (enmEvent == VUSBSNIFFEREVENT_SUBMIT)
            cbDataLength = 0;
    }
    else if (pUrb->enmDir == VUSBDIRECTION_OUT)
    {
        if (   enmEvent == VUSBSNIFFEREVENT_COMPLETE
            || pUrb->enmType == VUSBXFERTYPE_CTRL
            || pUrb->enmType == VUSBXFERTYPE_MSG)
            cbDataLength = 0;
    }
    else if (pUrb->enmDir == VUSBDIRECTION_SETUP)
        cbDataLength -= sizeof(VUSBSETUP);

    Epb.u32CapturedLen = cbCapturedLength + cbDataLength;
    Epb.u32PacketLen   = cbCapturedLength + cbUrbLength;

    UsbHdr.u8EndpointNumber = pUrb->EndPt | (pUrb->enmDir == VUSBDIRECTION_IN ? 0x80 : 0x00);
    UsbHdr.u8DeviceAddress  = pUrb->DstAddress;
    UsbHdr.u16BusId         = 0;
    UsbHdr.u8DataFlag       = cbDataLength ? 0 : 1;
    UsbHdr.u64TimestampSec  = u64TimestampEvent / RT_NS_1SEC_64;
    UsbHdr.u32TimestampUSec = u64TimestampEvent / RT_NS_1US_64 - UsbHdr.u64TimestampSec * RT_US_1SEC;
    UsbHdr.i32Status        = pUrb->enmStatus;
    UsbHdr.u32UrbLength     = cbUrbLength;
    UsbHdr.u32DataLength    = cbDataLength + cIsocPkts * sizeof(DumpFileUsbIsoDesc);
    UsbHdr.i32Interval      = 0;
    UsbHdr.i32StartFrame    = 0;
    UsbHdr.u32XferFlags     = 0;
    UsbHdr.u32NumDesc       = cIsocPkts;

    if (   (pUrb->enmType == VUSBXFERTYPE_MSG || pUrb->enmType == VUSBXFERTYPE_CTRL)
        && enmEvent == VUSBSNIFFEREVENT_SUBMIT)
    {
        PVUSBSETUP pSetup = (PVUSBSETUP)pUrb->abData;

        UsbHdr.u.UsbSetup.bmRequestType = pSetup->bmRequestType;
        UsbHdr.u.UsbSetup.bRequest      = pSetup->bRequest;
        UsbHdr.u.UsbSetup.wValue        = pSetup->wValue;
        UsbHdr.u.UsbSetup.wIndex        = pSetup->wIndex;
        UsbHdr.u.UsbSetup.wLength       = pSetup->wLength;
        UsbHdr.u8SetupFlag              = 0;
    }
    else
        UsbHdr.u8SetupFlag  = '-'; /* Follow usbmon source here. */

    /* Write the packet to the capture file. */
    rc = RTSemFastMutexRequest(pThis->hMtx);
    if (RT_SUCCESS(rc))
    {
        rc = vusbSnifferBlockNew(pThis, &Epb.Hdr, sizeof(Epb));
        if (RT_SUCCESS(rc))
            rc = vusbSnifferBlockAddData(pThis, &UsbHdr, sizeof(UsbHdr));

        /* Add Isochronous descriptors now. */
        for (unsigned i = 0; i < cIsocPkts && RT_SUCCESS(rc); i++)
        {
            DumpFileUsbIsoDesc IsoDesc;
            IsoDesc.i32Status = pUrb->aIsocPkts[i].enmStatus;
            IsoDesc.u32Offset = pUrb->aIsocPkts[i].off;
            IsoDesc.u32Len    = pUrb->aIsocPkts[i].cb;
            rc = vusbSnifferBlockAddData(pThis, &IsoDesc, sizeof(IsoDesc));
        }

        /* Record data. */
        if (   RT_SUCCESS(rc)
            && cbDataLength)
            rc = vusbSnifferBlockAddData(pThis, pbData, cbDataLength);

        if (RT_SUCCESS(rc))
            rc = vusbSnifferAddOption(pThis, DUMPFILE_OPTION_CODE_END, NULL, 0);

        if (RT_SUCCESS(rc))
            rc = vusbSnifferBlockCommit(pThis);

        RTSemFastMutexRelease(pThis->hMtx);
    }

    return rc;
}