Exemplo n.º 1
0
VOID NTAPI HoldIoRequestsWorkerRoutine(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context)
{
    PIRP                   irp;
    NTSTATUS               ntStatus;
    PDEVICE_EXTENSION      deviceExtension;
    PWORKER_THREAD_CONTEXT context;

    FreeBT_DbgPrint(3, ("FBTUSB: HoldIoRequestsWorkerRoutine: Entered\n"));

    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    context = (PWORKER_THREAD_CONTEXT) Context;
    irp = (PIRP) context->Irp;

    // wait for I/O in progress to finish.
    // the stop event is signalled when the counter drops to 1.
    // invoke FreeBT_IoDecrement twice: once each for the S-Irp and D-Irp.
    FreeBT_DbgPrint(3, ("FBTUSB: HoldIoRequestsWorkerRoutine::"));
    FreeBT_IoDecrement(deviceExtension);

    FreeBT_DbgPrint(3, ("FBTUSB: HoldIoRequestsWorkerRoutine::"));
    FreeBT_IoDecrement(deviceExtension);

    KeWaitForSingleObject(&deviceExtension->StopEvent, Executive, KernelMode, FALSE, NULL);

    // Increment twice to restore the count
    FreeBT_DbgPrint(3, ("FBTUSB: HoldIoRequestsWorkerRoutine::"));
    FreeBT_IoIncrement(deviceExtension);

    FreeBT_DbgPrint(3, ("FBTUSB: HoldIoRequestsWorkerRoutine::"));
    FreeBT_IoIncrement(deviceExtension);

    // now send the Irp down
    IoCopyCurrentIrpStackLocationToNext(irp);
    IoSetCompletionRoutine(
        irp,
        (PIO_COMPLETION_ROUTINE) FinishDevPoDnIrp,
        deviceExtension,
        TRUE,
        TRUE,
        TRUE);

    ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject, irp);
    if(!NT_SUCCESS(ntStatus))
    {
        FreeBT_DbgPrint(1, ("FBTUSB: HoldIoRequestsWorkerRoutine: Lower driver fail a power Irp\n"));

    }

    IoFreeWorkItem(context->WorkItem);
    ExFreePool((PVOID)context);

    FreeBT_DbgPrint(3, ("FBTUSB: HoldIoRequestsWorkerRoutine: Leaving\n"));

}
Exemplo n.º 2
0
VOID NTAPI DevPoCompletionRoutine(
    IN PDEVICE_OBJECT DeviceObject,
    IN UCHAR MinorFunction,
    IN POWER_STATE PowerState,
    IN PVOID Context,
    IN PIO_STATUS_BLOCK IoStatus
    )
{
    PIRP                      sIrp;
    PDEVICE_EXTENSION         deviceExtension;
    PPOWER_COMPLETION_CONTEXT powerContext;

    powerContext = (PPOWER_COMPLETION_CONTEXT) Context;
    sIrp = powerContext->SIrp;
    deviceExtension = (PDEVICE_EXTENSION) powerContext->DeviceObject->DeviceExtension;

    FreeBT_DbgPrint(3, ("FBTUSB: DevPoCompletionRoutine: Entered\n"));

    sIrp->IoStatus.Status = IoStatus->Status;
    PoStartNextPowerIrp(sIrp);
    sIrp->IoStatus.Information = 0;
    IoCompleteRequest(sIrp, IO_NO_INCREMENT);

    FreeBT_DbgPrint(3, ("FBTUSB: DevPoCompletionRoutine::"));
    FreeBT_IoDecrement(deviceExtension);

    ExFreePool(powerContext);

    FreeBT_DbgPrint(3, ("FBTUSB: DevPoCompletionRoutine: Leaving\n"));

}
Exemplo n.º 3
0
NTSTATUS NTAPI FinishDevPoDnIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PDEVICE_EXTENSION DeviceExtension)
{
    NTSTATUS           ntStatus;
    POWER_STATE        newState;
    PIO_STACK_LOCATION irpStack;

    FreeBT_DbgPrint(3, ("FBTUSB: FinishDevPoDnIrp: Entered\n"));

    ntStatus = Irp->IoStatus.Status;
    irpStack = IoGetCurrentIrpStackLocation(Irp);
    newState = irpStack->Parameters.Power.State;

    if (NT_SUCCESS(ntStatus) && irpStack->MinorFunction == IRP_MN_SET_POWER)
    {
        FreeBT_DbgPrint(3, ("FBTUSB: updating cache..\n"));
        DeviceExtension->DevPower = newState.DeviceState;
        PoSetPowerState(DeviceObject, DevicePowerState, newState);

    }

    PoStartNextPowerIrp(Irp);

    FreeBT_DbgPrint(3, ("FBTUSB: FinishDevPoDnIrp::"));
    FreeBT_IoDecrement(DeviceExtension);

    FreeBT_DbgPrint(3, ("FBTUSB: FinishDevPoDnIrp: Leaving\n"));

    return STATUS_SUCCESS;

}
Exemplo n.º 4
0
NTSTATUS NTAPI FinishDevPoUpIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PDEVICE_EXTENSION DeviceExtension)
{
    NTSTATUS           ntStatus;

    FreeBT_DbgPrint(3, ("FBTUSB: FinishDevPoUpIrp: Entered\n"));

    ntStatus = Irp->IoStatus.Status;
    if(Irp->PendingReturned)
    {
        IoMarkIrpPending(Irp);

    }

    if(!NT_SUCCESS(ntStatus))
    {
        PoStartNextPowerIrp(Irp);

        FreeBT_DbgPrint(3, ("FBTUSB: FinishDevPoUpIrp::"));
        FreeBT_IoDecrement(DeviceExtension);

        return STATUS_SUCCESS;

    }

    SetDeviceFunctional(DeviceObject, Irp, DeviceExtension);

    FreeBT_DbgPrint(3, ("FBTUSB: FinishDevPoUpIrp: Leaving\n"));

    return STATUS_MORE_PROCESSING_REQUIRED;

}
Exemplo n.º 5
0
NTSTATUS NTAPI HandleSystemQueryPower(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    NTSTATUS           ntStatus;
    PDEVICE_EXTENSION  deviceExtension;
    SYSTEM_POWER_STATE systemState;
    PIO_STACK_LOCATION irpStack;

    FreeBT_DbgPrint(3, ("FBTUSB: HandleSystemQueryPower: Entered\n"));

    // initialize variables
    deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
    irpStack = IoGetCurrentIrpStackLocation(Irp);
    systemState = irpStack->Parameters.Power.State.SystemState;

    FreeBT_DbgPrint(3, ("FBTUSB: HandleSystemQueryPower: Query for system power state S%X\n"
                        "FBTUSB: HandleSystemQueryPower: Current system power state S%X\n",
                         systemState - 1,
                         deviceExtension->SysPower - 1));

    // Fail a query for a power state incompatible with waking up the system
    if ((deviceExtension->WaitWakeEnable) && (systemState > deviceExtension->DeviceCapabilities.SystemWake))
    {
        FreeBT_DbgPrint(1, ("FBTUSB: HandleSystemQueryPower: Query for an incompatible system power state\n"));

        PoStartNextPowerIrp(Irp);
        Irp->IoStatus.Status = ntStatus = STATUS_INVALID_DEVICE_STATE;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        FreeBT_DbgPrint(3, ("FBTUSB: HandleSystemQueryPower::"));
        FreeBT_IoDecrement(deviceExtension);

        return ntStatus;

    }

    // if querying for a lower S-state, issue a wait-wake
    if((systemState > deviceExtension->SysPower) && (deviceExtension->WaitWakeEnable))
    {
        IssueWaitWake(deviceExtension);

    }

    IoCopyCurrentIrpStackLocationToNext(Irp);
    IoSetCompletionRoutine(
            Irp,
            (PIO_COMPLETION_ROUTINE)SysPoCompletionRoutine,
            deviceExtension,
            TRUE,
            TRUE,
            TRUE);

    ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
    FreeBT_DbgPrint(3, ("FBTUSB: HandleSystemQueryPower: Leaving\n"));

    return STATUS_PENDING;

}
Exemplo n.º 6
0
NTSTATUS NTAPI SetDeviceFunctional(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PDEVICE_EXTENSION DeviceExtension)
{
    KIRQL              oldIrql;
    NTSTATUS           ntStatus;
    POWER_STATE        newState;
    PIO_STACK_LOCATION irpStack;
    DEVICE_POWER_STATE newDevState, oldDevState;

    ntStatus = Irp->IoStatus.Status;
    irpStack = IoGetCurrentIrpStackLocation(Irp);
    newState = irpStack->Parameters.Power.State;
    newDevState = newState.DeviceState;
    oldDevState = DeviceExtension->DevPower;

    FreeBT_DbgPrint(3, ("FBTUSB: SetDeviceFunctional: Entered\n"));

    // update the cached state
    DeviceExtension->DevPower = newDevState;

    // restore appropriate amount of state to our h/w
    // this driver does not implement partial context
    // save/restore.
    PoSetPowerState(DeviceObject, DevicePowerState, newState);
    if(PowerDeviceD0 == newDevState)
    {
        KeAcquireSpinLock(&DeviceExtension->DevStateLock, &oldIrql);
        DeviceExtension->QueueState = AllowRequests;
        KeReleaseSpinLock(&DeviceExtension->DevStateLock, oldIrql);

        ProcessQueuedRequests(DeviceExtension);

    }

    PoStartNextPowerIrp(Irp);
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    FreeBT_DbgPrint(3, ("FBTUSB: SetDeviceFunctional::"));
    FreeBT_IoDecrement(DeviceExtension);

    FreeBT_DbgPrint(3, ("FBTUSB: SetDeviceFunctional: Leaving\n"));

    return STATUS_SUCCESS;

}
Exemplo n.º 7
0
NTSTATUS NTAPI SysPoCompletionRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PDEVICE_EXTENSION DeviceExtension)
{
    NTSTATUS           ntStatus;
    PIO_STACK_LOCATION irpStack;

    ntStatus = Irp->IoStatus.Status;
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    FreeBT_DbgPrint(3, ("FBTUSB: SysPoCompletionRoutine: Entered\n"));

    // lower drivers failed this Irp
    if(!NT_SUCCESS(ntStatus))
    {
        PoStartNextPowerIrp(Irp);
        FreeBT_DbgPrint(3, ("FBTUSB: SysPoCompletionRoutine::"));
        FreeBT_IoDecrement(DeviceExtension);

        return STATUS_SUCCESS;

    }

    // ..otherwise update the cached system power state (IRP_MN_SET_POWER)
    if(irpStack->MinorFunction == IRP_MN_SET_POWER)
    {
        DeviceExtension->SysPower = irpStack->Parameters.Power.State.SystemState;

    }

    // queue device irp and return STATUS_MORE_PROCESSING_REQUIRED
    SendDeviceIrp(DeviceObject, Irp);

    FreeBT_DbgPrint(3, ("FBTUSB: SysPoCompletionRoutine: Leaving\n"));

    return STATUS_MORE_PROCESSING_REQUIRED;

}
Exemplo n.º 8
0
NTSTATUS NTAPI HandleDeviceSetPower(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    KIRQL              oldIrql;
    NTSTATUS           ntStatus;
    POWER_STATE        newState;
    PIO_STACK_LOCATION irpStack;
    PDEVICE_EXTENSION  deviceExtension;
    DEVICE_POWER_STATE newDevState,
                       oldDevState;

    FreeBT_DbgPrint(3, ("FBTUSB: HandleDeviceSetPower: Entered\n"));

    deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
    irpStack = IoGetCurrentIrpStackLocation(Irp);
    oldDevState = deviceExtension->DevPower;
    newState = irpStack->Parameters.Power.State;
    newDevState = newState.DeviceState;

    FreeBT_DbgPrint(3, ("FBTUSB: HandleDeviceSetPower: Set request for device power state D%X\n"
                         "FBTUSB: HandleDeviceSetPower: Current device power state D%X\n",
                         newDevState - 1,
                         deviceExtension->DevPower - 1));

    if (newDevState < oldDevState)
    {

        FreeBT_DbgPrint(3, ("FBTUSB: HandleDeviceSetPower: Adding power to the device\n"));

        IoCopyCurrentIrpStackLocationToNext(Irp);
        IoSetCompletionRoutine(
                Irp,
                (PIO_COMPLETION_ROUTINE)FinishDevPoUpIrp,
                deviceExtension,
                TRUE,
                TRUE,
                TRUE);

        ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);

    }

    else
    {
        // newDevState >= oldDevState

        // hold I/O if transition from D0 -> DX (X = 1, 2, 3)
        // if transition from D1 or D2 to deeper sleep states,
        // I/O queue is already on hold.
        if(PowerDeviceD0 == oldDevState && newDevState > oldDevState)
        {
            // D0 -> DX transition
            FreeBT_DbgPrint(3, ("FBTUSB: HandleDeviceSetPower: Removing power from the device\n"));

            ntStatus = HoldIoRequests(DeviceObject, Irp);
            if (!NT_SUCCESS(ntStatus))
            {
                PoStartNextPowerIrp(Irp);
                Irp->IoStatus.Status = ntStatus;
                Irp->IoStatus.Information = 0;
                IoCompleteRequest(Irp, IO_NO_INCREMENT);

                FreeBT_DbgPrint(3, ("FBTUSB: HandleDeviceSetPower::"));
                FreeBT_IoDecrement(deviceExtension);

                return ntStatus;

            }

            else
            {
                goto HandleDeviceSetPower_Exit;

            }

        }

        else if (PowerDeviceD0 == oldDevState && PowerDeviceD0 == newDevState)
        {
            // D0 -> D0
            // unblock the queue which may have been blocked processing
            // query irp
            FreeBT_DbgPrint(3, ("FBTUSB: HandleDeviceSetPower: A SetD0 request\n"));

            KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql);
            deviceExtension->QueueState = AllowRequests;
            KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql);

            ProcessQueuedRequests(deviceExtension);

        }

        IoCopyCurrentIrpStackLocationToNext(Irp);
        IoSetCompletionRoutine(
                Irp,
                (PIO_COMPLETION_ROUTINE) FinishDevPoDnIrp,
                deviceExtension,
                TRUE,
                TRUE,
                TRUE);

        ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
        if(!NT_SUCCESS(ntStatus))
        {
            FreeBT_DbgPrint(1, ("FBTUSB: HandleDeviceSetPower: Lower drivers failed a power Irp\n"));

        }

    }

