⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 power.c

📁 1394 驱动程序源代码,有兴趣的朋友可以看看
💻 C
字号:
/*++

Copyright (c) 1998  Microsoft Corporation

Module Name: 

    power.c
--*/

#include "pch.h"

NTSTATUS
t1394VDev_Power(
    IN PDEVICE_OBJECT   DeviceObject,
    IN PIRP             Irp
    )
{
    NTSTATUS                ntStatus = STATUS_SUCCESS;
    PIO_STACK_LOCATION      IrpSp;
    PDEVICE_EXTENSION       deviceExtension;
    POWER_STATE             State;
    KIRQL                   Irql;

    ENTER("t1394VDev_Power");

    deviceExtension = DeviceObject->DeviceExtension;

    IrpSp = IoGetCurrentIrpStackLocation(Irp);

    State = IrpSp->Parameters.Power.State;

    TRACE(TL_TRACE, ("Power.Type = 0x%x\n", IrpSp->Parameters.Power.Type));
    TRACE(TL_TRACE, ("Power.State.SystemState = 0x%x\n", State.SystemState));
    TRACE(TL_TRACE, ("Power.State.DeviceState = 0x%x\n", State.DeviceState));

    switch (IrpSp->MinorFunction) {

        case IRP_MN_SET_POWER:
            
            TRACE(TL_TRACE, ("IRP_MN_SET_POWER\n"));                        

            switch (IrpSp->Parameters.Power.Type) {

                case SystemPowerState:
                    TRACE(TL_TRACE, ("SystemPowerState\n"));
                    
                    // Send the IRP down
                    IoMarkIrpPending (Irp);
                    IoCopyCurrentIrpStackLocationToNext(Irp);
                    IoSetCompletionRoutine(Irp,
                        (PIO_COMPLETION_ROUTINE) t1394VDev_SystemSetPowerIrpCompletion,
                        NULL, TRUE, TRUE, TRUE);

                    PoCallDriver(deviceExtension->StackDeviceObject, Irp);
                    ntStatus = STATUS_PENDING;
                    break;
                
                case DevicePowerState:
                    TRACE(TL_TRACE, ("DevicePowerState\n"));
                    TRACE(TL_TRACE, ("Current device state = 0x%x, new device state = 0x%x\n", 
                                     deviceExtension->CurrentDevicePowerState, State.DeviceState));

                    PoStartNextPowerIrp(Irp);
                    IoCopyCurrentIrpStackLocationToNext(Irp);
                    ntStatus = PoCallDriver(deviceExtension->StackDeviceObject, Irp);
                    break; // DevicePowerState

                default:
                    break;

            }
            break; // IRP_MN_SET_POWER

        case IRP_MN_QUERY_POWER:
            TRACE(TL_TRACE, ("IRP_MN_QUERY_POWER\n"));

            PoStartNextPowerIrp(Irp);
            IoSkipCurrentIrpStackLocation(Irp);
            ntStatus = PoCallDriver(deviceExtension->StackDeviceObject, Irp);

            break; // IRP_MN_QUERY_POWER

        default:
            TRACE(TL_TRACE, ("Default = 0x%x\n", IrpSp->MinorFunction));

            PoStartNextPowerIrp(Irp);
            IoSkipCurrentIrpStackLocation(Irp);
            ntStatus = PoCallDriver(deviceExtension->StackDeviceObject, Irp);

            break; // default
            
    } // switch

    EXIT("t1394VDev_Power", ntStatus);
    return(ntStatus);
} // t1394Vdev_Power


