64bit プロセス判定
IsWow64Process はWOW64か否かしか見ないため、次のような結果を返す。
OS | 32 | 64 | 64 |
---|---|---|---|
Process | 32 | 32 | 64 |
結果 | FALSE | TRUE | FALSE |
よって実行環境をGetNativeSystemInfo*1で調べて、64bitだった場合IsWow64Processを使う。
// 指定したプロセスがx86x64アーキテクチャのどちらで動いているか調査 // 調査に成功した場合関数はTRUEを返し、is64bitsの値を更新する // どちらか判断できない場合関数はFALSEを返す BOOL Check64bitProcess(__in DWORD pid, // 調査対象のプロセスID __out BOOL* is64bits) // 調査結果を受け取るポインタ(x64ならTRUE、x86ならFALSE) { _ASSERTE(is64bits && "NULLだめ"); // 最小権限でプロセスを開き、PIDの確認を行う OSVERSIONINFO osv; osv.dwOSVersionInfoSize = sizeof(osv); DWORD access = (::GetVersionEx(&osv) && osv.dwMajorVersion >= 6) ? PROCESS_QUERY_LIMITED_INFORMATION : PROCESS_QUERY_INFORMATION; if (!::CloseHandle(::OpenProcess(access, FALSE, pid))) { // 指定されたプロセスは存在しない return FALSE; } // 確認用関数を拾ってくる typedef BOOL (WINAPI* LPFN_ISWOW64PROCESS)(HANDLE hProcess, PBOOL Wow64Process); static LPFN_ISWOW64PROCESS IsWow64Process = (LPFN_ISWOW64PROCESS)::GetProcAddress( ::GetModuleHandle(_T("kernel32.dll")), "IsWow64Process"); typedef void (WINAPI *LPFN_GETNATIVESYSTEMINFO)(LPSYSTEM_INFO lpSystemInfo); static LPFN_GETNATIVESYSTEMINFO GetNativeSystemInfo = (LPFN_GETNATIVESYSTEMINFO)::GetProcAddress( ::GetModuleHandle(_T("kernel32.dll")), "GetNativeSystemInfo"); if (!IsWow64Process || !GetNativeSystemInfo) { // WOW64対応関数をエクスポートしていないバージョンのWindowsでは64bitプロセスはありえない *is64bits = FALSE; return TRUE; } SYSTEM_INFO sysinfo; GetNativeSystemInfo(&sysinfo); if (sysinfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) { // x64アーキテクチャのため、WOW64チェック HANDLE process = ::OpenProcess(access, FALSE, pid); if (!process) { return FALSE; } BOOL success = IsWow64Process(process, is64bits); ::CloseHandle(process); *is64bits = !(*is64bits); // iswow64 == TRUE == 32bits process return success; } else if (sysinfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) { // x86アーキテクチャで動くWindowsでは64bitプロセスはありえない *is64bits = FALSE; return TRUE; } else { // CPUアーキテクチャが不明。関数はとりあえず失敗する return FALSE; } }
コメントの "最小権限で〜〜" のくだりは無くてもいい。そうすると状況によってはPIDが不正値でも「32bitプロセスだよ!」って言ってくるが。
あと権限も常にPROCESS_QUERY_INFORMATIONだけでいいかもね。PROCESS_QUERY_INFORMATIONだとProtected Processのハンドルが取得できなくて失敗するようになっちゃうけど。