Пример #1
0
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);
        }
    }
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
0
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;
}
Пример #8
0
static NTSTATUS vboxUsbPnPMnDefault(PVBOXUSBDEV_EXT pDevExt, PIRP pIrp)
{
    NTSTATUS Status;
    IoSkipCurrentIrpStackLocation(pIrp);
    Status = IoCallDriver(pDevExt->pLowerDO, pIrp);
    vboxUsbDdiStateRelease(pDevExt);
    return Status;
}
Пример #9
0
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;
}
Пример #10
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 = STATUS_ACCESS_DENIED;
    Status = VBoxDrvToolIoComplete(pIrp, Status, 0);

    vboxUsbDdiStateRelease(pDevExt);

    return Status;
}
Пример #11
0
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;
}
Пример #12
0
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;
}
Пример #13
0
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;
}
Пример #14
0
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;
}
Пример #15
0
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);
}
Пример #16
0
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;
}
Пример #17
0
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;
}