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 = STATUS_ACCESS_DENIED; Status = VBoxDrvToolIoComplete(pIrp, Status, 0); vboxUsbDdiStateRelease(pDevExt); return Status; }
static NTSTATUS vboxUsbPnPMnQueryCapabilities(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp) { PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp); PDEVICE_CAPABILITIES pDevCaps = pSl->Parameters.DeviceCapabilities.Capabilities; if (pDevCaps->Version < 1 || pDevCaps->Size < sizeof (*pDevCaps)) { Assert(0); /* todo: return more appropriate status ?? */ return STATUS_UNSUCCESSFUL; } pDevCaps->SurpriseRemovalOK = TRUE; pIrp->IoStatus.Status = STATUS_SUCCESS; IoCopyCurrentIrpStackLocationToNext(pIrp); NTSTATUS Status = VBoxDrvToolIoPostSync(pDevExt->pLowerDO, pIrp); Assert(NT_SUCCESS(Status)); if (NT_SUCCESS(Status)) { pDevCaps->SurpriseRemovalOK = 1; pDevExt->DdiState.DevCaps = *pDevCaps; } VBoxDrvToolIoComplete(pIrp, Status, 0); vboxUsbDdiStateRelease(pDevExt); return Status; }
static NTSTATUS vboxUsbDispatchCleanup(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) { PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension; NTSTATUS Status = STATUS_SUCCESS; Status = VBoxDrvToolIoComplete(pIrp, Status, 0); return Status; }
DECLHIDDEN(NTSTATUS) vboxUsbDispatchPnP(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) { PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension; ENMVBOXUSB_PNPSTATE enmState = vboxUsbPnPStateGet(pDevExt); if (!vboxUsbDdiStateRetainIfNotRemoved(pDevExt)) { return VBoxDrvToolIoComplete(pIrp, STATUS_DELETE_PENDING, 0); } PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp); switch (pSl->MinorFunction) { case IRP_MN_START_DEVICE: { return vboxUsbPnPMnStartDevice(pDevExt, pIrp); } case IRP_MN_QUERY_STOP_DEVICE: { return vboxUsbPnPMnQueryStopDevice(pDevExt, pIrp); } case IRP_MN_STOP_DEVICE: { return vboxUsbPnPMnStopDevice(pDevExt, pIrp); } case IRP_MN_CANCEL_STOP_DEVICE: { return vboxUsbPnPMnCancelStopDevice(pDevExt, pIrp); } case IRP_MN_QUERY_REMOVE_DEVICE: { return vboxUsbPnPMnQueryRemoveDevice(pDevExt, pIrp); } case IRP_MN_REMOVE_DEVICE: { return vboxUsbPnPMnRemoveDevice(pDevExt, pIrp); } case IRP_MN_CANCEL_REMOVE_DEVICE: { return vboxUsbPnPMnCancelRemoveDevice(pDevExt, pIrp); } case IRP_MN_SURPRISE_REMOVAL: { return vboxUsbPnPMnSurpriseRemoval(pDevExt, pIrp); } case IRP_MN_QUERY_CAPABILITIES: { return vboxUsbPnPMnQueryCapabilities(pDevExt, pIrp); } default: { return vboxUsbPnPMnDefault(pDevExt, pIrp); } } }
static NTSTATUS vboxUsbDispatchDeviceControl(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) { PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension; NTSTATUS Status = STATUS_INVALID_HANDLE; if (vboxUsbDdiStateRetainIfStarted(pDevExt)) { return vboxUsbRtDispatch(pDevExt, pIrp); } else { Status = STATUS_INVALID_DEVICE_STATE; } Status = VBoxDrvToolIoComplete(pIrp, Status, 0); 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 vboxUsbPnPMnCancelStopDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp) { ENMVBOXUSB_PNPSTATE enmState = vboxUsbPnPStateGet(pDevExt); NTSTATUS Status = STATUS_SUCCESS; IoCopyCurrentIrpStackLocationToNext(pIrp); Status = VBoxDrvToolIoPostSync(pDevExt->pLowerDO, pIrp); if (NT_SUCCESS(Status) && enmState == ENMVBOXUSB_PNPSTATE_STOP_PENDING) { vboxUsbPnPStateRestore(pDevExt); } Status = STATUS_SUCCESS; VBoxDrvToolIoComplete(pIrp, Status, 0); vboxUsbDdiStateRelease(pDevExt); return Status; }
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 vboxUsbPnPMnStartDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp) { IoCopyCurrentIrpStackLocationToNext(pIrp); NTSTATUS Status = VBoxDrvToolIoPostSync(pDevExt->pLowerDO, pIrp); Assert(NT_SUCCESS(Status) || Status == STATUS_NOT_SUPPORTED); if (NT_SUCCESS(Status)) { Status = vboxUsbRtStart(pDevExt); Assert(Status == STATUS_SUCCESS); if (NT_SUCCESS(Status)) { vboxUsbPnPStateSet(pDevExt, ENMVBOXUSB_PNPSTATE_STARTED); } } VBoxDrvToolIoComplete(pIrp, Status, 0); vboxUsbDdiStateRelease(pDevExt); return Status; }
static NTSTATUS vboxUsbDispatchClose(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) { PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension; PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp); PFILE_OBJECT pFObj = pSl->FileObject; NTSTATUS Status = STATUS_SUCCESS; Assert(pFObj); Assert(!pFObj->FileName.Length); Status = vboxUsbRtClose(pDevExt, pIrp); if (NT_SUCCESS(Status)) { ASMAtomicDecU32(&pDevExt->cHandles); } else { AssertFailed(); } Status = VBoxDrvToolIoComplete(pIrp, Status, 0); return Status; }
static NTSTATUS vboxUsbPnPMnCancelRemoveDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp) { ENMVBOXUSB_PNPSTATE enmState = vboxUsbPnPStateGet(pDevExt); NTSTATUS Status = STATUS_SUCCESS; if (enmState == ENMVBOXUSB_PNPSTATE_REMOVE_PENDING) { IoCopyCurrentIrpStackLocationToNext(pIrp); Status = VBoxDrvToolIoPostSync(pDevExt->pLowerDO, pIrp); if (NT_SUCCESS(Status)) { vboxUsbPnPStateRestore(pDevExt); } } else { Assert(0); Assert(enmState == ENMVBOXUSB_PNPSTATE_STARTED); } VBoxDrvToolIoComplete(pIrp, Status, 0); vboxUsbDdiStateRelease(pDevExt); return Status; }