VBoxUsbRt.cpp revision 6594fa9834a20895966c8226893b08f5273c5d4d
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync/* $Id$ */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync/** @file
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * VBox USB R0 runtime
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync/*
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * Copyright (C) 2011 Oracle Corporation
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync *
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * available from http://www.virtualbox.org. This file is free software;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * you can redistribute it and/or modify it under the terms of the GNU
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * General Public License (GPL) as published by the Free Software
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync#include "VBoxUsbCmn.h"
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync#include "../cmn/VBoxUsbIdc.h"
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync#include "../cmn/VBoxUsbTool.h"
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync#include <VBox/usblib-win.h>
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync#include <iprt/assert.h>
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync#include <VBox/log.h>
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync#define _USBD_
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync#define USBD_DEFAULT_PIPE_TRANSFER 0x00000008
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync#define VBOXUSB_MAGIC 0xABCF1423
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsynctypedef struct VBOXUSB_URB_CONTEXT
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PURB pUrb;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PMDL pMdlBuf;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PVBOXUSBDEV_EXT pDevExt;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PVOID pOut;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync ULONG ulTransferType;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync ULONG ulMagic;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync} VBOXUSB_URB_CONTEXT, * PVBOXUSB_URB_CONTEXT;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsynctypedef struct VBOXUSB_SETUP
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync uint8_t bmRequestType;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync uint8_t bRequest;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync uint16_t wValue;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync uint16_t wIndex;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync uint16_t wLength;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync} VBOXUSB_SETUP, *PVBOXUSB_SETUP;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic bool vboxUsbRtCtxSetOwner(PVBOXUSBDEV_EXT pDevExt, PFILE_OBJECT pFObj)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync bool bRc = ASMAtomicCmpXchgPtr(&pDevExt->Rt.pOwner, pFObj, NULL);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (bRc)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Log((__FUNCTION__": pDevExt (0x%x) Owner(0x%x) acquired\n", pFObj));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync else
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Log((__FUNCTION__": pDevExt (0x%x) Owner(0x%x) FAILED!!\n", pFObj));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return bRc;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic bool vboxUsbRtCtxReleaseOwner(PVBOXUSBDEV_EXT pDevExt, PFILE_OBJECT pFObj)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync bool bRc = ASMAtomicCmpXchgPtr(&pDevExt->Rt.pOwner, NULL, pFObj);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (bRc)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Log((__FUNCTION__": pDevExt (0x%x) Owner(0x%x) released\n", pFObj));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync else
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Log((__FUNCTION__": pDevExt (0x%x) Owner(0x%x) release: is NOT an owner\n", pFObj));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return bRc;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic bool vboxUsbRtCtxIsOwner(PVBOXUSBDEV_EXT pDevExt, PFILE_OBJECT pFObj)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PFILE_OBJECT pOwner = (PFILE_OBJECT)ASMAtomicReadPtr((void *volatile *)(&pDevExt->Rt.pOwner));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return pOwner == pFObj;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic NTSTATUS vboxUsbRtIdcSubmit(ULONG uCtl, void *pvBuffer)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync /* we just reuse the standard usb tooling for simplicity here */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync NTSTATUS Status = VBoxUsbToolIoInternalCtlSendSync(g_VBoxUsbGlobals.RtIdc.pDevice, uCtl, pvBuffer, NULL);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(Status == STATUS_SUCCESS);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic NTSTATUS vboxUsbRtIdcInit()
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync UNICODE_STRING UniName;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync RtlInitUnicodeString(&UniName, USBMON_DEVICE_NAME_NT);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync NTSTATUS Status = IoGetDeviceObjectPointer(&UniName, FILE_ALL_ACCESS, &g_VBoxUsbGlobals.RtIdc.pFile, &g_VBoxUsbGlobals.RtIdc.pDevice);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (NT_SUCCESS(Status))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync VBOXUSBIDC_VERSION Version;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbRtIdcSubmit(VBOXUSBIDC_INTERNAL_IOCTL_GET_VERSION, &Version);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (NT_SUCCESS(Status))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (Version.u32Major == VBOXUSBIDC_VERSION_MAJOR
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync && Version.u32Minor >= VBOXUSBIDC_VERSION_MINOR)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return STATUS_SUCCESS;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertFailed();
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync else
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertFailed();
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync /* this will as well dereference the dev obj */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync ObDereferenceObject(g_VBoxUsbGlobals.RtIdc.pFile);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync else
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertFailed();
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync memset(&g_VBoxUsbGlobals.RtIdc, 0, sizeof (g_VBoxUsbGlobals.RtIdc));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic VOID vboxUsbRtIdcTerm()
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(g_VBoxUsbGlobals.RtIdc.pFile);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(g_VBoxUsbGlobals.RtIdc.pDevice);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync ObDereferenceObject(g_VBoxUsbGlobals.RtIdc.pFile);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync memset(&g_VBoxUsbGlobals.RtIdc, 0, sizeof (g_VBoxUsbGlobals.RtIdc));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic NTSTATUS vboxUsbRtIdcReportDevStart(PDEVICE_OBJECT pPDO, HVBOXUSBIDCDEV *phDev)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync VBOXUSBIDC_PROXY_STARTUP Start;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Start.u.pPDO = pPDO;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync *phDev = NULL;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync NTSTATUS Status = vboxUsbRtIdcSubmit(VBOXUSBIDC_INTERNAL_IOCTL_PROXY_STARTUP, &Start);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(Status == STATUS_SUCCESS);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!NT_SUCCESS(Status))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync *phDev = Start.u.hDev;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return STATUS_SUCCESS;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic NTSTATUS vboxUsbRtIdcReportDevStop(HVBOXUSBIDCDEV hDev)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync VBOXUSBIDC_PROXY_TEARDOWN Stop;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Stop.hDev = hDev;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync NTSTATUS Status = vboxUsbRtIdcSubmit(VBOXUSBIDC_INTERNAL_IOCTL_PROXY_TEARDOWN, &Stop);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(Status == STATUS_SUCCESS);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncDECLHIDDEN(NTSTATUS) vboxUsbRtGlobalsInit()
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return vboxUsbRtIdcInit();
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncDECLHIDDEN(VOID) vboxUsbRtGlobalsTerm()
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbRtIdcTerm();
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncDECLHIDDEN(NTSTATUS) vboxUsbRtInit(PVBOXUSBDEV_EXT pDevExt)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync RtlZeroMemory(&pDevExt->Rt, sizeof (pDevExt->Rt));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync NTSTATUS Status = IoRegisterDeviceInterface(pDevExt->pPDO, &GUID_CLASS_VBOXUSB,
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync NULL, /* IN PUNICODE_STRING ReferenceString OPTIONAL */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync &pDevExt->Rt.IfName);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(Status == STATUS_SUCCESS);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (NT_SUCCESS(Status))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = vboxUsbRtIdcReportDevStart(pDevExt->pPDO, &pDevExt->Rt.hMonDev);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(Status == STATUS_SUCCESS);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (NT_SUCCESS(Status))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(pDevExt->Rt.hMonDev);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return STATUS_SUCCESS;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync NTSTATUS tmpStatus = IoSetDeviceInterfaceState(&pDevExt->Rt.IfName, FALSE);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(tmpStatus == STATUS_SUCCESS);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (NT_SUCCESS(tmpStatus))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync RtlFreeUnicodeString(&pDevExt->Rt.IfName);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync/**
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * Free cached USB device/configuration descriptors
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync *
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * @param pDevExt USB DevExt pointer
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic void vboxUsbRtFreeCachedDescriptors(PVBOXUSBDEV_EXT pDevExt)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pDevExt->Rt.devdescr)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbMemFree(pDevExt->Rt.devdescr);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.devdescr = NULL;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync for (ULONG i = 0; i < VBOXUSBRT_MAX_CFGS; ++i)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pDevExt->Rt.cfgdescr[i])
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbMemFree(pDevExt->Rt.cfgdescr[i]);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.cfgdescr[i] = NULL;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync/**
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * Free per-device interface info
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync *
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * @param pDevExt USB DevExt pointer
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * @param fAbortPipes If true, also abort any open pipes
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic void vboxUsbRtFreeInterfaces(PVBOXUSBDEV_EXT pDevExt, BOOLEAN fAbortPipes)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync unsigned i;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync unsigned j;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync /*
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * Free old interface info
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pDevExt->Rt.pVBIfaceInfo)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync for (i=0;i<pDevExt->Rt.uNumInterfaces;i++)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (fAbortPipes)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync for(j=0; j<pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo->NumberOfPipes; j++)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Log(("Aborting Pipe %d handle %x address %x\n", j,
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo->Pipes[j].PipeHandle,
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo->Pipes[j].EndpointAddress));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync VBoxUsbToolPipeClear(pDevExt->pLowerDO, pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo->Pipes[j].PipeHandle, FALSE);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbMemFree(pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo = NULL;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pDevExt->Rt.pVBIfaceInfo[i].pPipeInfo)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbMemFree(pDevExt->Rt.pVBIfaceInfo[i].pPipeInfo);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.pVBIfaceInfo[i].pPipeInfo = NULL;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbMemFree(pDevExt->Rt.pVBIfaceInfo);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.pVBIfaceInfo = NULL;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncDECLHIDDEN(VOID) vboxUsbRtClear(PVBOXUSBDEV_EXT pDevExt)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbRtFreeCachedDescriptors(pDevExt);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbRtFreeInterfaces(pDevExt, FALSE);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncDECLHIDDEN(NTSTATUS) vboxUsbRtRm(PVBOXUSBDEV_EXT pDevExt)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!pDevExt->Rt.IfName.Buffer)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return STATUS_SUCCESS;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync NTSTATUS Status = vboxUsbRtIdcReportDevStop(pDevExt->Rt.hMonDev);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(Status == STATUS_SUCCESS);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = IoSetDeviceInterfaceState(&pDevExt->Rt.IfName, FALSE);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(Status == STATUS_SUCCESS);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (NT_SUCCESS(Status))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync RtlFreeUnicodeString(&pDevExt->Rt.IfName);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.IfName.Buffer = NULL;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncDECLHIDDEN(NTSTATUS) vboxUsbRtStart(PVBOXUSBDEV_EXT pDevExt)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync NTSTATUS Status = IoSetDeviceInterfaceState(&pDevExt->Rt.IfName, TRUE);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(Status == STATUS_SUCCESS);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic NTSTATUS vboxUsbRtCacheDescriptors(PVBOXUSBDEV_EXT pDevExt)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync// uint32_t uTotalLength;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync// unsigned i;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync /* Read device descriptor */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(!pDevExt->Rt.devdescr);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.devdescr = (PUSB_DEVICE_DESCRIPTOR)vboxUsbMemAlloc(sizeof (USB_DEVICE_DESCRIPTOR));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pDevExt->Rt.devdescr)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync memset(pDevExt->Rt.devdescr, 0, sizeof (USB_DEVICE_DESCRIPTOR));
e04781b223e38e3b0c386d7e7c1dd7f30e9f6e90vboxsync Status = VBoxUsbToolGetDescriptor(pDevExt->pLowerDO, pDevExt->Rt.devdescr, sizeof (USB_DEVICE_DESCRIPTOR), USB_DEVICE_DESCRIPTOR_TYPE, 0, 0, RT_INDEFINITE_WAIT);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (NT_SUCCESS(Status))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(pDevExt->Rt.devdescr->bNumConfigurations > 0);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PUSB_CONFIGURATION_DESCRIPTOR pDr = (PUSB_CONFIGURATION_DESCRIPTOR)vboxUsbMemAlloc(sizeof (USB_CONFIGURATION_DESCRIPTOR));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(pDr);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pDr)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync UCHAR i = 0;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync for (; i < pDevExt->Rt.devdescr->bNumConfigurations; ++i)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
e04781b223e38e3b0c386d7e7c1dd7f30e9f6e90vboxsync Status = VBoxUsbToolGetDescriptor(pDevExt->pLowerDO, pDr, sizeof (USB_CONFIGURATION_DESCRIPTOR), USB_CONFIGURATION_DESCRIPTOR_TYPE, i, 0, RT_INDEFINITE_WAIT);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!NT_SUCCESS(Status))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync USHORT uTotalLength = pDr->wTotalLength;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.cfgdescr[i] = (PUSB_CONFIGURATION_DESCRIPTOR)vboxUsbMemAlloc(uTotalLength);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!pDevExt->Rt.cfgdescr[i])
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_INSUFFICIENT_RESOURCES;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
e04781b223e38e3b0c386d7e7c1dd7f30e9f6e90vboxsync Status = VBoxUsbToolGetDescriptor(pDevExt->pLowerDO, pDevExt->Rt.cfgdescr[i], uTotalLength, USB_CONFIGURATION_DESCRIPTOR_TYPE, i, 0, RT_INDEFINITE_WAIT);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!NT_SUCCESS(Status))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbMemFree(pDr);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (NT_SUCCESS(Status))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync /* recources will be freed in vboxUsbRtFreeCachedDescriptors below */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbRtFreeCachedDescriptors(pDevExt);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync /* shoud be only on fail here */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(!NT_SUCCESS(Status));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic NTSTATUS vboxUsbRtDispatchClaimDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PFILE_OBJECT pFObj = pSl->FileObject;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PUSBSUP_CLAIMDEV pDev = (PUSBSUP_CLAIMDEV)pIrp->AssociatedIrp.SystemBuffer;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync ULONG cbOut = 0;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync NTSTATUS Status = STATUS_SUCCESS;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync do
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!pFObj)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertFailed();
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_INVALID_PARAMETER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if ( !pDev
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync || pSl->Parameters.DeviceIoControl.InputBufferLength != sizeof (*pDev)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync || pSl->Parameters.DeviceIoControl.OutputBufferLength != sizeof (*pDev))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertFailed();
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_INVALID_PARAMETER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!vboxUsbRtCtxSetOwner(pDevExt, pFObj))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertFailed();
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDev->fClaimed = false;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync cbOut = sizeof (*pDev);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbRtFreeCachedDescriptors(pDevExt);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = vboxUsbRtCacheDescriptors(pDevExt);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (NT_SUCCESS(Status))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDev->fClaimed = true;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync cbOut = sizeof (*pDev);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync } while (0);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(Status != STATUS_PENDING);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync VBoxDrvToolIoComplete(pIrp, Status, cbOut);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbDdiStateRelease(pDevExt);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic NTSTATUS vboxUsbRtDispatchReleaseDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PFILE_OBJECT pFObj = pSl->FileObject;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync NTSTATUS Status= STATUS_SUCCESS;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (vboxUsbRtCtxIsOwner(pDevExt, pFObj))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbRtFreeCachedDescriptors(pDevExt);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync bool bRc = vboxUsbRtCtxReleaseOwner(pDevExt, pFObj);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(bRc);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync else
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertFailed();
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_ACCESS_DENIED;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync VBoxDrvToolIoComplete(pIrp, STATUS_SUCCESS, 0);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbDdiStateRelease(pDevExt);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return STATUS_SUCCESS;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic NTSTATUS vboxUsbRtGetDeviceDescription(PVBOXUSBDEV_EXT pDevExt)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PUSB_DEVICE_DESCRIPTOR pDr = (PUSB_DEVICE_DESCRIPTOR)vboxUsbMemAllocZ(sizeof (USB_DEVICE_DESCRIPTOR));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pDr)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
e04781b223e38e3b0c386d7e7c1dd7f30e9f6e90vboxsync Status = VBoxUsbToolGetDescriptor(pDevExt->pLowerDO, pDr, sizeof(*pDr), USB_DEVICE_DESCRIPTOR_TYPE, 0, 0, RT_INDEFINITE_WAIT);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (NT_SUCCESS(Status))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.idVendor = pDr->idVendor;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.idProduct = pDr->idProduct;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.bcdDevice = pDr->bcdDevice;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.szSerial[0] = 0;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pDr->iSerialNumber
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync#ifdef DEBUG
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync || pDr->iProduct || pDr->iManufacturer
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync#endif
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync )
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync int langId;
e04781b223e38e3b0c386d7e7c1dd7f30e9f6e90vboxsync Status = VBoxUsbToolGetLangID(pDevExt->pLowerDO, &langId, RT_INDEFINITE_WAIT);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (NT_SUCCESS(Status))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
e04781b223e38e3b0c386d7e7c1dd7f30e9f6e90vboxsync Status = VBoxUsbToolGetStringDescriptorA(pDevExt->pLowerDO, pDevExt->Rt.szSerial, sizeof (pDevExt->Rt.szSerial), pDr->iSerialNumber, langId, RT_INDEFINITE_WAIT);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync else
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_SUCCESS;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbMemFree(pDr);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic NTSTATUS vboxUsbRtDispatchGetDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PUSBSUP_GETDEV pDev = (PUSBSUP_GETDEV)pIrp->AssociatedIrp.SystemBuffer;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync NTSTATUS Status = STATUS_SUCCESS;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync ULONG cbOut = 0;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync /* don't check for owner since this request is allowed for non-owners as well */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pDev && pSl->Parameters.DeviceIoControl.InputBufferLength == sizeof (*pDev)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync && pSl->Parameters.DeviceIoControl.OutputBufferLength == sizeof (*pDev))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = VBoxUsbToolGetDeviceSpeed(pDevExt->pLowerDO, &pDevExt->Rt.fIsHighSpeed);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (NT_SUCCESS(Status))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDev->hDevice = pDevExt->Rt.hMonDev;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDev->fAttached = true;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDev->fHiSpeed = pDevExt->Rt.fIsHighSpeed;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync cbOut = sizeof (*pDev);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync else
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_INVALID_PARAMETER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(Status != STATUS_PENDING);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync VBoxDrvToolIoComplete(pIrp, Status, cbOut);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbDdiStateRelease(pDevExt);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic NTSTATUS vboxUsbRtDispatchUsbReset(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PFILE_OBJECT pFObj = pSl->FileObject;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PUSBSUP_GETDEV pDev = (PUSBSUP_GETDEV)pIrp->AssociatedIrp.SystemBuffer;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync NTSTATUS Status = STATUS_SUCCESS;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync do
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!pFObj)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertFailed();
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_INVALID_PARAMETER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!vboxUsbRtCtxIsOwner(pDevExt, pFObj))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertFailed();
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_ACCESS_DENIED;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pIrp->AssociatedIrp.SystemBuffer
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync || pSl->Parameters.DeviceIoControl.InputBufferLength
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync || pSl->Parameters.DeviceIoControl.OutputBufferLength)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertFailed();
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_INVALID_PARAMETER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = VBoxUsbToolIoInternalCtlSendSync(pDevExt->pLowerDO, IOCTL_INTERNAL_USB_RESET_PORT, NULL, NULL);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(NT_SUCCESS(Status));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync } while (0);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(Status != STATUS_PENDING);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync VBoxDrvToolIoComplete(pIrp, Status, 0);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbDdiStateRelease(pDevExt);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic PUSB_CONFIGURATION_DESCRIPTOR vboxUsbRtFindConfigDesc(PVBOXUSBDEV_EXT pDevExt, uint8_t uConfiguration)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PUSB_CONFIGURATION_DESCRIPTOR pCfgDr = NULL;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync for (ULONG i = 0; i < VBOXUSBRT_MAX_CFGS; ++i)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pDevExt->Rt.cfgdescr[i])
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pDevExt->Rt.cfgdescr[i]->bConfigurationValue == uConfiguration)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pCfgDr = pDevExt->Rt.cfgdescr[i];
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return pCfgDr;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic NTSTATUS vboxUsbRtSetConfig(PVBOXUSBDEV_EXT pDevExt, uint8_t uConfiguration)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PURB pUrb = NULL;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync NTSTATUS Status = STATUS_SUCCESS;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync uint32_t i;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!uConfiguration)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb = VBoxUsbToolUrbAllocZ(URB_FUNCTION_SELECT_CONFIGURATION, sizeof (struct _URB_SELECT_CONFIGURATION));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if(!pUrb)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": VBoxUsbToolUrbAlloc failed\n"));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return STATUS_INSUFFICIENT_RESOURCES;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbRtFreeInterfaces(pDevExt, TRUE);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbSelectConfiguration.ConfigurationDescriptor = NULL;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
e04781b223e38e3b0c386d7e7c1dd7f30e9f6e90vboxsync Status = VBoxUsbToolUrbPost(pDevExt->pLowerDO, pUrb, RT_INDEFINITE_WAIT);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if(NT_SUCCESS(Status) && USBD_SUCCESS(pUrb->UrbHeader.Status))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.hConfiguration = pUrb->UrbSelectConfiguration.ConfigurationHandle;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.uConfigValue = uConfiguration;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync else
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": VBoxUsbToolUrbPost failed Status (0x%x), usb Status (0x%x)\n", Status, pUrb->UrbHeader.Status));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync VBoxUsbToolUrbFree(pUrb);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PUSB_CONFIGURATION_DESCRIPTOR pCfgDr = vboxUsbRtFindConfigDesc(pDevExt, uConfiguration);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!pCfgDr)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": VBoxUSBFindConfigDesc did not find cfg (%d)\n", uConfiguration));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return STATUS_INVALID_PARAMETER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PUSBD_INTERFACE_LIST_ENTRY pIfLe = (PUSBD_INTERFACE_LIST_ENTRY)vboxUsbMemAllocZ((pCfgDr->bNumInterfaces + 1) * sizeof(USBD_INTERFACE_LIST_ENTRY));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!pIfLe)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": vboxUsbMemAllocZ for pIfLe failed\n"));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return STATUS_INSUFFICIENT_RESOURCES;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
4660185b061706d3534165ebf4f6039d9293fa2avboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync for (i = 0; i < pCfgDr->bNumInterfaces; i++)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pIfLe[i].InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(pCfgDr, pCfgDr, i, 0, -1, -1, -1);
6594fa9834a20895966c8226893b08f5273c5d4dvboxsync pIfLe[i].Interface = NULL;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!pIfLe[i].InterfaceDescriptor)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": interface %d not found\n", i));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_INVALID_PARAMETER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
6594fa9834a20895966c8226893b08f5273c5d4dvboxsync pIfLe[pCfgDr->bNumInterfaces].InterfaceDescriptor = NULL;
6594fa9834a20895966c8226893b08f5273c5d4dvboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (NT_SUCCESS(Status))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb = USBD_CreateConfigurationRequestEx(pCfgDr, pIfLe);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pUrb)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
e04781b223e38e3b0c386d7e7c1dd7f30e9f6e90vboxsync Status = VBoxUsbToolUrbPost(pDevExt->pLowerDO, pUrb, RT_INDEFINITE_WAIT);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (NT_SUCCESS(Status) && USBD_SUCCESS(pUrb->UrbHeader.Status))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbRtFreeInterfaces(pDevExt, FALSE);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.hConfiguration = pUrb->UrbSelectConfiguration.ConfigurationHandle;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.uConfigValue = uConfiguration;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.uNumInterfaces = pCfgDr->bNumInterfaces;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.pVBIfaceInfo = (VBOXUSB_IFACE_INFO*)vboxUsbMemAllocZ(pDevExt->Rt.uNumInterfaces * sizeof (VBOXUSB_IFACE_INFO));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pDevExt->Rt.pVBIfaceInfo)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(NT_SUCCESS(Status));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync for (i = 0; i < pDevExt->Rt.uNumInterfaces; i++)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
6594fa9834a20895966c8226893b08f5273c5d4dvboxsync size_t uTotalIfaceInfoLength = RT_OFFSETOF(struct _USBD_INTERFACE_INFORMATION, Pipes[RT_MAX(pIfLe[i].Interface->NumberOfPipes, 1)]);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo = (PUSBD_INTERFACE_INFORMATION)vboxUsbMemAlloc(uTotalIfaceInfoLength);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": vboxUsbMemAlloc failed\n"));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_INSUFFICIENT_RESOURCES;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pIfLe[i].Interface->NumberOfPipes > 0)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.pVBIfaceInfo[i].pPipeInfo = (VBOXUSB_PIPE_INFO *)vboxUsbMemAlloc(pIfLe[i].Interface->NumberOfPipes * sizeof(VBOXUSB_PIPE_INFO));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!pDevExt->Rt.pVBIfaceInfo[i].pPipeInfo)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": vboxUsbMemAlloc failed\n"));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_NO_MEMORY;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync else
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.pVBIfaceInfo[i].pPipeInfo = NULL;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
6594fa9834a20895966c8226893b08f5273c5d4dvboxsync
6594fa9834a20895966c8226893b08f5273c5d4dvboxsync RtlCopyMemory(pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo, pIfLe[i].Interface, uTotalIfaceInfoLength);
6594fa9834a20895966c8226893b08f5273c5d4dvboxsync
6594fa9834a20895966c8226893b08f5273c5d4dvboxsync for (ULONG j = 0; j < pIfLe[i].Interface->NumberOfPipes; j++)
6594fa9834a20895966c8226893b08f5273c5d4dvboxsync {
6594fa9834a20895966c8226893b08f5273c5d4dvboxsync pDevExt->Rt.pVBIfaceInfo[i].pPipeInfo[j].EndpointAddress = pIfLe[i].Interface->Pipes[j].EndpointAddress;
6594fa9834a20895966c8226893b08f5273c5d4dvboxsync pDevExt->Rt.pVBIfaceInfo[i].pPipeInfo[j].NextScheduledFrame = 0;
6594fa9834a20895966c8226893b08f5273c5d4dvboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync// if (NT_SUCCESS(Status))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync// {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync//
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync// }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync else
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": vboxUsbMemAllocZ failed\n"));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_NO_MEMORY;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync else
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": VBoxUsbToolUrbPost failed Status (0x%x), usb Status (0x%x)\n", Status, pUrb->UrbHeader.Status));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync ExFreePool(pUrb);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync else
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": USBD_CreateConfigurationRequestEx failed\n"));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_INSUFFICIENT_RESOURCES;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbMemFree(pIfLe);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic NTSTATUS vboxUsbRtDispatchUsbSetConfig(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PFILE_OBJECT pFObj = pSl->FileObject;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PUSBSUP_SET_CONFIG pCfg = (PUSBSUP_SET_CONFIG)pIrp->AssociatedIrp.SystemBuffer;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync NTSTATUS Status = STATUS_SUCCESS;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync do
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!pFObj)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertFailed();
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_INVALID_PARAMETER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!vboxUsbRtCtxIsOwner(pDevExt, pFObj))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertFailed();
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_ACCESS_DENIED;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if ( !pCfg
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync || pSl->Parameters.DeviceIoControl.InputBufferLength != sizeof (*pCfg)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync || pSl->Parameters.DeviceIoControl.OutputBufferLength != 0)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": STATUS_INVALID_PARAMETER\n"));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_INVALID_PARAMETER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = vboxUsbRtSetConfig(pDevExt, pCfg->bConfigurationValue);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync } while (0);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(Status != STATUS_PENDING);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync VBoxDrvToolIoComplete(pIrp, Status, 0);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbDdiStateRelease(pDevExt);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic NTSTATUS vboxUsbRtSetInterface(PVBOXUSBDEV_EXT pDevExt, uint32_t InterfaceNumber, int AlternateSetting)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!pDevExt->Rt.uConfigValue)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": Can't select an interface without an active configuration\n"));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return STATUS_INVALID_PARAMETER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (InterfaceNumber >= pDevExt->Rt.uNumInterfaces)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": InterfaceNumber %d too high!!\n", InterfaceNumber));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return STATUS_INVALID_PARAMETER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PUSB_CONFIGURATION_DESCRIPTOR pCfgDr = vboxUsbRtFindConfigDesc(pDevExt, pDevExt->Rt.uConfigValue);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!pCfgDr)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": configuration %d not found!!\n", pDevExt->Rt.uConfigValue));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return STATUS_INVALID_PARAMETER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PUSB_INTERFACE_DESCRIPTOR pIfDr = USBD_ParseConfigurationDescriptorEx(pCfgDr, pCfgDr, InterfaceNumber, AlternateSetting, -1, -1, -1);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!pIfDr)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": invalid interface %d or alternate setting %d\n", InterfaceNumber, AlternateSetting));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return STATUS_UNSUCCESSFUL;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync USHORT uUrbSize = GET_SELECT_INTERFACE_REQUEST_SIZE(pIfDr->bNumEndpoints);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync ULONG uTotalIfaceInfoLength = GET_USBD_INTERFACE_SIZE(pIfDr->bNumEndpoints);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync NTSTATUS Status = STATUS_SUCCESS;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PURB pUrb = VBoxUsbToolUrbAllocZ(0, uUrbSize);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!pUrb)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": VBoxUsbToolUrbAlloc failed\n"));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return STATUS_NO_MEMORY;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync /*
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * Free old interface and pipe info, allocate new again
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pInterfaceInfo)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync /* Clear pipes associated with the interface, else Windows may hang. */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync for(ULONG i = 0; i < pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pInterfaceInfo->NumberOfPipes; i++)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync VBoxUsbToolPipeClear(pDevExt->pLowerDO, pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pInterfaceInfo->Pipes[i].PipeHandle, FALSE);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbMemFree(pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pInterfaceInfo);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pPipeInfo)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbMemFree(pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pPipeInfo);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pInterfaceInfo = (PUSBD_INTERFACE_INFORMATION)vboxUsbMemAlloc(uTotalIfaceInfoLength);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pInterfaceInfo)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pIfDr->bNumEndpoints > 0)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pPipeInfo = (VBOXUSB_PIPE_INFO*)vboxUsbMemAlloc(pIfDr->bNumEndpoints * sizeof(VBOXUSB_PIPE_INFO));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pPipeInfo)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed(("VBoxUSBSetInterface: ExAllocatePool failed!\n"));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_NO_MEMORY;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync else
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pPipeInfo = NULL;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (NT_SUCCESS(Status))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync UsbBuildSelectInterfaceRequest(pUrb, uUrbSize, pDevExt->Rt.hConfiguration, InterfaceNumber, AlternateSetting);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbSelectInterface.Interface.Length = GET_USBD_INTERFACE_SIZE(pIfDr->bNumEndpoints);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
e04781b223e38e3b0c386d7e7c1dd7f30e9f6e90vboxsync Status = VBoxUsbToolUrbPost(pDevExt->pLowerDO, pUrb, RT_INDEFINITE_WAIT);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (NT_SUCCESS(Status) && USBD_SUCCESS(pUrb->UrbHeader.Status))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync USBD_INTERFACE_INFORMATION *pIfInfo = &pUrb->UrbSelectInterface.Interface;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync memcpy(pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pInterfaceInfo, pIfInfo, GET_USBD_INTERFACE_SIZE(pIfDr->bNumEndpoints));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(pIfInfo->NumberOfPipes == pIfDr->bNumEndpoints);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync for(ULONG i = 0; i < pIfInfo->NumberOfPipes; i++)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pInterfaceInfo->Pipes[i] = pIfInfo->Pipes[i];
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pPipeInfo[i].EndpointAddress = pIfInfo->Pipes[i].EndpointAddress;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pDevExt->Rt.pVBIfaceInfo[InterfaceNumber].pPipeInfo[i].NextScheduledFrame = 0;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync else
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": VBoxUsbToolUrbPost failed Status (0x%x) usb Status (0x%x)\n", Status, pUrb->UrbHeader.Status));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync else
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed(("VBoxUSBSetInterface: ExAllocatePool failed!\n"));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_NO_MEMORY;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync VBoxUsbToolUrbFree(pUrb);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic NTSTATUS vboxUsbRtDispatchUsbSelectInterface(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PFILE_OBJECT pFObj = pSl->FileObject;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PUSBSUP_SELECT_INTERFACE pIf = (PUSBSUP_SELECT_INTERFACE)pIrp->AssociatedIrp.SystemBuffer;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync NTSTATUS Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync do
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!pFObj)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertFailed();
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_INVALID_PARAMETER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!vboxUsbRtCtxIsOwner(pDevExt, pFObj))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertFailed();
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_ACCESS_DENIED;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if ( !pIf
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync || pSl->Parameters.DeviceIoControl.InputBufferLength != sizeof (*pIf)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync || pSl->Parameters.DeviceIoControl.OutputBufferLength != 0)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": STATUS_INVALID_PARAMETER\n"));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_INVALID_PARAMETER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = vboxUsbRtSetInterface(pDevExt, pIf->bInterfaceNumber, pIf->bAlternateSetting);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync } while (0);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(Status != STATUS_PENDING);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync VBoxDrvToolIoComplete(pIrp, Status, 0);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbDdiStateRelease(pDevExt);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic HANDLE vboxUsbRtGetPipeHandle(PVBOXUSBDEV_EXT pDevExt, uint32_t EndPointAddress)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync for (ULONG i = 0; i < pDevExt->Rt.uNumInterfaces; i++)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync for (ULONG j = 0; j < pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo->NumberOfPipes; j++)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync /* Note that bit 7 determines pipe direction, but is still significant
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * because endpoints may be numbered like 0x01, 0x81, 0x02, 0x82 etc.
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo->Pipes[j].EndpointAddress == EndPointAddress)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo->Pipes[j].PipeHandle;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return 0;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic VBOXUSB_PIPE_INFO* vboxUsbRtGetPipeInfo(PVBOXUSBDEV_EXT pDevExt, uint32_t EndPointAddress)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync for (ULONG i = 0; i < pDevExt->Rt.uNumInterfaces; i++)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync for (ULONG j = 0; j < pDevExt->Rt.pVBIfaceInfo[i].pInterfaceInfo->NumberOfPipes; j++)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pDevExt->Rt.pVBIfaceInfo[i].pPipeInfo[j].EndpointAddress == EndPointAddress)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return &pDevExt->Rt.pVBIfaceInfo[i].pPipeInfo[j];
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return NULL;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic NTSTATUS vboxUsbRtClearEndpoint(PVBOXUSBDEV_EXT pDevExt, uint32_t EndPointAddress, bool fReset)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync NTSTATUS Status = VBoxUsbToolPipeClear(pDevExt->pLowerDO, vboxUsbRtGetPipeHandle(pDevExt, EndPointAddress), fReset);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!NT_SUCCESS(Status))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": VBoxUsbToolPipeClear failed Status (0x%x)\n", Status));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic NTSTATUS vboxUsbRtDispatchUsbClearEndpoint(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PFILE_OBJECT pFObj = pSl->FileObject;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PUSBSUP_CLEAR_ENDPOINT pCe = (PUSBSUP_CLEAR_ENDPOINT)pIrp->AssociatedIrp.SystemBuffer;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync NTSTATUS Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync do
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!pFObj)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertFailed();
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_INVALID_PARAMETER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!vboxUsbRtCtxIsOwner(pDevExt, pFObj))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertFailed();
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_ACCESS_DENIED;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if ( !pCe
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync || pSl->Parameters.DeviceIoControl.InputBufferLength != sizeof (*pCe)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync || pSl->Parameters.DeviceIoControl.OutputBufferLength != 0)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": STATUS_INVALID_PARAMETER\n"));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_INVALID_PARAMETER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = vboxUsbRtClearEndpoint(pDevExt, pCe->bEndpoint, TRUE);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync } while (0);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(Status != STATUS_PENDING);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync VBoxDrvToolIoComplete(pIrp, Status, 0);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbDdiStateRelease(pDevExt);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic NTSTATUS vboxUsbRtDispatchUsbAbortEndpoint(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PFILE_OBJECT pFObj = pSl->FileObject;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PUSBSUP_CLEAR_ENDPOINT pCe = (PUSBSUP_CLEAR_ENDPOINT)pIrp->AssociatedIrp.SystemBuffer;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync NTSTATUS Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync do
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!pFObj)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertFailed();
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_INVALID_PARAMETER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!vboxUsbRtCtxIsOwner(pDevExt, pFObj))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertFailed();
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_ACCESS_DENIED;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if ( !pCe
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync || pSl->Parameters.DeviceIoControl.InputBufferLength != sizeof (*pCe)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync || pSl->Parameters.DeviceIoControl.OutputBufferLength != 0)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": STATUS_INVALID_PARAMETER\n"));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_INVALID_PARAMETER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = vboxUsbRtClearEndpoint(pDevExt, pCe->bEndpoint, FALSE);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync } while (0);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(Status != STATUS_PENDING);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync VBoxDrvToolIoComplete(pIrp, Status, 0);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbDdiStateRelease(pDevExt);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic NTSTATUS vboxUsbRtUrbSendCompletion(PDEVICE_OBJECT pDevObj, IRP *pIrp, void *pvContext)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!pvContext)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": context is NULL\n"));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pIrp->IoStatus.Information = 0;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return STATUS_CONTINUE_COMPLETION;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PVBOXUSB_URB_CONTEXT pContext = (PVBOXUSB_URB_CONTEXT)pvContext;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pContext->ulMagic != VBOXUSB_MAGIC)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": Invalid context magic\n"));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pIrp->IoStatus.Information = 0;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return STATUS_CONTINUE_COMPLETION;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PURB pUrb = pContext->pUrb;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PMDL pMdlBuf = pContext->pMdlBuf;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PUSBSUP_URB pUrbInfo = (PUSBSUP_URB)pContext->pOut;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PVBOXUSBDEV_EXT pDevExt = pContext->pDevExt;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!pUrb || !pMdlBuf || !pUrbInfo | !pDevExt)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": Invalid args\n"));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pDevExt)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbDdiStateRelease(pDevExt);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pIrp->IoStatus.Information = 0;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return STATUS_CONTINUE_COMPLETION;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync NTSTATUS Status = pIrp->IoStatus.Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (Status == STATUS_SUCCESS)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync switch(pUrb->UrbHeader.Status)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBD_STATUS_CRC:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrbInfo->error = USBSUP_XFER_CRC;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBD_STATUS_SUCCESS:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrbInfo->error = USBSUP_XFER_OK;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBD_STATUS_STALL_PID:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrbInfo->error = USBSUP_XFER_STALL;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBD_STATUS_INVALID_URB_FUNCTION:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBD_STATUS_INVALID_PARAMETER:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": sw error, urb Status (0x%x)\n", pUrb->UrbHeader.Status));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBD_STATUS_DEV_NOT_RESPONDING:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync default:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrbInfo->error = USBSUP_XFER_DNR;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync switch(pContext->ulTransferType)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBSUP_TRANSFER_TYPE_CTRL:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBSUP_TRANSFER_TYPE_MSG:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrbInfo->len = pUrb->UrbControlTransfer.TransferBufferLength;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pContext->ulTransferType == USBSUP_TRANSFER_TYPE_MSG)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync /* QUSB_TRANSFER_TYPE_MSG is a control transfer, but it is special
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * the first 8 bytes of the buffer is the setup packet so the real
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * data length is therefore urb->len - 8
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrbInfo->len += sizeof (pUrb->UrbControlTransfer.SetupPacket);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBSUP_TRANSFER_TYPE_ISOC:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrbInfo->len = pUrb->UrbIsochronousTransfer.TransferBufferLength;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBSUP_TRANSFER_TYPE_BULK:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBSUP_TRANSFER_TYPE_INTR:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pUrbInfo->dir == USBSUP_DIRECTION_IN && pUrbInfo->error == USBSUP_XFER_OK
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync && !(pUrbInfo->flags & USBSUP_FLAG_SHORT_OK)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync && pUrbInfo->len > pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync )
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync /* If we don't use the USBD_SHORT_TRANSFER_OK flag, the returned buffer lengths are
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * wrong for short transfers (always a multiple of max packet size?). So we just figure
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * out if this was a data underrun on our own.
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrbInfo->error = USBSUP_XFER_UNDERRUN;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrbInfo->len = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync default:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync else
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrbInfo->len = 0;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Log((__FUNCTION__": URB failed Status (0x%x) urb Status (0x%x)\n", Status, pUrb->UrbHeader.Status));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync#ifdef DEBUG
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync switch(pContext->ulTransferType)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBSUP_TRANSFER_TYPE_CTRL:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBSUP_TRANSFER_TYPE_MSG:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync LogRel(("Ctrl/Msg length=%d\n", pUrb->UrbControlTransfer.TransferBufferLength));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBSUP_TRANSFER_TYPE_ISOC:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync LogRel(("ISOC length=%d\n", pUrb->UrbIsochronousTransfer.TransferBufferLength));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBSUP_TRANSFER_TYPE_BULK:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBSUP_TRANSFER_TYPE_INTR:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync LogRel(("BULK/INTR length=%d\n", pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync#endif
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync switch(pUrb->UrbHeader.Status)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBD_STATUS_CRC:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrbInfo->error = USBSUP_XFER_CRC;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_SUCCESS;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBD_STATUS_STALL_PID:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrbInfo->error = USBSUP_XFER_STALL;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_SUCCESS;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBD_STATUS_DEV_NOT_RESPONDING:
1d2d0112a43cf3bec74a2cf81134c215e9d1d72fvboxsync case USBD_STATUS_DEVICE_GONE:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrbInfo->error = USBSUP_XFER_DNR;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_SUCCESS;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case ((USBD_STATUS)0xC0010000L): // USBD_STATUS_CANCELED - too bad usbdi.h and usb.h aren't consistent!
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync // TODO: What the heck are we really supposed to do here?
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrbInfo->error = USBSUP_XFER_STALL;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_SUCCESS;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBD_STATUS_BAD_START_FRAME: // This one really shouldn't happen
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBD_STATUS_ISOCH_REQUEST_FAILED:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrbInfo->error = USBSUP_XFER_NAC;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_SUCCESS;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync default:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": err Status (0x%x) (0x%x)\n", Status, pUrb->UrbHeader.Status));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrbInfo->error = USBSUP_XFER_DNR;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_SUCCESS;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync // For isochronous transfers, always update the individual packets
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pContext->ulTransferType == USBSUP_TRANSFER_TYPE_ISOC)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(pUrbInfo->numIsoPkts == pUrb->UrbIsochronousTransfer.NumberOfPackets);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync for (ULONG i = 0; i < pUrbInfo->numIsoPkts; ++i)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(pUrbInfo->aIsoPkts[i].off == pUrb->UrbIsochronousTransfer.IsoPacket[i].Offset);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrbInfo->aIsoPkts[i].cb = (uint16_t)pUrb->UrbIsochronousTransfer.IsoPacket[i].Length;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync switch (pUrb->UrbIsochronousTransfer.IsoPacket[i].Status)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBD_STATUS_SUCCESS:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrbInfo->aIsoPkts[i].stat = USBSUP_XFER_OK;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBD_STATUS_NOT_ACCESSED:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrbInfo->aIsoPkts[i].stat = USBSUP_XFER_NAC;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync default:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrbInfo->aIsoPkts[i].stat = USBSUP_XFER_STALL;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync MmUnlockPages(pMdlBuf);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync IoFreeMdl(pMdlBuf);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbMemFree(pContext);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbDdiStateRelease(pDevExt);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(pIrp->IoStatus.Status != STATUS_IO_TIMEOUT);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pIrp->IoStatus.Information = sizeof(*pUrbInfo);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pIrp->IoStatus.Status = Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return STATUS_CONTINUE_COMPLETION;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic NTSTATUS vboxUsbRtUrbSend(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp, PUSBSUP_URB pUrbInfo)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync NTSTATUS Status = STATUS_SUCCESS;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PVBOXUSB_URB_CONTEXT pContext = NULL;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PMDL pMdlBuf = NULL;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync ULONG cbUrb;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(pUrbInfo);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pUrbInfo->type == USBSUP_TRANSFER_TYPE_ISOC)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(pUrbInfo->numIsoPkts <= 8);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync cbUrb = GET_ISO_URB_SIZE(pUrbInfo->numIsoPkts);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync else
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync cbUrb = sizeof (URB);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync do
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pContext = (PVBOXUSB_URB_CONTEXT)vboxUsbMemAllocZ(cbUrb + sizeof (VBOXUSB_URB_CONTEXT));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!pContext)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": vboxUsbMemAlloc failed\n"));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_INSUFFICIENT_RESOURCES;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PURB pUrb = (PURB)(pContext + 1);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync HANDLE hPipe = NULL;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pUrbInfo->ep)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync hPipe = vboxUsbRtGetPipeHandle(pDevExt, pUrbInfo->ep | ((pUrbInfo->dir == USBSUP_DIRECTION_IN) ? 0x80 : 0x00));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!hPipe)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": vboxUsbRtGetPipeHandle failed for endpoint (0x%x)\n", pUrbInfo->ep));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_INVALID_PARAMETER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pMdlBuf = IoAllocateMdl(pUrbInfo->buf, (ULONG)pUrbInfo->len, FALSE, FALSE, NULL);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!pMdlBuf)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": IoAllocateMdl failed for buffer (0x%p) length (%d)\n", pUrbInfo->buf, pUrbInfo->len));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_INSUFFICIENT_RESOURCES;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync __try
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync MmProbeAndLockPages(pMdlBuf, KernelMode, IoModifyAccess);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync __except(EXCEPTION_EXECUTE_HANDLER)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = GetExceptionCode();
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync IoFreeMdl(pMdlBuf);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pMdlBuf = NULL;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": Exception Code (0x%x)\n", Status));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync /* For some reason, passing a MDL in the URB does not work reliably. Notably
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * the iPhone when used with iTunes fails.
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PVOID pBuffer = MmGetSystemAddressForMdlSafe(pMdlBuf, NormalPagePriority);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!pBuffer)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": MmGetSystemAddressForMdlSafe failed\n"));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_INSUFFICIENT_RESOURCES;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync switch (pUrbInfo->type)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBSUP_TRANSFER_TYPE_CTRL:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBSUP_TRANSFER_TYPE_MSG:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbHeader.Function = URB_FUNCTION_CONTROL_TRANSFER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbHeader.Length = sizeof (struct _URB_CONTROL_TRANSFER);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbControlTransfer.PipeHandle = hPipe;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbControlTransfer.TransferBufferLength = (ULONG)pUrbInfo->len;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbControlTransfer.TransferFlags = ((pUrbInfo->dir == USBSUP_DIRECTION_IN) ? USBD_TRANSFER_DIRECTION_IN : USBD_TRANSFER_DIRECTION_OUT);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbControlTransfer.UrbLink = 0;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!hPipe)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbControlTransfer.TransferFlags |= USBD_DEFAULT_PIPE_TRANSFER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pUrbInfo->type == USBSUP_TRANSFER_TYPE_MSG)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync /* QUSB_TRANSFER_TYPE_MSG is a control transfer, but it is special
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * the first 8 bytes of the buffer is the setup packet so the real
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * data length is therefore pUrb->len - 8
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PVBOXUSB_SETUP pSetup = (PVBOXUSB_SETUP)pUrb->UrbControlTransfer.SetupPacket;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync memcpy(pUrb->UrbControlTransfer.SetupPacket, pBuffer, min(sizeof (pUrb->UrbControlTransfer.SetupPacket), pUrbInfo->len));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pUrb->UrbControlTransfer.TransferBufferLength <= sizeof (pUrb->UrbControlTransfer.SetupPacket))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbControlTransfer.TransferBufferLength = 0;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync else
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbControlTransfer.TransferBufferLength -= sizeof (pUrb->UrbControlTransfer.SetupPacket);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbControlTransfer.TransferBuffer = (uint8_t *)pBuffer + sizeof(pUrb->UrbControlTransfer.SetupPacket);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbControlTransfer.TransferBufferMDL = 0;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbControlTransfer.TransferFlags |= USBD_SHORT_TRANSFER_OK;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync else
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbControlTransfer.TransferBuffer = 0;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbControlTransfer.TransferBufferMDL = pMdlBuf;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBSUP_TRANSFER_TYPE_ISOC:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(pUrbInfo->dir == USBSUP_DIRECTION_IN || pUrbInfo->type == USBSUP_TRANSFER_TYPE_BULK);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(hPipe);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync VBOXUSB_PIPE_INFO *pPipeInfo = vboxUsbRtGetPipeInfo(pDevExt, pUrbInfo->ep | ((pUrbInfo->dir == USBSUP_DIRECTION_IN) ? 0x80 : 0x00));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pPipeInfo == NULL)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync /* Can happen if the isoc request comes in too early or late. */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": pPipeInfo not found\n"));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_INVALID_PARAMETER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbHeader.Function = URB_FUNCTION_ISOCH_TRANSFER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbHeader.Length = (USHORT)cbUrb;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbIsochronousTransfer.PipeHandle = hPipe;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbIsochronousTransfer.TransferBufferLength = (ULONG)pUrbInfo->len;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbIsochronousTransfer.TransferBufferMDL = 0;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbIsochronousTransfer.TransferBuffer = pBuffer;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbIsochronousTransfer.TransferFlags = ((pUrbInfo->dir == USBSUP_DIRECTION_IN) ? USBD_TRANSFER_DIRECTION_IN : USBD_TRANSFER_DIRECTION_OUT);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbIsochronousTransfer.TransferFlags |= USBD_SHORT_TRANSFER_OK; // May be implied already
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbIsochronousTransfer.NumberOfPackets = pUrbInfo->numIsoPkts;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbIsochronousTransfer.ErrorCount = 0;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbIsochronousTransfer.UrbLink = 0;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(pUrbInfo->numIsoPkts == pUrb->UrbIsochronousTransfer.NumberOfPackets);
9ec0abcc252ba1216f255b2be6650cceb00c1d46vboxsync for (ULONG i = 0; i < pUrbInfo->numIsoPkts; ++i)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbIsochronousTransfer.IsoPacket[i].Offset = pUrbInfo->aIsoPkts[i].off;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbIsochronousTransfer.IsoPacket[i].Length = pUrbInfo->aIsoPkts[i].cb;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync /* We have to schedule the URBs ourselves. There is an ASAP flag but
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * that can only be reliably used after pipe creation/reset, ie. it's
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * almost completely useless.
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync ULONG iFrame, iStartFrame;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync VBoxUsbToolCurrentFrame(pDevExt->pLowerDO, pIrp, &iFrame);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync iFrame += 2;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync iStartFrame = pPipeInfo->NextScheduledFrame;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if ((iFrame < iStartFrame) || (iStartFrame > iFrame + 512))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync iFrame = iStartFrame;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pPipeInfo->NextScheduledFrame = iFrame + pUrbInfo->numIsoPkts;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbIsochronousTransfer.StartFrame = iFrame;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBSUP_TRANSFER_TYPE_BULK:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case USBSUP_TRANSFER_TYPE_INTR:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(pUrbInfo->dir != USBSUP_DIRECTION_SETUP);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(pUrbInfo->dir == USBSUP_DIRECTION_IN || pUrbInfo->type == USBSUP_TRANSFER_TYPE_BULK);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(hPipe);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbHeader.Function = URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbHeader.Length = sizeof (struct _URB_BULK_OR_INTERRUPT_TRANSFER);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbBulkOrInterruptTransfer.PipeHandle = hPipe;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength = (ULONG)pUrbInfo->len;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbBulkOrInterruptTransfer.TransferBufferMDL = 0;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbBulkOrInterruptTransfer.TransferBuffer = pBuffer;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbBulkOrInterruptTransfer.TransferFlags = ((pUrbInfo->dir == USBSUP_DIRECTION_IN) ? USBD_TRANSFER_DIRECTION_IN : USBD_TRANSFER_DIRECTION_OUT);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pUrb->UrbBulkOrInterruptTransfer.TransferFlags & USBD_TRANSFER_DIRECTION_IN)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbBulkOrInterruptTransfer.TransferFlags |= (USBD_SHORT_TRANSFER_OK);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pUrb->UrbBulkOrInterruptTransfer.UrbLink = 0;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync default:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertFailed();
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_INVALID_PARAMETER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!NT_SUCCESS(Status))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pContext->pDevExt = pDevExt;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pContext->pMdlBuf = pMdlBuf;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pContext->pUrb = pUrb;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pContext->pOut = pUrbInfo;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pContext->ulTransferType = pUrbInfo->type;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pContext->ulMagic = VBOXUSB_MAGIC;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PIO_STACK_LOCATION pSl = IoGetNextIrpStackLocation(pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pSl->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pSl->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pSl->Parameters.Others.Argument1 = pUrb;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pSl->Parameters.Others.Argument2 = NULL;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync IoSetCompletionRoutine(pIrp, vboxUsbRtUrbSendCompletion, pContext, TRUE, TRUE, TRUE);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync IoMarkIrpPending(pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = IoCallDriver(pDevExt->pLowerDO, pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsg(NT_SUCCESS(Status), (__FUNCTION__": IoCallDriver failed Status (0x%x)\n", Status));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return STATUS_PENDING;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync } while (0);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(!NT_SUCCESS(Status));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pMdlBuf)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync MmUnlockPages(pMdlBuf);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync IoFreeMdl(pMdlBuf);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pContext)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbMemFree(pContext);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync VBoxDrvToolIoComplete(pIrp, Status, 0);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbDdiStateRelease(pDevExt);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic NTSTATUS vboxUsbRtDispatchSendUrb(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PFILE_OBJECT pFObj = pSl->FileObject;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PUSBSUP_URB pUrbInfo = (PUSBSUP_URB)pIrp->AssociatedIrp.SystemBuffer;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync NTSTATUS Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync do
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!pFObj)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertFailed();
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_INVALID_PARAMETER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!vboxUsbRtCtxIsOwner(pDevExt, pFObj))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertFailed();
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_ACCESS_DENIED;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if ( !pUrbInfo
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync || pSl->Parameters.DeviceIoControl.InputBufferLength != sizeof (*pUrbInfo)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync || pSl->Parameters.DeviceIoControl.OutputBufferLength != sizeof (*pUrbInfo))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": STATUS_INVALID_PARAMETER\n"));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_INVALID_PARAMETER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync break;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return vboxUsbRtUrbSend(pDevExt, pIrp, pUrbInfo);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync } while (0);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(Status != STATUS_PENDING);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync VBoxDrvToolIoComplete(pIrp, Status, 0);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbDdiStateRelease(pDevExt);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic NTSTATUS vboxUsbRtDispatchIsOperational(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync VBoxDrvToolIoComplete(pIrp, STATUS_SUCCESS, 0);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbDdiStateRelease(pDevExt);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return STATUS_SUCCESS;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic NTSTATUS vboxUsbRtDispatchGetVersion(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PUSBSUP_VERSION pVer= (PUSBSUP_VERSION)pIrp->AssociatedIrp.SystemBuffer;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync NTSTATUS Status = STATUS_SUCCESS;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (pVer && pSl->Parameters.DeviceIoControl.InputBufferLength == 0
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync && pSl->Parameters.DeviceIoControl.OutputBufferLength == sizeof (*pVer))
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pVer->u32Major = USBDRV_MAJOR_VERSION;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync pVer->u32Minor = USBDRV_MINOR_VERSION;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync else
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertMsgFailed((__FUNCTION__": STATUS_INVALID_PARAMETER\n"));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Status = STATUS_INVALID_PARAMETER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(Status != STATUS_PENDING);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync VBoxDrvToolIoComplete(pIrp, Status, sizeof (*pVer));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbDdiStateRelease(pDevExt);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return Status;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic NTSTATUS vboxUsbRtDispatchDefault(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync VBoxDrvToolIoComplete(pIrp, STATUS_INVALID_DEVICE_REQUEST, 0);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbDdiStateRelease(pDevExt);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return STATUS_INVALID_DEVICE_REQUEST;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncDECLHIDDEN(NTSTATUS) vboxUsbRtCreate(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PFILE_OBJECT pFObj = pSl->FileObject;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync if (!pFObj)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync AssertFailed();
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return STATUS_INVALID_PARAMETER;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return STATUS_SUCCESS;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncDECLHIDDEN(NTSTATUS) vboxUsbRtClose(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PFILE_OBJECT pFObj = pSl->FileObject;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync Assert(pFObj);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync vboxUsbRtCtxReleaseOwner(pDevExt, pFObj);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return STATUS_SUCCESS;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncDECLHIDDEN(NTSTATUS) vboxUsbRtDispatch(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync{
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync switch (pSl->Parameters.DeviceIoControl.IoControlCode)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case SUPUSB_IOCTL_USB_CLAIM_DEVICE:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return vboxUsbRtDispatchClaimDevice(pDevExt, pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case SUPUSB_IOCTL_USB_RELEASE_DEVICE:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return vboxUsbRtDispatchReleaseDevice(pDevExt, pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case SUPUSB_IOCTL_GET_DEVICE:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return vboxUsbRtDispatchGetDevice(pDevExt, pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case SUPUSB_IOCTL_USB_RESET:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return vboxUsbRtDispatchUsbReset(pDevExt, pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case SUPUSB_IOCTL_USB_SET_CONFIG:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return vboxUsbRtDispatchUsbSetConfig(pDevExt, pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case SUPUSB_IOCTL_USB_SELECT_INTERFACE:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return vboxUsbRtDispatchUsbSelectInterface(pDevExt, pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case SUPUSB_IOCTL_USB_CLEAR_ENDPOINT:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return vboxUsbRtDispatchUsbClearEndpoint(pDevExt, pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case SUPUSB_IOCTL_USB_ABORT_ENDPOINT:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return vboxUsbRtDispatchUsbAbortEndpoint(pDevExt, pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case SUPUSB_IOCTL_SEND_URB:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return vboxUsbRtDispatchSendUrb(pDevExt, pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case SUPUSB_IOCTL_IS_OPERATIONAL:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return vboxUsbRtDispatchIsOperational(pDevExt, pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case SUPUSB_IOCTL_GET_VERSION:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return vboxUsbRtDispatchGetVersion(pDevExt, pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync default:
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync {
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return vboxUsbRtDispatchDefault(pDevExt, pIrp);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync }
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync}