WinPE(Windows PE)のこと
WinPE(Windows PE)環境は、緊急時にUSB Bootできるレスキュー環境として広く知られている様子。
私は、Windowsのキッティング作業でお世話になっている。
WinPeのこと
WinPEを起動すると、CUI コンソールが標準で立ち上がる。
コマンドラインツールとしてwpeutil.exeが用意されているので、【wpeutil shutdown】を発呼することでちゃんとシャットダウンできるのだが、CUI コンソールを単純に×閉じ(またはCUIコンソールで【exit】を発呼)しちゃった場合、再起動しちゃう場合はまだいいほうで、最悪の場合はコンソールだけが閉じられて何もできない”だるまさん状態”(=「手も足も出ない」の意味で使っています)になってしまう。
WinPE環境で動くキッティングツールをいろいろ考えて、手始めに自作アプリからシャットダウンできるかどうか、挑戦してみることに。
公式情報によると、WinPEアプリを作成することは可能ということで、wpeutil.dllが用意されている。
便利なのぞき見ToolをGetだぜ!!
公式情報によると、WinMain 関数と同じ関数シグネチャとなっているようなので、そのように解釈し、コード例のInitializeNetworkingWに倣うのが素直でよろしいかと。
DLLをのぞき見するためにお世話になったのが「Dependencies v1.11.1.0」。有名なDependency WalkerをC#で書き直してオープンソースにしたものだとか。
シャットダウン命令はコマンドラインの様子からしてもオプション無しなので、All NULLと固く決意。
稚拙なsource codeをお披露目
//---------------------------------------------------------------------------
// WinMain Functionと同じ関数Signature
//
typedef int (*WpeutilFunction)(
HINSTANCE hInst,
HINSTANCE hPrev,
LPTSTR lpszCmdLine,
int nCmdShow
);
//---------------------------------------------------------------------------
// function name: _shutdown
// parameter : none
// return : [error code] or [0]
//
int _cdecl _shutdown(void) {
HMODULE hWpeutil = NULL;
WpeutilFunction fnc = NULL;
//LoadLibraryしたら、最後にFreeLibraryするのがお作法。
hWpeutil = LoadLibrary(_T("wpeutil"));
if (hWpeutil == NULL) {
return GetLastError();
}
//Dependenciesで見つけたShutdownW
fnc = (WpeutilFunction)GetProcAddress(hWpeutil, "ShutdownW");
if (fnc == NULL) {
FreeLibrary(hWpeutil);
return GetLastError();
}
//All NULLでキメてやる
fnc(NULL,NULL,NULL,NULL);
//LoadLibraryしたら、最後にFreeLibraryするのがお作法。
FreeLibrary(hWpeutil);
return 0;
}
実行結果
結果は成功でした。
本当に成功したのかどうかは正直分かりませんが、シャットダウンすることには成功しました。
今回の検証環境について
今回の検証に使用した環境を紹介。
DELL XPS 13 2-in-1(7390)
Windows 11 Pro(version 21H2 build 22000.556)
Oracle VM VirtualBox6.1
Windows Assessment & Deployment Kit(Windows ADK)
Windows PE Add-on
Embarcadero C++Builder 10.4 Community Edition
Dependencies v1.11.1.0