HandleDeviceSetPower_Exit:

    FreeBT_DbgPrint(3, ("FBTUSB: HandleDeviceSetPower: Leaving\n"));

    return STATUS_PENDING;

}
Exemplo n.º 9
0
VOID NTAPI SendDeviceIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP SIrp )
{
    NTSTATUS                  ntStatus;
    POWER_STATE               powState;
    PDEVICE_EXTENSION         deviceExtension;
    PIO_STACK_LOCATION        irpStack;
    SYSTEM_POWER_STATE        systemState;
    DEVICE_POWER_STATE        devState;
    PPOWER_COMPLETION_CONTEXT powerContext;

    irpStack = IoGetCurrentIrpStackLocation(SIrp);
    systemState = irpStack->Parameters.Power.State.SystemState;
    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

    FreeBT_DbgPrint(3, ("FBTUSB: SendDeviceIrp: Entered\n"));

    // Read out the D-IRP out of the S->D mapping array captured in QueryCap's.
    // we can choose deeper sleep states than our mapping but never choose
    // lighter ones.
    devState = deviceExtension->DeviceCapabilities.DeviceState[systemState];
    powState.DeviceState = devState;

    powerContext = (PPOWER_COMPLETION_CONTEXT) ExAllocatePool(NonPagedPool, sizeof(POWER_COMPLETION_CONTEXT));
    if (!powerContext)
    {
        FreeBT_DbgPrint(1, ("FBTUSB: SendDeviceIrp: Failed to alloc memory for powerContext\n"));
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;

    }

    else
    {
        powerContext->DeviceObject = DeviceObject;
        powerContext->SIrp = SIrp;

        // in win2k PoRequestPowerIrp can take fdo or pdo.
        ntStatus = PoRequestPowerIrp(
                            deviceExtension->PhysicalDeviceObject,
                            irpStack->MinorFunction,
                            powState,
                            (PREQUEST_POWER_COMPLETE)DevPoCompletionRoutine,
                            powerContext,
                            NULL);

    }

    if (!NT_SUCCESS(ntStatus))
    {
        if (powerContext)
        {
            ExFreePool(powerContext);

        }

        PoStartNextPowerIrp(SIrp);
        SIrp->IoStatus.Status = ntStatus;
        SIrp->IoStatus.Information = 0;
        IoCompleteRequest(SIrp, IO_NO_INCREMENT);

        FreeBT_DbgPrint(3, ("FBTUSB: SendDeviceIrp::"));
        FreeBT_IoDecrement(deviceExtension);

    }

    FreeBT_DbgPrint(3, ("FBTUSB: SendDeviceIrp: Leaving\n"));

}
Exemplo n.º 10
0
NTSTATUS NTAPI HandleDeviceQueryPower(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    NTSTATUS           ntStatus;
    PDEVICE_EXTENSION  deviceExtension;
    PIO_STACK_LOCATION irpStack;
    DEVICE_POWER_STATE deviceState;

    FreeBT_DbgPrint(3, ("FBTUSB: HandleDeviceQueryPower: Entered\n"));

    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    irpStack = IoGetCurrentIrpStackLocation(Irp);
    deviceState = irpStack->Parameters.Power.State.DeviceState;

    FreeBT_DbgPrint(3, ("FBTUSB: HandleDeviceQueryPower: Query for device power state D%X\n"
                         "FBTUSB: HandleDeviceQueryPower: Current device power state D%X\n",
                         deviceState - 1,
                         deviceExtension->DevPower - 1));

    if (deviceExtension->WaitWakeEnable && deviceState > deviceExtension->DeviceCapabilities.DeviceWake)
    {
        PoStartNextPowerIrp(Irp);
        Irp->IoStatus.Status = ntStatus = STATUS_INVALID_DEVICE_STATE;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        FreeBT_DbgPrint(3, ("FBTUSB: HandleDeviceQueryPower::"));
        FreeBT_IoDecrement(deviceExtension);

        return ntStatus;

    }

    if (deviceState < deviceExtension->DevPower)
    {
        ntStatus = STATUS_SUCCESS;

    }

    else
    {
        ntStatus = HoldIoRequests(DeviceObject, Irp);
        if(STATUS_PENDING == ntStatus)
        {
            return ntStatus;

        }

    }

    // on error complete the Irp.
    // on success pass it to the lower layers
    PoStartNextPowerIrp(Irp);
    Irp->IoStatus.Status = ntStatus;
    Irp->IoStatus.Information = 0;
    if(!NT_SUCCESS(ntStatus))
    {
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

    }

    else
    {
        IoSkipCurrentIrpStackLocation(Irp);
        ntStatus=PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);

    }

    FreeBT_DbgPrint(3, ("FBTUSB: HandleDeviceQueryPower::"));
    FreeBT_IoDecrement(deviceExtension);

    FreeBT_DbgPrint(3, ("FBTUSB: HandleDeviceQueryPower: Leaving\n"));

    return ntStatus;

}
Exemplo n.º 11
0
// Handle power events
NTSTATUS NTAPI FreeBT_DispatchPower(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    NTSTATUS           ntStatus = STATUS_SUCCESS;
    PIO_STACK_LOCATION irpStack;
    //PUNICODE_STRING    tagString;
    PDEVICE_EXTENSION  deviceExtension;

    irpStack = IoGetCurrentIrpStackLocation(Irp);
    deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;

    // We don't queue power Irps, we'll only check if the
    // device was removed, otherwise we'll take appropriate
    // action and send it to the next lower driver. In general
    // drivers should not cause long delays while handling power
    // IRPs. If a driver cannot handle a power IRP in a brief time,
    // it should return STATUS_PENDING and queue all incoming
    // IRPs until the IRP completes.
    if (Removed == deviceExtension->DeviceState)
    {

        // Even if a driver fails the IRP, it must nevertheless call
        // PoStartNextPowerIrp to inform the Power Manager that it
        // is ready to handle another power IRP.
        PoStartNextPowerIrp(Irp);
        Irp->IoStatus.Status = ntStatus = STATUS_DELETE_PENDING;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        return ntStatus;

    }

    if (NotStarted == deviceExtension->DeviceState)
    {
        // if the device is not started yet, pass it down
        PoStartNextPowerIrp(Irp);
        IoSkipCurrentIrpStackLocation(Irp);

        return PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);

    }

    FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchPower::"));
    FreeBT_IoIncrement(deviceExtension);

    switch(irpStack->MinorFunction)
    {
    case IRP_MN_SET_POWER:
        // The Power Manager sends this IRP for one of the
        // following reasons:

        // 1) To notify drivers of a change to the system power state.
        // 2) To change the power state of a device for which
        //    the Power Manager is performing idle detection.

        // A driver sends IRP_MN_SET_POWER to change the power
        // state of its device if it's a power policy owner for the
        // device.
        FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchPower: IRP_MN_SET_POWER\n"));
        IoMarkIrpPending(Irp);

        switch(irpStack->Parameters.Power.Type)
        {
        case SystemPowerState:
            HandleSystemSetPower(DeviceObject, Irp);
            ntStatus = STATUS_PENDING;
            break;

        case DevicePowerState:
            HandleDeviceSetPower(DeviceObject, Irp);
            ntStatus = STATUS_PENDING;
            break;

        }

        break;

    case IRP_MN_QUERY_POWER:
        // The Power Manager sends a power IRP with the minor
        // IRP code IRP_MN_QUERY_POWER to determine whether it
        // can safely change to the specified system power state
        // (S1-S5) and to allow drivers to prepare for such a change.
        // If a driver can put its device in the requested state,
        // it sets status to STATUS_SUCCESS and passes the IRP down.
        FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchPower: IRP_MN_QUERY_POWER\n"));
        IoMarkIrpPending(Irp);

        switch(irpStack->Parameters.Power.Type)
        {
        case SystemPowerState:
            HandleSystemQueryPower(DeviceObject, Irp);
            ntStatus = STATUS_PENDING;
            break;

        case DevicePowerState:
            HandleDeviceQueryPower(DeviceObject, Irp);
            ntStatus = STATUS_PENDING;
            break;

        }

        break;

    case IRP_MN_WAIT_WAKE:
        // The minor power IRP code IRP_MN_WAIT_WAKE provides
        // for waking a device or waking the system. Drivers
        // of devices that can wake themselves or the system
        // send IRP_MN_WAIT_WAKE. The system sends IRP_MN_WAIT_WAKE
        // only to devices that always wake the system, such as
        // the power-on switch.
        FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchPower: IRP_MN_WAIT_WAKE\n"));
        IoMarkIrpPending(Irp);
        IoCopyCurrentIrpStackLocationToNext(Irp);
        IoSetCompletionRoutine(
                        Irp,
                        (PIO_COMPLETION_ROUTINE)WaitWakeCompletionRoutine,
                        deviceExtension,
                        TRUE,
                        TRUE,
                        TRUE);

        PoStartNextPowerIrp(Irp);
        ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
        if(!NT_SUCCESS(ntStatus))
        {
            FreeBT_DbgPrint(1, ("FBTUSB: Lower drivers failed the wait-wake Irp\n"));

        }

        ntStatus = STATUS_PENDING;

        // push back the count HERE and NOT in completion routine
        // a pending Wait Wake Irp should not impede stopping the device
        FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchPower: IRP_MN_WAIT_WAKE::"));
        FreeBT_IoDecrement(deviceExtension);
        break;

    case IRP_MN_POWER_SEQUENCE:
        // A driver sends this IRP as an optimization to determine
        // whether its device actually entered a specific power state.
        // This IRP is optional. Power Manager cannot send this IRP.
        FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchPower: IRP_MN_POWER_SEQUENCE\n"));

    default:
        PoStartNextPowerIrp(Irp);
        IoSkipCurrentIrpStackLocation(Irp);
        ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
        if(!NT_SUCCESS(ntStatus))
        {
            FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_DispatchPower: Lower drivers failed this Irp\n"));

        }

        FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchPower::"));
        FreeBT_IoDecrement(deviceExtension);

        break;

    }

    return ntStatus;

}
Exemplo n.º 12
0
NTSTATUS NTAPI FreeBT_DispatchSysCtrl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    PDEVICE_EXTENSION       deviceExtension;
    SYSCTL_IRP_DISPOSITION  disposition;
    NTSTATUS                ntStatus;
    PIO_STACK_LOCATION      irpStack;

    PAGED_CODE();

    irpStack = IoGetCurrentIrpStackLocation (Irp);
    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

	FreeBT_DbgPrint(3, ("FBTUSB: "));
    FreeBT_DbgPrint(3, (WMIMinorFunctionString(irpStack->MinorFunction)));
    if (Removed == deviceExtension->DeviceState)
	{
        ntStatus = STATUS_DELETE_PENDING;

        Irp->IoStatus.Status = ntStatus;
        Irp->IoStatus.Information = 0;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        return ntStatus;

    }

    FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchSysCtrl::"));
    FreeBT_IoIncrement(deviceExtension);

    ntStatus = WmiSystemControl(&deviceExtension->WmiLibInfo,
                                DeviceObject,
                                Irp,
                                &disposition);

    switch(disposition)
	{
        case IrpProcessed:
        {
            // This irp has been processed and may be completed or pending.
            break;

        }

        case IrpNotCompleted:
        {
            // This irp has not been completed, but has been fully processed.
            // we will complete it now
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
            break;

        }

        case IrpForward:
        case IrpNotWmi:
        {
            // This irp is either not a WMI irp or is a WMI irp targeted
            // at a device lower in the stack.
            IoSkipCurrentIrpStackLocation (Irp);
            ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
            break;
        }

        default:
        {
            // We really should never get here, but if we do just forward....
            ASSERT(FALSE);
            IoSkipCurrentIrpStackLocation (Irp);
            ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
            break;

        }

    }

    FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchSysCtrl::"));
    FreeBT_IoDecrement(deviceExtension);

    return ntStatus;

}