私の当初の目標は、実際の電源状態が開始する前にWindows OSが入る電源状態を判別することであったと言って、これを前置きします。別のスレッドで同様の質問をしました。これを知る必要があります。したがって、なぜこれが必要なのかについて長い説明をすることなく、PCに接続したハードウェアがそれ自体の電源管理のためにこの情報を必要とすることを簡単に述べさせてください。
この時点で、デバイスドライバーの作成も避けようとしているので、代わりにユーザーモード/ローカルサービスコードから解決策を見つけたいと思います。
さて、目前の問題に戻りましょう。Windows OSは、たとえば、再起動とシャットダウン、またはスリープと休止状態を区別できない基本的な電源通知のみを提供するため、これらの電源状態を開始するWindowsAPIにグローバルフックを実装することを考えました。 (スリープ/休止状態の場合はSetSuspendState 、再起動/シャットダウンの場合はInitiateSystemShutdownです。) C ++/WinAPIを使用してグローバルAPIフックを実装する方法を説明するこの記事も見つかりました。
したがって、電源イベントが発生する前にコマンドをインターセプトできるようにするには、システムレジストリに電源イベントのタイプ(以下のPOWER_ACTIONおよびSYSTEM_POWER_STATEを参照)を書き込み、その後のユーザーモード/ローカルサービスコードから読み取ります。 WM_POWERBROADCAST通知を受信します。
私はグローバルAPIフックを行ったことがないので、コーディングに取り掛かる前に、このサイトの専門家にアドバイスを求めています。これはどう思いますか?
また、API自体に関するいくつかの技術的な質問:
1:調査を行ったところ、カーネルレベルのほとんどの高レベルのPower APIは、 Ntdll.dllからエクスポートされたNtInitiatePowerActionまたはZwInitiatePowerActionのいずれかに要約されているようです。どちらも同じように見えますが、問題は、どちらにフックする必要があるかということです。
2:これらのカーネルレベルのAPIに関するMicrosoftのドキュメントが不足しています。私が見つけたのはこれだけです。誰かがそれに追加する情報を持っていますか?
NTSYSAPI
NTSTATUS
NTAPI
NtInitiatePowerAction(
IN POWER_ACTION SystemAction,
IN SYSTEM_POWER_STATE MinSystemState,
IN ULONG Flags,
IN BOOLEAN Asynchronous
);
typedef enum _POWER_ACTION {
PowerActionNone,
PowerActionReserved,
PowerActionSleep,
PowerActionHibernate,
PowerActionShutdown,
PowerActionShutdownReset,
PowerActionShutdownOff
} POWER_ACTION, *PPOWER_ACTION;
typedef enum _SYSTEM_POWER_STATE {
PowerSystemUnspecified = 0,
PowerSystemWorking,
PowerSystemSleeping1,
PowerSystemSleeping2,
PowerSystemSleeping3,
PowerSystemHibernate,
PowerSystemShutdown
} SYSTEM_POWER_STATE, *PSYSTEM_POWER_STATE;
//Flags seem to be the these ones
POWER_ACTION_QUERY_ALLOWED
POWER_ACTION_UI_ALLOWED
POWER_ACTION_OVERRIDE_APPS
POWER_ACTION_LOCK_CONSOLE
POWER_ACTION_DISABLE_WAKES
POWER_ACTION_CRITICAL
上記のフラグの実際の値は、ここで次のようになります。
3: WindowsXPSP3以降のOSで動作するためにこれが必要です。XP以降、これらすべてがサポートされているようですが、私の懸念は、公式のMSDNドキュメントに記載されていないカーネルレベルのAPIです。
とにかく、これについて何か洞察を聞いていただければ幸いです。