なぜGetLastInputInfo()は偽装中のユーザーの情報を返さないのか?
GetLastInputInfo()関数は、現在のスレッドが偽装しているユーザーではなく、物理的にログオンしている対話型ユーザーの最終入力情報を常に返します。これは、このAPIがセッション全体の最後の入力時刻を追跡するよう設計されており、スレッドごとの偽装状態とは独立して動作するためです。
背景メモ
- この記事が扱っているのは、Windowsの「偽装(impersonation)」という仕組み。あるスレッド(実行中の処理の単位)が、本来のプロセス(アプリ)のユーザーとは別のユーザーになりすまして動作する機能で、サーバーアプリなどで使われる。
- `GetLastInputInfo()` はWindows APIの一つで、「最後にユーザーがキーボードやマウスを操作したのはいつか」という情報を取得する。アイドル状態の検出などに使われる。
- 問題の核心:スレッドがユーザーBを偽装している状態でこのAPIを呼んでも、「ユーザーBが最後に入力した時刻」は返ってこない。その理由を、Microsoftの開発者ブログ(The Old New Thing、通称「老舗のWindows内部解説ブログ」)がWindowsの設計原則から解説している。
- カギは「セッション」という概念。Windowsでは入力情報は「セッション単位」で管理されており、偽装はスレッドの「トークン(身分証)」を差し替えるだけなので、入力情報まで偽装ユーザーに紐づくようにはなっていない。設計上は意図的な制限であり、バグではない。