IsWow64Process の 結果 | OS |
32bit | 64bit |
app. | 32bit | FALSE | TRUE |
64bit | 動作できない | FALSE |
64bit コードは 32bit OS では動かない。このことを利用して、32bit コードと 64bit コードでソースを分ければ、IsWow64Process だけで OS が x64 かどうかを判別できる。
でも、同じソースを2つ管理するのは嫌だ。何とか1つのソースで、32bit か 64bit か判別できないものだろうか?
問題は、FALSE になる、32bit app. on 32bit OS と、64bit app. on 64bit OS の違いを、どのように見分けるか。ここをクリアすれば、この問題は解決。
今度は _UNICODE 指定で 32bit でも 64bit でもビルド済み、実行済みのコード
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
typedef void (WINAPI *LPFN_GETNATIVESYSTEMINFO) (LPSYSTEM_INFO);
// Blog にコピったときに、これを関数に移動させたのがバグの原因
// ちゃっぴさん、ごめん。
LPFN_ISWOW64PROCESS fnIsWow64Process;
LPFN_GETNATIVESYSTEMINFO fnGetNativeSystemInfo;
BOOL IsWow64(HANDLE processHandle)
{
BOOL bIsWow64 = FALSE;
if (fnIsWow64Process == NULL) {
fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(
GetModuleHandle(TEXT("kernel32")), "IsWow64Process");
}
if (fnIsWow64Process != NULL) {
if (!fnIsWow64Process(processHandle, &bIsWow64)) {
return FALSE;
}
}
return bIsWow64;
}
BOOL Isx64Architecture(void)
{
BOOL bIsx64 = FALSE;
SYSTEM_INFO info;
if (fnGetNativeSystemInfo == NULL) {
fnGetNativeSystemInfo = (LPFN_GETNATIVESYSTEMINFO) GetProcAddress(
GetModuleHandle(TEXT("kernel32")), "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;
}
void PrintOSVersion(void)
{
OSVERSIONINFO verInfo;
verInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx(&verInfo) == FALSE) {
DWORD err = GetLastError();
(void) printf("Error %d.\n", err);
} else {
(void) printf("Version: %d.%d(Build.%d) Platform %d\n"
, verInfo.dwMajorVersion, verInfo.dwMinorVersion
, verInfo.dwBuildNumber, verInfo.dwPlatformId);
}
return;
}
int _tmain(int argc, _TCHAR* argv[])
{
BOOL bIsWow64 = IsWow64(GetCurrentProcess());
if (bIsWow64 == TRUE) {
(void) printf("32bit Application Running on WOW64.\n");
} else {
BOOL bIsx64 = Isx64Architecture();
if (bIsx64 == TRUE) {
(void) printf("64bit Application Running on 64bit Archtecture.\n");
} else {
(void) printf("32bit Application Running on 32bit Archtecture.\n");
}
}
PrintOSVersion();
return 0;
}
もっと簡単そうなのは、WMI。Win32_OperatingSystem クラス(英語)
OSArchitecture プロパティに、文字列で、"32-bit" とか、入っているらしい。文字列ですか。そうですか。。。
それに、なんですか?Windows Server 2003, Windows 2000, Windows NT 4.0, Windows XP, and Windows Me/98/95 には実装されていないのですか。ああ、そうですか。
ちなみに printf を使っているのは、コンソールが SHIFT_JIS でないと印字できないからです。。。
投稿日時 : 2007年12月31日 22:48