DECLHIDDEN(NTSTATUS) vboxUsbDispatchPower(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) { PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension; ENMVBOXUSB_PNPSTATE enmState = vboxUsbDdiStateRetainIfNotRemoved(pDevExt); switch (enmState) { case ENMVBOXUSB_PNPSTATE_REMOVED: { PoStartNextPowerIrp(pIrp); pIrp->IoStatus.Status = STATUS_DELETE_PENDING; pIrp->IoStatus.Information = 0; IoCompleteRequest(pIrp, IO_NO_INCREMENT); vboxUsbDdiStateRelease(pDevExt); return STATUS_DELETE_PENDING; } case ENMVBOXUSB_PNPSTATE_START_PENDING: { PoStartNextPowerIrp(pIrp); IoSkipCurrentIrpStackLocation(pIrp); vboxUsbDdiStateRelease(pDevExt); return PoCallDriver(pDevExt->pLowerDO, pIrp); } default: { return vboxUsbPwrDispatch(pDevExt, pIrp); } } }
static NTSTATUS vboxUsbPwrSetPowerDev(IN PVBOXUSBDEV_EXT pDevExt, IN PIRP pIrp) { PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp); DEVICE_POWER_STATE enmDevPState = pSl->Parameters.Power.State.DeviceState; DEVICE_POWER_STATE enmCurDevPState = pDevExt->DdiState.PwrState.PowerState.DeviceState; NTSTATUS Status = STATUS_SUCCESS; if (enmDevPState > enmCurDevPState && enmCurDevPState == PowerDeviceD0) { Status = vboxUsbPwrIoWaitCompletionAndPostAsync(pDevExt, pIrp); Assert(NT_SUCCESS(Status)); if (NT_SUCCESS(Status)) return Status; } PoStartNextPowerIrp(pIrp); if (NT_SUCCESS(Status)) { IoCopyCurrentIrpStackLocationToNext(pIrp); IoSetCompletionRoutine(pIrp, vboxUsbPwrIoPostDevCompletion, pDevExt, TRUE, TRUE, TRUE); Status = PoCallDriver(pDevExt->pLowerDO, pIrp); } else { pIrp->IoStatus.Status = Status; pIrp->IoStatus.Information = 0; IoCompleteRequest(pIrp, IO_NO_INCREMENT); vboxUsbDdiStateRelease(pDevExt); } return Status; }
static NTSTATUS vboxUsbPnPMnRemoveDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp) { ENMVBOXUSB_PNPSTATE enmState = vboxUsbPnPStateGet(pDevExt); NTSTATUS Status = STATUS_SUCCESS; if (enmState != ENMVBOXUSB_PNPSTATE_SURPRISE_REMOVED) { Status = vboxUsbPnPRmDev(pDevExt); Assert(Status == STATUS_SUCCESS); } vboxUsbPnPStateSet(pDevExt, ENMVBOXUSB_PNPSTATE_REMOVED); vboxUsbDdiStateRelease(pDevExt); vboxUsbDdiStateReleaseAndWaitRemoved(pDevExt); vboxUsbRtClear(pDevExt); pIrp->IoStatus.Status = STATUS_SUCCESS; pIrp->IoStatus.Information = 0; IoSkipCurrentIrpStackLocation(pIrp); Status = IoCallDriver(pDevExt->pLowerDO, pIrp); IoDetachDevice(pDevExt->pLowerDO); IoDeleteDevice(pDevExt->pFDO); return Status; }
static NTSTATUS vboxUsbPwrIoPostSysCompletion(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp, IN PVOID pvContext) { PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pvContext; NTSTATUS Status = pIrp->IoStatus.Status; Assert(Status == STATUS_SUCCESS); if (NT_SUCCESS(Status)) { PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp); switch (pSl->MinorFunction) { case IRP_MN_SET_POWER: { pDevExt->DdiState.PwrState.PowerState.SystemState = pSl->Parameters.Power.State.SystemState; break; } default: { break; } } return vboxUsbPwrIoRequestDev(pDevExt, pIrp); } PoStartNextPowerIrp(pIrp); vboxUsbDdiStateRelease(pDevExt); return STATUS_SUCCESS; }
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 vboxUsbPwrIoPostDevCompletion(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp, IN PVOID pvContext) { PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pvContext; if (pIrp->PendingReturned) { IoMarkIrpPending(pIrp); } NTSTATUS Status = pIrp->IoStatus.Status; Assert(Status == STATUS_SUCCESS); if (NT_SUCCESS(Status)) { PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp); switch (pSl->MinorFunction) { case IRP_MN_SET_POWER: { pDevExt->DdiState.PwrState.PowerState.DeviceState = pSl->Parameters.Power.State.DeviceState; PoSetPowerState(pDevExt->pFDO, DevicePowerState, pSl->Parameters.Power.State); break; } default: { break; } } } PoStartNextPowerIrp(pIrp); vboxUsbDdiStateRelease(pDevExt); return STATUS_SUCCESS; }
static NTSTATUS vboxUsbPwrIoRequestDev(IN PVBOXUSBDEV_EXT pDevExt, IN PIRP pIrp) { PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp); POWER_STATE PwrState; PwrState.SystemState = pSl->Parameters.Power.State.SystemState; PwrState.DeviceState = pDevExt->DdiState.DevCaps.DeviceState[PwrState.SystemState]; NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES; PVBOXUSB_PWRDEV_CTX pDevCtx = (PVBOXUSB_PWRDEV_CTX)vboxUsbMemAlloc(sizeof (*pDevCtx)); Assert(pDevCtx); if (pDevCtx) { pDevCtx->pDevExt = pDevExt; pDevCtx->pIrp = pIrp; Status = PoRequestPowerIrp(pDevExt->pPDO, pSl->MinorFunction, PwrState, vboxUsbPwrIoDeviceCompletion, pDevCtx, NULL); Assert(NT_SUCCESS(Status)); if (NT_SUCCESS(Status)) { return STATUS_MORE_PROCESSING_REQUIRED; } vboxUsbMemFree(pDevCtx); } PoStartNextPowerIrp(pIrp); pIrp->IoStatus.Status = Status; pIrp->IoStatus.Information = 0; vboxUsbDdiStateRelease(pDevExt); /* the "real" Status is stored in pIrp->IoStatus.Status, * return success here to complete the Io */ return STATUS_SUCCESS; }
static NTSTATUS vboxUsbPnPMnDefault(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp) { NTSTATUS Status; IoSkipCurrentIrpStackLocation(pIrp); Status = IoCallDriver(pDevExt->pLowerDO, pIrp); vboxUsbDdiStateRelease(pDevExt); return Status; }
static NTSTATUS vboxUsbPwrMnDefault(IN PVBOXUSBDEV_EXT pDevExt, IN PIRP pIrp) { NTSTATUS Status; PoStartNextPowerIrp(pIrp); IoSkipCurrentIrpStackLocation(pIrp); Status = PoCallDriver(pDevExt->pLowerDO, pIrp); Assert(NT_SUCCESS(Status) || Status == STATUS_NOT_SUPPORTED); vboxUsbDdiStateRelease(pDevExt); return Status; }
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 vboxUsbPnPMnSurpriseRemoval(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp) { vboxUsbPnPStateSet(pDevExt, ENMVBOXUSB_PNPSTATE_SURPRISE_REMOVED); NTSTATUS Status = vboxUsbPnPRmDev(pDevExt); Assert(Status == STATUS_SUCCESS); pIrp->IoStatus.Status = STATUS_SUCCESS; pIrp->IoStatus.Information = 0; IoSkipCurrentIrpStackLocation(pIrp); Status = IoCallDriver(pDevExt->pLowerDO, pIrp); 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 vboxUsbPnPMnStopDevice(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp) { vboxUsbPnPStateSet(pDevExt, ENMVBOXUSB_PNPSTATE_STOPPED); vboxUsbRtClear(pDevExt); NTSTATUS Status = VBoxUsbToolDevUnconfigure(pDevExt->pLowerDO); Assert(NT_SUCCESS(Status)); pIrp->IoStatus.Status = Status; pIrp->IoStatus.Information = 0; IoSkipCurrentIrpStackLocation(pIrp); 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 VOID vboxUsbPwrIoDeviceCompletion(IN PDEVICE_OBJECT pDeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, IN PVOID pvContext, IN PIO_STATUS_BLOCK pIoStatus) { PVBOXUSB_PWRDEV_CTX pDevCtx = (PVBOXUSB_PWRDEV_CTX)pvContext; PVBOXUSBDEV_EXT pDevExt = pDevCtx->pDevExt; PIRP pIrp = pDevCtx->pIrp; pIrp->IoStatus.Status = pIoStatus->Status; pIrp->IoStatus.Information = 0; PoStartNextPowerIrp(pIrp); IoCompleteRequest(pIrp, IO_NO_INCREMENT); vboxUsbDdiStateRelease(pDevExt); vboxUsbMemFree(pDevCtx); }
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 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; }