如题:
WDM设备驱动程序中能修改系统的电源状态吗?如何修改?

解决方案 »

  1.   

    ZwSetSystemPowerState
        ZwSetSystemPowerState sets the power state of the system.NTSYSAPI
    NTSTATUS
    NTAPI
    ZwSetSystemPowerState(
      IN POWER_ACTION SystemAction,
      IN SYSTEM_POWER_STATE MinSystemState,
      IN ULONG Flags
    );
    Parameters
        SystemAction
            Specifies the power action to perform.The permitted values are drawn from the enumeration POWER_ACTION:typedef enum _POWER_ACTION {
        PowerActionNone,
        PowerActionReserved,
        PowerActionSleep,
        PowerActionHibernate,
        PowerActionShutdown,
        PowerActionShutdownReset,
        PowerActionShutdownOff
    } POWER_ACTION, *PPOWER_ACTION;    MinSystemState
            Specifies the minimum power state to enter as a result of performing the action. The permitted values are drawn from the enumeration SYSTEM_POWER_STATE:typedef enum _SYSTEM_POWER_STATE {
        PowerSystemUnspecified = 0,
        PowerSystemWorking,
        PowerSystemSleeping1,
        PowerSystemSleeping2,
        PowerSystemSleeping3,
        PowerSystemHibernate,
        PowerSystemShutdown
    } SYSTEM_POWER_STATE, *PSYSTEM_POWER_STATE;    Flags
            Qualifies the SystemAction. Defined values include:POWER_ACTION_QUERY_ALLOWED
    POWER_ACTION_UI_ALLOWED
    POWER_ACTION_OVERRIDE_APPS
    POWER_ACTION_LOCK_CONSOLE
    POWER_ACTION_DISABLE_WAKES
    POWER_ACTION_CRITICALReturn Value
         Returns STATUS_SUCCESS or an error status, such as STATUS_PRIVILEGE_NOT_HELD, STATUS_ALREADY_COMMITTED, or STATUS_CANCELLED.
      

  2.   

    待机的话ZwSetPowerAction (PowerActionSleep, PowerSystemSleeping1, 0);
    最后一个参数也可以换成
    POWER_ACTION_QUERY_ALLOWED,这样会向应用程序进行询问,如果有应用程序不允许进入睡眠状态,调用将失败。休眠的话ZwSetPowerAction (PowerActionHibernate, PowerSystemHibernate, 0);
    最后一个参数也可以换成
    POWER_ACTION_QUERY_ALLOWED,这样会向应用程序进行询问,如果有应用程序不允许进入休眠状态,调用将失败。不使用ZwSetPowerAction的话,也可以用另外一个Native API
    ZwInitiatePowerAction,这个API仅比上一个多一个参数,在最后。前三个参数完全一样。最后一个参数传0就可以了。win32 API中有一个SetSystemPowerState,它调用的是ZwInitiatePowerAction。你需要包含的ddk头文件是
    ntpoapi.h可能需要将函数名的前缀Zw换成Nt
      

  3.   

    好像没有ZwSetPowerAction啊,在WIN2000 DDK里面找不到ZwInitiatePowerAction和ZwSetPowerAction,能否举个例子来看看啊?
      

  4.   

    前面说了可能需要将函数名的前缀Zw换成Nt
    ZwSetPowerAction换成NtSetPowerAction
    ZwInitiatePowerAction换成NtInitiatePowerAction
      

  5.   

    前面不是已经给出代码了么睡眠
    ZwSetPowerAction (PowerActionSleep, PowerSystemSleeping1, 0);休眠
    ZwSetPowerAction (PowerActionHibernate, PowerSystemHibernate, 0);
      

  6.   

    谢谢!让您见笑了,不过我还是不明白,我加了#include "ntpoapi.h",然后调用NtSetPowerAction (PowerActionSleep, PowerSystemSleeping1, 0);
    可是提示这个没被定义,于是我在NTDDK查找包含NtSetPowerAction和ZwSetPowerAction都没找到啊。
      

  7.   

    我找到
    NTSYSCALLAPI                        // only called by WinLogon
    NTSTATUS
    NTAPI
    NtSetSystemPowerState(
        IN POWER_ACTION SystemAction,
        IN SYSTEM_POWER_STATE MinSystemState,
        IN ULONG Flags                  // POWER_ACTION_xxx flags
        );
      

  8.   

    可是加入
    NtSetSystemPowerState (PowerActionSleep, PowerSystemSleeping1, 0);
    后,BUILD出现
    unresolved external symbol _imp_NtSetSystemPowerState@12
      

  9.   

    编译的时候好象得加上库ntdll.lib
      

  10.   

    我加了
    #pragma comment(lib,"ntdll.lib")
    还是不行
      

  11.   

    奇怪了,问一下,
    #pragma comment(lib,"ntdll.lib")
    这个在BUILD的时候会不会进行检测,我把
    #pragma comment(lib,"ntdll.lib")故意改成#pragma comment(lib,"ntdllAAAA.lib"),实际上没有ntdllAAAA.lib,可是BUILD的时候还是只出现“unresolved external symbol _imp_NtSetSystemPowerState@12”这个错误??不明白这是怎么回事。
      

  12.   

    我把NtSetSystemPowerState (PowerActionSleep, PowerSystemSleeping1, 0);删除,而加上#pragma comment(lib,"ntdllAAAA.lib"),在BUILD的时候也不会出错,这是怎么回事?
      

  13.   

    #pragma comment (lib, "***.lib")
    当***.lib不存在时是不提示错误的你最好把ntdll.lib拷贝到当前目录来,这样能保证找到ntdll.lib
      

  14.   

    我把ntdll.lib拷到当前目录下,然后加入#pragma comment(lib,"ntdll.lib")
    在BUILD的时候,还是出现
    unresolved external symbol _imp_NtSetSystemPowerState@12
      

  15.   

    你是什么的ddk?不太可能啊,我查过ntdll.lib了,里面有_imp_NtSetSystemPowerState@12这个符号啊你用ultra edit或其他的文本编辑器打开ntdll.lib看看里面有没有_imp_NtSetSystemPowerState@12 这个字符串
      

  16.   

    我用的是WIN2000DDK,ntdll.lib里面有_NtSetSystemPowerState@12,可是BUILD的时候还是错误,是不是#pragma comment(lib,"ntdll.lib")不起作用??
      

  17.   

    估计是
    以前我好象也碰到过
    我记得是我需要加上ntoskrnl.lib我用#pragma comment (lib, "...")也不成不过不起作用,你看看能不能在source文件里面加呢
      

  18.   

    哈哈,果然在source里面加入
    TARGETLIBS=$(BASEDIR)\lib\*\free\ntdll.lib后,BUILD通过,我先测试一下,看看行不行。
      

  19.   

    好像不行啊,我在驱动里面是这样做的
    POWER_STATE PowerState = Irpstack->Parameters.Power.State;
    if (PowerState.SystemState==PowerSystemHibernate)
    {
     NtSetSystemPowerState (PowerActionSleep, PowerSystemSleeping1, 0);
    }
    可是当我执行休眠时,NtSetSystemPowerState不起作用,机器继续进入休眠啊
      

  20.   

    你看看NtSetSystemPowerState的返值是什么, DebugPrint一下另外,如果你是要防止系统被休眠的话,可以不使用驱动,写一个小的程序,创建一个窗口当系统要休眠时,会发送WM_POWERBROADCAST消息来向每个应用程序查询是否允许休眠。wParam值是PBT_APMQUERYSUSPEND,只要你处理这个消息并返回BROADCAST_QUERY_DENY就可以了不过当强制休眠时,是不会发送WM_POWERBROADCAST消息的。估计在驱动里面也无法取消强制的休眠
      

  21.   

    不能用窗口,只能用驱程啊。
    请问DebugPrint怎么用啊?以前没用过。
      

  22.   

    不能用窗口的,一定要用驱动的,真是痛苦,这个问题困了我快一个月了。
    DebugPrint要什么支持,要怎么用?以前没用过啊。
      

  23.   

    系统准备进入休眠状态时先向各个驱动发送IRP_MN_QUERY_POWER查询驱动是不是允许进入休眠状态如果所有驱动都允许,则最后向每个驱动发送IRP_MN_SET_POWER所以你好象可以不用调用那些函数就可以实现。只要在处理IRP_MN_QUERY_POWER时返回相应的值就可以了,下面的东西来自msdnIRP_MN_QUERY_POWER
      Major Code
        IRP_MJ_POWERWhen Sent
            The Power Manager or a device power policy owner sends this IRP to determine whether it can change the system or device power state, typically to go to sleep. A driver must call PoRequestPowerIrp to allocate and send this IRP.        The Power Manager sends this IRP at IRQL = PASSIVE_LEVEL to device stacks that set the DO_POWER_PAGABLE flag in the PDO.         The Power Manager can send the IRP at IRQL = DISPATCH_LEVEL if the DO_POWER_INRUSH flag is set. Such drivers cannot directly or indirectly access any paged code or data.Input
            Parameters.Power.Type specifies the type of power state being set, either SystemPowerState or DevicePowerState.        Parameters.Power.State specifies the power state itself, as follows:             * If Parameters.Power.Type is SystemPowerState, the value is an enumerator of the SYSTEM_POWER_STATE type. 
                * If Parameters.Power.Type is DevicePowerState, the value is an enumerator of the DEVICE_POWER_STATE type. 
            Parameters.Power.ShutdownType specifies additional information about the requested transition. Possible values are enumerators of the POWER_ACTION type.Output
            None.I/O Status Block
            A driver sets Irp->IoStatus.Status to STATUS_SUCCESS to indicate that the device can enter the requested state. A driver sets any appropriate failure status to indicate that it cannot enter the requested state.
      

  24.   

    是啊,按道理来说,我只要在IRP_MJ_POWER对休眠运行不进行处理就可以防止机器进入休眠,可是不进行处理的话,要怎么要返回这个值?
      

  25.   

    是啊,按道理来说,我只要在IRP_MJ_POWER对休眠运行不进行处理就可以防止机器进入休眠,可是不进行处理的话,要怎么要返回这个值?
    --------------------------------------------------------------------------
    前面有了啊I/O Status Block
            A driver sets Irp->IoStatus.Status to STATUS_SUCCESS to indicate that the device can enter the requested state. A driver sets any appropriate failure status to indicate that it cannot enter the requested state.
    另外,如果对休眠不进行任何处理,当选择休眠时,系统会提示不能进入休眠,我想让系统不提示禁止休眠,而把休眠的动作转成待机处理,这样行不行?----------------------------------------------------------
    这好象不行 :(没查到
      

  26.   

    我要对IRP_MN_QUERY_POWER怎么处理啊?能否写个代码出来看看。
      

  27.   

    在处理IRP_MN_QUERY_POWER时将Irp->IoStatus.Status 设置成任何一个失败代码都将会阻止系统进入指定的power state
      

  28.   

    为了使IRP_MN_QUERY_POWER请求失效,驱动程序应该采取下列措施:
    1.调用PoStartNextPowerIrp,表明其已准备处理下一个电源IRP。
    2.设置Irp->IoStatus.Status为失效状态,并且调用IoCompleteRequest,指定IO_NO_INCREMENT。不把IRP传递到更下面的设备栈中。 
    3.调用IoReleaseRemoveLock,释放以前获取的锁。 
    4.从其DispatchPower例程中返回一个失效状态。 这里面的第3、4点不知道该怎么做?Irp->IoStatus.Status为失效状态,失效状态的值为多少,我随便设了一个11,不知道行不行?
      

  29.   

    xstring(麻雀),你有没有驱动开发这方面的资料,我手头上的资料太少了,你能不能发一份给我?[email protected],谢谢您!
      

  30.   

    昨天我用返回值STATUS_UNSUCCESSFUL搞定了阻止休眠,谢谢您了!另外还有问题请教,新开一贴中请教。