kkAyatakaのメモ帳。

誰かの役に立つかもしれない備忘録。

Win32 APIを使ってOSを再起動する

ちょっと必要になって調べてた。呼び出す関数はExitWindowsExなんだけど特権の調整が必要で単純に呼び出すだけでは成功しない。

ExitWindowsExから調べていって、LUID_AND_ATTRIBUTESのところで...

Its meaning is dependent on the definition and use of the LUID

LUID_AND_ATTRIBUTES

といわれて、SE_SHUTDOWN_NAMEで調べたらサンプルが出てきたというオチ。以下はサンプルベースでは無くて、それまでに作っていたコード。

#include <Windows.h>

int main() {
  HANDLE token = NULL;
  OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &token);
  if (token) {
    LUID luid = {};
    LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &luid);

    LUID_AND_ATTRIBUTES attr = { luid, SE_PRIVILEGE_ENABLED };

    TOKEN_PRIVILEGES p = {};
    p.PrivilegeCount = 1;
    p.Privileges[0] = attr;

    AdjustTokenPrivileges(token, FALSE, &p, 0, 0, 0);

    CloseHandle(token);
  }

  // 第2引数は値が豊富な上に、推奨される組み合わせがある
  ExitWindowsEx(EWX_REBOOT, SHTDN_REASON_MAJOR_SYSTEM | SHTDN_REASON_MINOR_NETWORK_CONNECTIVITY);
}

ExitWindowsExの第2引数はパターンが豊富なのできちっとリファレンスを参照したほうが良い。

ExitWindowsExにはなじみが無かったんだけど、手札として持っておくと何かあったときに使えそうな感じ。

結局SE_SHUTDOWN_NAMESE_PRIVILEGE_ENABLEDを結びつける文書って見つからなかったんだけど、他の値を使うときはどうなるのか...

参考