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

📄 power.c

📁 enumerates Plug-n-Play RS-232 devices that are compliant with the current revision of Plug and Play
💻 C
字号:
/*++
Copyright (c) 1997  Microsoft Corporation

Module Name:

    POWER.C

Abstract:

    This module contains contains the plugplay power calls for the serenum
    PNP / WDM BUS driver.


Environment:

    kernel mode only

Notes:


Revision History:


--*/

#include "pch.h"

#ifdef ALLOC_PRAGMA
//#pragma alloc_text (PAGE, Serenum_Power)
//#pragma alloc_text (PAGE, Serenum_FDO_Power)
//#pragma alloc_text (PAGE, Serenum_PDO_Power)
#endif

NTSTATUS
Serenum_Power (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
/*++
--*/
{
    PIO_STACK_LOCATION  irpStack;
    NTSTATUS            status;
    PCOMMON_DEVICE_DATA commonData;

    PAGED_CODE ();

    status = STATUS_SUCCESS;
    irpStack = IoGetCurrentIrpStackLocation (Irp);
    ASSERT (IRP_MJ_POWER == irpStack->MajorFunction);

    commonData = (PCOMMON_DEVICE_DATA) DeviceObject->DeviceExtension;

    if (commonData->IsFDO) {
        status =
            Serenum_FDO_Power ((PFDO_DEVICE_DATA) DeviceObject->DeviceExtension,
                Irp);
    } else {
        status =
            Serenum_PDO_Power ((PPDO_DEVICE_DATA) DeviceObject->DeviceExtension,
                Irp);
    }

    return status;
}

NTSTATUS
Serenum_FDOPowerComplete (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PVOID Context
    );

VOID
Serenum_PowerFDOControllingPDO (
    IN PDEVICE_OBJECT DeviceObject,
    IN UCHAR MinorFunction,
    IN POWER_STATE PowerState,
    IN PVOID Irp,
    IN PIO_STATUS_BLOCK IoStatus
    );

NTSTATUS
Serenum_FDO_Power (
    PFDO_DEVICE_DATA    Data,
    PIRP                Irp
    )
/*++
--*/
{
    NTSTATUS            status;
    BOOLEAN             hookit = FALSE;
    POWER_STATE         powerState;
    POWER_STATE_TYPE    powerType;
    PIO_STACK_LOCATION  stack;

    stack = IoGetCurrentIrpStackLocation (Irp);
    powerType = stack->Parameters.Power.Type;
    powerState = stack->Parameters.Power.State;

    PAGED_CODE ();

    status = Serenum_IncIoCount (Data);
    if (!NT_SUCCESS (status)) {
        PoStartNextPowerIrp (Irp);
        Irp->IoStatus.Information = 0;
        Irp->IoStatus.Status = status;
        IoCompleteRequest (Irp, IO_NO_INCREMENT);
        return status;
    }

    switch (stack->MinorFunction) {
    case IRP_MN_SET_POWER:
	//
	// If it hasn't started, we just pass it through
	//

	if (Data->Started != TRUE) {
	    status = Irp->IoStatus.Status = STATUS_SUCCESS;
	    break;
	}

        Serenum_KdPrint(Data,
                     SER_DBG_PNP_TRACE,
                     ("Serenum-PnP Setting %s state to %d\n",
                      ((powerType == SystemPowerState) ?  "System" : "Device"),
                      powerState.SystemState));

        switch (powerType) {
        case DevicePowerState:

            status = Irp->IoStatus.Status = STATUS_SUCCESS;

            if (Data->DeviceState < powerState.DeviceState) {
                //
                // Powering down
                // Need to stop polling at the first sign of power down
                //
                Serenum_StopPolling(Data, SERENUM_POWER_LOCK);

#if 0
              if (Data->AttachedPDO) {
                 ASSERT(((PCOMMON_DEVICE_DATA) Data->AttachedPDO->
                        DeviceExtension)->DeviceState >=
                        powerState.DeviceState);

                }
#endif // DBG
                PoSetPowerState (Data->Self, powerType, powerState);
                Data->DeviceState = powerState.DeviceState;
            } else if (Data->DeviceState > powerState.DeviceState) {
                //
                // Powering Up
                //
                hookit = TRUE;
            }

            break;

        case SystemPowerState:
            break;
        }
        break;

    case IRP_MN_QUERY_POWER:
        //
        Data->PowerQueryLock = TRUE;
        status = Irp->IoStatus.Status = STATUS_SUCCESS;
        break;

    default:
        break;
    }

    IoCopyCurrentIrpStackLocationToNext (Irp);

    if (hookit) {
        status = Serenum_IncIoCount (Data);
        ASSERT (STATUS_SUCCESS == status);
        IoSetCompletionRoutine (Irp,
                                Serenum_FDOPowerComplete,
                                NULL,
                                TRUE,
                                TRUE,
                                TRUE);

        status = PoCallDriver (Data->TopOfStack, Irp);

    } else {
        //
        // Power IRPS come synchronously; drivers must call
        // PoStartNextPowerIrp, when they are ready for the next power
        // irp.  This can be called here, or in the completetion
        // routine, but never the less must be called.
        //
        PoStartNextPowerIrp (Irp);

        status =  PoCallDriver (Data->TopOfStack, Irp);
    }

    Serenum_DecIoCount (Data);
    return status;
}

VOID
Serenum_PowerFDOControllingPDO (
    IN PDEVICE_OBJECT DeviceObject,
    IN UCHAR MinorFunction,
    IN POWER_STATE PowerState,
    IN PVOID Irp,
    IN PIO_STATUS_BLOCK IoStatus
    )
/*++
--*/
{
    NTSTATUS            status = STATUS_SUCCESS;
    PFDO_DEVICE_DATA    fdoData;

    UNREFERENCED_PARAMETER (MinorFunction);

    fdoData = (PFDO_DEVICE_DATA) DeviceObject->DeviceExtension;

    if (fdoData->DeviceState == PowerState.DeviceState) {
        //
        // If the device has been fully powered up, then the only way it
        // should get this irp is if this fdo had to manually repower
        // up its child pdo.  So now we should start polling again.
        //
        if (fdoData->DeviceState == PowerDeviceD0) {
            //
            // Should only start polling again when fully powered up.
            //
            Serenum_StartPolling(fdoData, SERENUM_POWER_LOCK);
        }
        ((PIRP) Irp)->IoStatus.Information = 0;
        ((PIRP) Irp)->IoStatus.Status = status;
    } else {
        //
        // The PDO had to be manually powered down.  Now that it's done, we're
        // allowed to power down the FDO.
        //
        PoSetPowerState (fdoData->Self, DevicePowerState, PowerState);
        fdoData->DeviceState = PowerState.DeviceState;

        PoStartNextPowerIrp ((PIRP) Irp);
        IoSkipCurrentIrpStackLocation ((PIRP) Irp);
        IoStatus->Status = PoCallDriver (fdoData->TopOfStack, (PIRP) Irp);
    }
}

NTSTATUS
Serenum_FDOPowerComplete (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PVOID Context
    )
/*++
--*/
{
    POWER_STATE         powerState;
    POWER_STATE_TYPE    powerType;
    PIO_STACK_LOCATION  stack;
    PFDO_DEVICE_DATA    data;

    UNREFERENCED_PARAMETER (Context);

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

    data = (PFDO_DEVICE_DATA) DeviceObject->DeviceExtension;
    stack = IoGetCurrentIrpStackLocation (Irp);
    powerType = stack->Parameters.Power.Type;
    powerState = stack->Parameters.Power.State;

    switch (stack->MinorFunction) {
    case IRP_MN_SET_POWER:
        switch (powerType) {
        case DevicePowerState:
            //
            // Powering Up
            //
            ASSERT (powerState.DeviceState < data->DeviceState);
            data->DeviceState = powerState.DeviceState;

            PoSetPowerState (data->Self, powerType, powerState);

            if (data->LastSetPowerState == PowerDeviceD0) {
               //
               // Time to start polling again!
               //
               Serenum_StartPolling(data, SERENUM_POWER_LOCK);
            }
            break;

        default:
           break;
        }
        break;

    case IRP_MN_QUERY_POWER:

        ASSERT (IRP_MN_QUERY_POWER != stack->MinorFunction);
        break;

    default:
        ASSERT (0xBADBAD == IRP_MN_QUERY_POWER);
        break;
    }


    PoStartNextPowerIrp (Irp);
    Serenum_DecIoCount (data);

    return STATUS_SUCCESS; // Continue completion...
}

VOID
Serenum_PDOPowerComplete (
    IN PDEVICE_OBJECT DeviceObject,
    IN UCHAR MinorFunction,
    IN POWER_STATE PowerState,
    IN PVOID Irp,
    IN PIO_STATUS_BLOCK IoStatus
    );

NTSTATUS
Serenum_PDO_Power (
    PPDO_DEVICE_DATA    PdoData,
    PIRP                Irp
    )
/*++
--*/
{
    NTSTATUS            status = STATUS_SUCCESS;
    PIO_STACK_LOCATION  stack;
    POWER_STATE         powerState;
    POWER_STATE_TYPE    powerType;

    stack = IoGetCurrentIrpStackLocation (Irp);
    powerType = stack->Parameters.Power.Type;
    powerState = stack->Parameters.Power.State;

    switch (stack->MinorFunction) {
    case IRP_MN_SET_POWER:
        switch (powerType) {
        case DevicePowerState:
            if (PdoData->DeviceState > powerState.DeviceState) {
                PoSetPowerState (PdoData->Self, powerType, powerState);
                PdoData->DeviceState = powerState.DeviceState;
            } else if (PdoData->DeviceState < powerState.DeviceState) {
                //
                // Powering down.
                //
                PoSetPowerState (PdoData->Self, powerType, powerState);
                PdoData->DeviceState = powerState.DeviceState;
            }
            break;

        case SystemPowerState:
           status = STATUS_SUCCESS;
           break;

        default:
            status = STATUS_NOT_IMPLEMENTED;
            break;
        }
        break;

    case IRP_MN_QUERY_POWER:
        PdoData->PowerQueryLock = TRUE;
        status = STATUS_SUCCESS;
        break;

    case IRP_MN_WAIT_WAKE:
    case IRP_MN_POWER_SEQUENCE:
    default:
        status = STATUS_NOT_IMPLEMENTED;
        break;
    }

    Irp->IoStatus.Status = status;
    PoStartNextPowerIrp (Irp);
    IoCompleteRequest (Irp, IO_NO_INCREMENT);
    return status;
}



⌨️ 快捷键说明

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