From f215e02bf85f68d3a6106c2a1f4f7f063f819064 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 11 Apr 2024 10:17:27 +0200 Subject: Adding upstream version 7.0.14-dfsg. Signed-off-by: Daniel Baumann --- .../HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.cpp | 357 +++++++++++++++++++++ 1 file changed, 357 insertions(+) create mode 100644 src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.cpp (limited to 'src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.cpp') diff --git a/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.cpp b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.cpp new file mode 100644 index 00000000..680f5d2f --- /dev/null +++ b/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.cpp @@ -0,0 +1,357 @@ +/* $Id: VBoxUsbDev.cpp $ */ +/** @file + * VBoxUsbDev.cpp - USB device. + */ + +/* + * Copyright (C) 2011-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include "VBoxUsbCmn.h" +#include +#include + + +/********************************************************************************************************************************* +* Defined Constants And Macros * +*********************************************************************************************************************************/ +#define VBOXUSB_MEMTAG 'bUBV' + + + +DECLHIDDEN(PVOID) vboxUsbMemAlloc(SIZE_T cbBytes) +{ + PVOID pvMem = ExAllocatePoolWithTag(NonPagedPool, cbBytes, VBOXUSB_MEMTAG); + Assert(pvMem); + return pvMem; +} + +DECLHIDDEN(PVOID) vboxUsbMemAllocZ(SIZE_T cbBytes) +{ + PVOID pvMem = vboxUsbMemAlloc(cbBytes); + if (pvMem) + { + RtlZeroMemory(pvMem, cbBytes); + } + return pvMem; +} + +DECLHIDDEN(VOID) vboxUsbMemFree(PVOID pvMem) +{ + ExFreePoolWithTag(pvMem, VBOXUSB_MEMTAG); +} + +VBOXUSB_GLOBALS g_VBoxUsbGlobals = {0}; + +static NTSTATUS vboxUsbDdiAddDevice(PDRIVER_OBJECT pDriverObject, + PDEVICE_OBJECT pPDO) +{ + PDEVICE_OBJECT pFDO = NULL; + NTSTATUS Status = IoCreateDevice(pDriverObject, + sizeof (VBOXUSBDEV_EXT), + NULL, /* IN PUNICODE_STRING pDeviceName OPTIONAL */ + FILE_DEVICE_UNKNOWN, /* IN DEVICE_TYPE DeviceType */ + FILE_AUTOGENERATED_DEVICE_NAME, /* IN ULONG DeviceCharacteristics */ + FALSE, /* IN BOOLEAN fExclusive */ + &pFDO); + Assert(Status == STATUS_SUCCESS); + if (Status == STATUS_SUCCESS) + { + PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pFDO->DeviceExtension; + /* init Device Object bits */ + pFDO->Flags |= DO_DIRECT_IO; + if (pPDO->Flags & DO_POWER_PAGABLE) + pFDO->Flags |= DO_POWER_PAGABLE; + + + /* now init our state bits */ + + pDevExt->cHandles = 0; + + pDevExt->pFDO = pFDO; + pDevExt->pPDO = pPDO; + pDevExt->pLowerDO = IoAttachDeviceToDeviceStack(pFDO, pPDO); + Assert(pDevExt->pLowerDO); + if (pDevExt->pLowerDO) + { + vboxUsbDdiStateInit(pDevExt); + Status = vboxUsbRtInit(pDevExt); + if (Status == STATUS_SUCCESS) + { + /* we're done! */ + pFDO->Flags &= ~DO_DEVICE_INITIALIZING; + return STATUS_SUCCESS; + } + + IoDetachDevice(pDevExt->pLowerDO); + } + else + Status = STATUS_NO_SUCH_DEVICE; + + IoDeleteDevice(pFDO); + } + + return Status; +} + +static VOID vboxUsbDdiUnload(PDRIVER_OBJECT pDriverObject) +{ + RT_NOREF1(pDriverObject); + LogRel(("VBoxUsb::DriverUnload. Built Date (%s) Time (%s)\n", __DATE__, __TIME__)); + VBoxDrvToolStrFree(&g_VBoxUsbGlobals.RegPath); + + vboxUsbRtGlobalsTerm(); + + PRTLOGGER pLogger = RTLogRelSetDefaultInstance(NULL); + if (pLogger) + { + RTLogDestroy(pLogger); + } + pLogger = RTLogSetDefaultInstance(NULL); + if (pLogger) + { + RTLogDestroy(pLogger); + } +} + +static NTSTATUS vboxUsbDispatchCreate(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) +{ + PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension; + NTSTATUS Status = STATUS_INVALID_HANDLE; + do + { + if (vboxUsbPnPStateGet(pDevExt) != ENMVBOXUSB_PNPSTATE_STARTED) + { + Status = STATUS_INVALID_DEVICE_STATE; + break; + } + + PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp); + PFILE_OBJECT pFObj = pSl->FileObject; + if (!pFObj) + { + Status = STATUS_INVALID_PARAMETER; + break; + } + + pFObj->FsContext = NULL; + + if (pFObj->FileName.Length) + { + Status = STATUS_INVALID_PARAMETER; + break; + } + + Status = vboxUsbRtCreate(pDevExt, pIrp); + if (!NT_SUCCESS(Status)) + { + AssertFailed(); + break; + } + + ASMAtomicIncU32(&pDevExt->cHandles); + Status = STATUS_SUCCESS; + break; + } while (0); + + Status = VBoxDrvToolIoComplete(pIrp, Status, 0); + return Status; +} + +static NTSTATUS vboxUsbDispatchClose(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) +{ + PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension; + NTSTATUS Status = STATUS_SUCCESS; +#ifdef VBOX_STRICT + PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp); + PFILE_OBJECT pFObj = pSl->FileObject; + Assert(pFObj); + Assert(!pFObj->FileName.Length); +#endif + Status = vboxUsbRtClose(pDevExt, pIrp); + if (NT_SUCCESS(Status)) + { + ASMAtomicDecU32(&pDevExt->cHandles); + } + else + { + AssertFailed(); + } + Status = VBoxDrvToolIoComplete(pIrp, Status, 0); + return Status; +} + +static NTSTATUS vboxUsbDispatchDeviceControl(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) +{ + PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension; + if (vboxUsbDdiStateRetainIfStarted(pDevExt)) + return vboxUsbRtDispatch(pDevExt, pIrp); + return VBoxDrvToolIoComplete(pIrp, STATUS_INVALID_DEVICE_STATE, 0); +} + +static NTSTATUS vboxUsbDispatchCleanup(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) +{ + RT_NOREF1(pDeviceObject); + return VBoxDrvToolIoComplete(pIrp, STATUS_SUCCESS, 0); +} + +static NTSTATUS vboxUsbDevAccessDeviedDispatchStub(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) +{ + PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension; + if (!vboxUsbDdiStateRetainIfNotRemoved(pDevExt)) + { + VBoxDrvToolIoComplete(pIrp, STATUS_DELETE_PENDING, 0); + return STATUS_DELETE_PENDING; + } + + NTSTATUS Status = VBoxDrvToolIoComplete(pIrp, STATUS_ACCESS_DENIED, 0); + + vboxUsbDdiStateRelease(pDevExt); + + return Status; +} + +static NTSTATUS vboxUsbDispatchSystemControl(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) +{ + PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension; + if (!vboxUsbDdiStateRetainIfNotRemoved(pDevExt)) + { + VBoxDrvToolIoComplete(pIrp, STATUS_DELETE_PENDING, 0); + return STATUS_DELETE_PENDING; + } + + IoSkipCurrentIrpStackLocation(pIrp); + + NTSTATUS Status = IoCallDriver(pDevExt->pLowerDO, pIrp); + + vboxUsbDdiStateRelease(pDevExt); + + return Status; +} + +static NTSTATUS vboxUsbDispatchRead(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) +{ +#ifdef DEBUG_misha + AssertFailed(); +#endif + return vboxUsbDevAccessDeviedDispatchStub(pDeviceObject, pIrp); +} + +static NTSTATUS vboxUsbDispatchWrite(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) +{ +#ifdef DEBUG_misha + AssertFailed(); +#endif + return vboxUsbDevAccessDeviedDispatchStub(pDeviceObject, pIrp); +} + +RT_C_DECLS_BEGIN + +NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath); + +RT_C_DECLS_END + +NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath) +{ + LogRel(("VBoxUsb::DriverEntry. Built Date (%s) Time (%s)\n", __DATE__, __TIME__)); + + NTSTATUS Status = vboxUsbRtGlobalsInit(); + Assert(Status == STATUS_SUCCESS); + if (Status == STATUS_SUCCESS) + { + Status = VBoxDrvToolStrCopy(&g_VBoxUsbGlobals.RegPath, pRegistryPath); + Assert(Status == STATUS_SUCCESS); + if (Status == STATUS_SUCCESS) + { + g_VBoxUsbGlobals.pDrvObj = pDriverObject; + + pDriverObject->DriverExtension->AddDevice = vboxUsbDdiAddDevice; + + pDriverObject->DriverUnload = vboxUsbDdiUnload; + + pDriverObject->MajorFunction[IRP_MJ_CREATE] = vboxUsbDispatchCreate; + pDriverObject->MajorFunction[IRP_MJ_CLOSE] = vboxUsbDispatchClose; + pDriverObject->MajorFunction[IRP_MJ_READ] = vboxUsbDispatchRead; + pDriverObject->MajorFunction[IRP_MJ_WRITE] = vboxUsbDispatchWrite; + pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = vboxUsbDispatchDeviceControl; + pDriverObject->MajorFunction[IRP_MJ_CLEANUP] = vboxUsbDispatchCleanup; + pDriverObject->MajorFunction[IRP_MJ_POWER] = vboxUsbDispatchPower; + pDriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = vboxUsbDispatchSystemControl; + pDriverObject->MajorFunction[IRP_MJ_PNP] = vboxUsbDispatchPnP; + + return STATUS_SUCCESS; + } + vboxUsbRtGlobalsTerm(); + } + + LogRel(("VBoxUsb::DriverEntry. failed with Status (0x%x)\n", Status)); + + return Status; +} + +#ifdef VBOX_STRICT +DECLHIDDEN(VOID) vboxUsbPnPStateGbgChange(ENMVBOXUSB_PNPSTATE enmOldState, ENMVBOXUSB_PNPSTATE enmNewState) +{ + /* *ensure the state change is valid */ + switch (enmNewState) + { + case ENMVBOXUSB_PNPSTATE_STARTED: + Assert( enmOldState == ENMVBOXUSB_PNPSTATE_START_PENDING + || enmOldState == ENMVBOXUSB_PNPSTATE_REMOVE_PENDING + || enmOldState == ENMVBOXUSB_PNPSTATE_STOPPED + || enmOldState == ENMVBOXUSB_PNPSTATE_STOP_PENDING); + break; + case ENMVBOXUSB_PNPSTATE_STOP_PENDING: + Assert(enmOldState == ENMVBOXUSB_PNPSTATE_STARTED); + break; + case ENMVBOXUSB_PNPSTATE_STOPPED: + Assert(enmOldState == ENMVBOXUSB_PNPSTATE_STOP_PENDING); + break; + case ENMVBOXUSB_PNPSTATE_SURPRISE_REMOVED: + Assert(enmOldState == ENMVBOXUSB_PNPSTATE_STARTED); + break; + case ENMVBOXUSB_PNPSTATE_REMOVE_PENDING: + Assert(enmOldState == ENMVBOXUSB_PNPSTATE_STARTED); + break; + case ENMVBOXUSB_PNPSTATE_REMOVED: + Assert( enmOldState == ENMVBOXUSB_PNPSTATE_REMOVE_PENDING + || enmOldState == ENMVBOXUSB_PNPSTATE_SURPRISE_REMOVED); + break; + default: + AssertFailed(); + break; + } + +} +#endif -- cgit v1.2.3