NTSTATUS
t1394VDev_SystemSetPowerIrpCompletion(
    IN PDEVICE_OBJECT   DeviceObject,
    IN PIRP             Irp,
    IN PVOID            NotUsed
    )
{

    PDEVICE_EXTENSION           deviceExtension     = DeviceObject->DeviceExtension;
    NTSTATUS                    ntStatus            = Irp->IoStatus.Status;
    PIO_STACK_LOCATION          stack               = IoGetCurrentIrpStackLocation(Irp);
    POWER_STATE                 state               = stack->Parameters.Power.State;
    POWER_COMPLETION_CONTEXT    *powerContext       = NULL;

    ENTER("t1394VDev_SystemPowerIrpCompletion");

     if(Irp->PendingReturned)
    {
        IoMarkIrpPending(Irp);
    }

    if (!NT_SUCCESS(ntStatus)) {

        TRACE(TL_TRACE, ("Set System Power Irp failed, status = 0x%x\n", ntStatus));
        PoStartNextPowerIrp(Irp);
        return STATUS_SUCCESS;
    }

    // allocate powerContext
    powerContext = (POWER_COMPLETION_CONTEXT*)
                ExAllocatePool(NonPagedPool, sizeof(POWER_COMPLETION_CONTEXT));

    if (!powerContext) {

        TRACE(TL_TRACE, ("Failed to allocate powerContext, status = 0x%x\n", ntStatus));
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
        goto Exit_SystemSetPowerIrpCompletion;

    } else {

        if (state.SystemState == PowerSystemWorking) {

            state.DeviceState = PowerDeviceD0;
        }
        else {
                    
            state.DeviceState = PowerDeviceD3;
        }
        
        powerContext->DeviceObject = DeviceObject;
        powerContext->SIrp = Irp;
        
        ntStatus = PoRequestPowerIrp(deviceExtension->StackDeviceObject,
                                    IRP_MN_SET_POWER,
                                    state,
                                    t1394VDev_DeviceSetPowerIrpCompletion,
                                    powerContext,
                                    NULL);
        
    }

Exit_SystemSetPowerIrpCompletion:

    if (!NT_SUCCESS(ntStatus)) {


        TRACE(TL_TRACE, ("System SetPowerIrp Completion routine failed = 0x%x\n", ntStatus));

        if (powerContext) {
            ExFreePool(powerContext);
        }

        PoStartNextPowerIrp(Irp);
        Irp->IoStatus.Status = ntStatus;
    }
    else
    {
        ntStatus = STATUS_MORE_PROCESSING_REQUIRED;
    }

    EXIT("t1394VDev_SystemPowerIrpCompletion", ntStatus);    
    return ntStatus;
}



VOID
t1394VDev_DeviceSetPowerIrpCompletion(
    PDEVICE_OBJECT DeviceObject,
    UCHAR MinorFunction,
    POWER_STATE state,
    POWER_COMPLETION_CONTEXT* PowerContext,
    PIO_STATUS_BLOCK IoStatus
    )
{
    PDEVICE_EXTENSION   deviceExtension = (PDEVICE_EXTENSION) PowerContext->DeviceObject->DeviceExtension;
    PIRP                sIrp = PowerContext->SIrp;
    PIRP                Irp;
    PIRB                pIrb;
    CCHAR               StackSize;
    NTSTATUS            ntStatus = IoStatus->Status;
	PIO_WORKITEM		ioWorkItem		= NULL;

    ENTER("t1394VDev_DevicePowerIrpCompletion");

    if(!NT_SUCCESS(ntStatus))
    {
        TRACE(TL_WARNING, ("Device Power Irp failed by driver below us = 0x%x\n", ntStatus));
        goto Exit_t1394VDev_DeviceSetPowerIrpCompletion;
    }

    // set the new power state
    PoSetPowerState(DeviceObject, DevicePowerState, state);

    // figure out how to respond to this power state change
    if (state.DeviceState < deviceExtension->CurrentDevicePowerState)
    {
        // adding power
        // check to see if we are working again
        if (PowerDeviceD0 == state.DeviceState)
        {
            TRACE (TL_TRACE, ("Restarting our device\n"));
            deviceExtension->bShutdown = FALSE;
            
	        // need to update the generation count, queue a work item to do that
	        ioWorkItem = IoAllocateWorkItem (PowerContext->DeviceObject);
	        if (!ioWorkItem)
	        {
		        TRACE(TL_ERROR, ("t1394VDev_DeviceSetPowerIrpCompletion Failed to allocate work item!\n"));
		        goto Exit_t1394VDev_DeviceSetPowerIrpCompletion;
	        }

	        IoQueueWorkItem (ioWorkItem,
						     t1394_UpdateGenerationCount,
						     DelayedWorkQueue,
						     ioWorkItem);
        }
    }
    else
    {
        // removing power
        deviceExtension->bShutdown = TRUE;
    }
        
    // save the current device power state
    deviceExtension->CurrentDevicePowerState = state.DeviceState;

Exit_t1394VDev_DeviceSetPowerIrpCompletion:

    // Here we copy the D-IRP status into the S-IRP
    sIrp->IoStatus.Status = IoStatus->Status;

    // Release the IRP
    PoStartNextPowerIrp(sIrp);    
    sIrp->IoStatus.Information = 0;
    IoCompleteRequest(sIrp, IO_NO_INCREMENT);

    // Cleanup
    ExFreePool(PowerContext);
    
    EXIT("t1394VDev_DevicePowerIrpCompletion", ntStatus);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -