書き直し
x64 環境なのかどうかの判定をする方法。
OS のバージョンを見ても、x64 なのかどうかはわかりません。例えば、32ビット版 Windows XP のバージョンは 5.1 ですが、64ビット版の場合は 5.2 になります。しかし、Windows Server 2003 も、5.2 です。なので、別の方法で調べます。
MSDN を調べると、IsWow64Process 関数(英語)が見つかります。しかし、「64ビット OS 上で動く64ビット アプリケーションの場合は、この関数は FALSE を返す」のだそうです。一応、それなりに作り込めば、32ビット アプリケーションと64ビット アプリケーションは、同じコードを共有できます。したがって、「WOW64 上で動いているか」をチェックするだけでは不完全な場合もあります。
ということで、まず、IsWow64Process 関数があるかどうかを調べ、なければ32ビット OS 上で動く32ビット アプリケーション。関数が存在し、TRUE を返せば64ビット OS 上で動く32ビット アプリケーション。FALSE を返せば、さらに何らかの調査をして、64ビット OS 上で動く64ビット アプリケーションなのか、32ビット OS 上で動く32ビット アプリケーションなのか、という判別を行います。
それはなに?と調べると、GetSystemInfo 関数(英語)を使えば良さそうです。SYSTEM_INFO 構造体(英語)の、wProcessorArchitecture で判別すれば良さそうです。
なお、この関数は、IsWow64Process 関数とセットで使う必要がありそうです。WOW64 上で動いている場合、32ビットだと返事をしそうだからです。WOW64 上で動作している場合に、ベースとなる OS が64ビットなのかどうかを知るには、GetNativeSystemInfo 関数(英語)を使います。なお、GetNativeSystemInfo 関数は、WOW64 上でなければ GetSystemInfo 関数と同等であると書かれていますので、とりあえずこちらを使ってもいいかもしれません。その場合、存在チェックが必要かと思われます。
ビルドできることのみ確認しています。
#include <windows.h>
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
typedef void (WINAPI *LPFN_GETNATIVESYSTEMINFO) (LPSYSTEM_INFO);
typedef enum {
UNKNOWN = 0
, SYSINFO_32PROCESS = 1
, SYSINFO_32PROCESS_ON_WO64 = 2
, SYSINFO_64PROCESS = 3
} BaseSystemInfo;
BOOL Isx64Architecture(void)
{
LPFN_GETNATIVESYSTEMINFO fnGetNativeSystemInfo;
BOOL bIsx64 = FALSE;
SYSTEM_INFO info;
if (fnGetNativeSystemInfo == NULL) {
fnGetNativeSystemInfo = (LPFN_GETNATIVESYSTEMINFO) GetProcAddress(
GetModuleHandle(TEXT("kernel32")), TEXT("GetNativeSystemInfo"));
}
if (fnGetNativeSystemInfo != NULL) {
fnGetNativeSystemInfo(&info);
if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
bIsx64 = TRUE;
} else if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) {
bIsx64 = TRUE;
} else if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) {
bIsx64 = FALSE;
}
}
return bIsx64;
}
BOOL IsWow64(HANDLE processHandle)
{
LPFN_ISWOW64PROCESS fnIsWow64Process;
BOOL bIsWow64 = FALSE;
if (fnIsWow64Process == NULL) {
fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(
GetModuleHandle(TEXT("kernel32")), TEXT("IsWow64Process"));
}
if (fnIsWow64Process != NULL) {
if (!fnIsWow64Process(processHandle, &bIsWow64)) {
return FALSE;
}
}
return bIsWow64;
}
BaseSystemInfo GetBaseSystemInfo(HANDLE processHandle)
{
if (IsWow64(processHandle) == FALSE) {
return SYSINFO_32PROCESS;
} else if (Isx64Architecture() == TRUE) {
return SYSINFO_64PROCESS;
} else {
return SYSINFO_32PROCESS_ON_WO64;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
switch (GetBaseSystemInfo(GetCurrentProcess())) {
case SYSINFO_32PROCESS_ON_WO64:
printf("WOW64");
break;
case SYSINFO_64PROCESS:
printf("x64");
break;
case SYSINFO_32PROCESS:
printf("x86");
break;
}
return 0;
}
投稿日時 : 2007年12月26日 22:39