Files
soft/CristalDiskMark/source/CrystalDiskMark/Priscilla/SystemInfoFx.cpp
T

1888 lines
45 KiB
C++

/*---------------------------------------------------------------------------*/
// Author : hiyohiyo
// Mail : hiyohiyo@crystalmark.info
// Web : https://crystalmark.info/
// License : MIT License
/*---------------------------------------------------------------------------*/
#include "stdafx.h"
#include "OsInfoFx.h"
#include "SystemInfoFx.h"
#include "UtilityFx.h"
//------------------------------------------------
// Get System Information by WMI
//------------------------------------------------
//warning : enum3, enum class
#if _MSC_VER > 1310
#pragma warning(disable : 26812)
#endif
#include <comdef.h>
#include <comutil.h>
#include <wbemcli.h>
#pragma comment(lib, "oleaut32.lib")
#pragma comment(lib, "wbemuuid.lib")
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
#ifndef safeCloseHandle
#define safeCloseHandle(h) { if( h != NULL ) { ::CloseHandle(h); h = NULL; } }
#endif
#ifndef safeVirtualFree
#define safeVirtualFree(h,b,c) { if( h != NULL ) { ::VirtualFree(h, b, c); h = NULL; } }
#endif
#if _MSC_VER > 1310
DWORD CountSetBits(ULONG_PTR bitMask) {
DWORD LSHIFT = sizeof(ULONG_PTR) * 8 - 1;
DWORD bitSetCount = 0;
ULONG_PTR bitTest = (ULONG_PTR)1 << LSHIFT;
for (DWORD i = 0; i <= LSHIFT; ++i) {
bitSetCount += ((bitMask & bitTest) ? 1 : 0);
bitTest >>= 1;
}
return bitSetCount;
}
typedef ULONGLONG(WINAPI* FuncGetLogicalProcessorInformationEx)(LOGICAL_PROCESSOR_RELATIONSHIP, PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX, PDWORD);
typedef BOOL(WINAPI* FuncGetLogicalProcessorInformation)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD);
#endif
void GetProcessorInfo(int* cores, int* threads)
{
*cores = 0;
*threads = 0;
#if _MSC_VER > 1310
HMODULE hModule = GetModuleHandle(_T("kernel32.dll"));
FuncGetLogicalProcessorInformationEx pGetLogicalProcessorInformationEx = NULL;
FuncGetLogicalProcessorInformation pGetLogicalProcessorInformation = NULL;
if (hModule)
{
pGetLogicalProcessorInformationEx = (FuncGetLogicalProcessorInformationEx)GetProcAddress(hModule, "GetLogicalProcessorInformationEx");
pGetLogicalProcessorInformation = (FuncGetLogicalProcessorInformation)GetProcAddress(hModule, "GetLogicalProcessorInformation");
}
// for Windows 7 or later
if (pGetLogicalProcessorInformationEx != NULL)
{
DWORD length = 0;
pGetLogicalProcessorInformationEx(RelationAll, nullptr, &length);
BYTE* buffer = new BYTE[length];
if (pGetLogicalProcessorInformationEx(RelationAll, reinterpret_cast<PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX>(buffer), &length)) {
DWORD offset = 0;
while (offset < length) {
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX info = reinterpret_cast<PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX>(buffer + offset);
if (info->Relationship == RelationProcessorCore) {
*cores += 1;
for (int group = 0; group < info->Processor.GroupCount; ++group) {
*threads += CountSetBits(info->Processor.GroupMask[group].Mask);
}
}
offset += info->Size;
}
}
delete[] buffer;
}
// for Windows XP SP3/Vista
else if(pGetLogicalProcessorInformation != NULL)
{
DWORD length = 0;
pGetLogicalProcessorInformation(NULL, &length);
SYSTEM_LOGICAL_PROCESSOR_INFORMATION* buffer = new SYSTEM_LOGICAL_PROCESSOR_INFORMATION[length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION)];
pGetLogicalProcessorInformation(&buffer[0], &length);
for (DWORD i = 0; i != length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); ++i) {
if (buffer[i].Relationship == RelationProcessorCore) {
*cores += 1;
ULONG_PTR mask = buffer[i].ProcessorMask;
while (mask) {
if (mask & 1) {
*threads += 1;
}
mask >>= 1;
}
}
}
delete[] buffer;
}
else // - Windows XP SP2
{
SYSTEM_INFO si = { 0 };
GetSystemInfo(&si);
*cores = si.dwNumberOfProcessors;
*threads = si.dwNumberOfProcessors;
}
#else
SYSTEM_INFO si = {0};
GetSystemInfo(&si);
*cores = si.dwNumberOfProcessors;
*threads = si.dwNumberOfProcessors;
#endif
}
#if defined(_M_IX86) || defined(_M_X64)
void getProcessorBrandString(char* brandString);
void getCpuName(char* cpuName);
unsigned int getCacheInfoIntel(int test);
CStringA getCpuModelName(CStringA vendor, unsigned int family, unsigned int model, unsigned int stepping, unsigned int type, unsigned int L2Cashe, unsigned int fpu);
#if _MSC_VER > 1310
#include <intrin.h> // for __cpuid
void GetCpuid(unsigned int param, unsigned int* _eax, unsigned int* _ebx, unsigned int* _ecx, unsigned int* _edx)
{
int cpuInfo[4] = { 0 };
__cpuid(cpuInfo, param);
*_eax = cpuInfo[0];
*_ebx = cpuInfo[1];
*_ecx = cpuInfo[2];
*_edx = cpuInfo[3];
}
#else
BOOL IsCpuidSupported()
{
bool supported = false;
__asm {
pushfd
pop eax
mov ebx, eax
xor eax, 0x200000
push eax
popfd
pushfd
pop eax
xor eax, ebx
test eax, 0x200000
jz not_supported
mov supported, 1
not_supported:
push ebx
popfd
}
return supported;
}
void GetCpuid(unsigned int param, unsigned int* _eax, unsigned int* _ebx, unsigned int* _ecx, unsigned int* _edx)
{
static BOOL bIsCpuid = IsCpuidSupported();
if (!bIsCpuid) { return; }
unsigned int a, b, c, d;
__asm {
MOV EAX, param
CPUID
MOV a, EAX
MOV b, EBX
MOV c, ECX
MOV d, EDX
}
*_eax = a;
*_ebx = b;
*_ecx = c;
*_edx = d;
}
#endif
void getProcessorBrandString(char* brandString)
{
unsigned int eax = 0;
unsigned int ebx = 0;
unsigned int ecx = 0;
unsigned int edx = 0;
__try
{
// Check if CPUID supports brand string
GetCpuid(0x80000000, &eax, &ebx, &ecx, &edx);
if (eax < 0x80000004) {
strcpy(brandString, "");
return;
}
// Get brand string
for (int i = 0x80000002; i <= 0x80000004; ++i) {
GetCpuid(i, &eax, &ebx, &ecx, &edx);
memcpy(brandString + (i - 0x80000002) * 16, &eax, 4);
memcpy(brandString + (i - 0x80000002) * 16 + 4, &ebx, 4);
memcpy(brandString + (i - 0x80000002) * 16 + 8, &ecx, 4);
memcpy(brandString + (i - 0x80000002) * 16 + 12, &edx, 4);
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
strcpy(brandString, "");
}
}
void GetHypervisorVendorString(char* vendorString)
{
unsigned int eax = 0;
unsigned int ebx = 0;
unsigned int ecx = 0;
unsigned int edx = 0;
__try
{
GetCpuid(0x40000000, &eax, &ebx, &ecx, &edx);
memcpy(vendorString, &ebx, 4);
memcpy(vendorString + 4, &ecx, 4);
memcpy(vendorString + 8, &edx, 4);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
strcpy(vendorString, "");
}
}
#if _MSC_VER <= 1310
BOOL Is486orAbove();
BOOL IsCyrixCPU();
BOOL IsAmd486();
BOOL readCcr(BYTE addr, BYTE* value);
CStringA getCyrixModelName();
inline unsigned char inpb(unsigned short port)
{
unsigned char val;
__asm {
mov dx, port
in al, dx
mov val, al
}
return val;
}
inline void outpb(unsigned short port, unsigned char data)
{
__asm {
mov dx, port
mov al, data
out dx, al
}
}
// https://github.com/captainys/TOWNSEMU/issues/147#issuecomment-2764633838
BOOL IsFMTOWNS()
{
static BOOL b = -1;
if (b == -1)
{
b = FALSE;
if (IsPC98())
{
return FALSE;
}
if (! IsWin95First())
{
return FALSE;
}
if (GetUserDefaultLCID() != 0x0411) // Japanese
{
return FALSE;
}
__try
{
BYTE in30 = (BYTE)inpb(0x30);
BYTE in31 = (BYTE)inpb(0x31);
if (in30 && in30 != 0xFF && in31 && in31 != 0xFF)
{
b = TRUE;
return TRUE;
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return FALSE;
}
}
return b;
}
BOOL Is486orAbove()
{
BOOL result = FALSE;
__asm {
pushfd
pop eax
mov ecx, eax
xor eax, 0x40000
push eax
popfd
pushfd
pop eax
cmp eax, ecx
jz is_not_80486
mov result, 1
jmp end
is_not_80486 :
mov result, 0
end :
}
return result;
}
BOOL IsCyrixCPU()
{
BOOL result = FALSE;
__asm {
xor ax, ax
sahf
mov ax, 5
mov bx, 2
div bl
lahf
cmp ah, 2
jne not_cyrix
mov result, 1
jmp end
not_cyrix:
mov result, 0
end:
}
return result;
}
BOOL IsAmd486()
{
__try
{
outpb(0xC0, 0x55);
BYTE val = (BYTE)inpb(0xC0);
if (val == 0x55)
{
return TRUE;
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return FALSE;
}
return FALSE;
}
BOOL readCcr(BYTE addr, BYTE* value)
{
__try
{
outpb(0x22, addr);
*value = inpb(0x23);
return TRUE;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return FALSE;
}
}
// http://www.bitsavers.org/components/cyrix/appnotes/Cyrix_CPU_Detection_Guide_1997.pdf
CStringA getCyrixModelName()
{
BYTE dir0 = 0;
if(! readCcr(0xFE, &dir0))
{
return "Cyrix Unknown CPU";
}
if (0x00 <= dir0 && dir0 <= 0x1F) { return "Cyrix Cx486"; }
else if (0x20 <= dir0 && dir0 <= 0x2F) { return "Cyrix 5x86"; }
else if (0x30 <= dir0 && dir0 <= 0x3F) { return "Cyrix 6x86"; }
else if (0x40 <= dir0 && dir0 <= 0x4F) { return "Cyrix MediaGX"; }
else if (0x50 <= dir0 && dir0 <= 0x5F) { return "Cyrix 6x86MX/MII"; }
else
{
return "Cyrix Unknown CPU";
}
}
#endif
void getCpuName(char* cpuName)
{
unsigned int eax = 0;
unsigned int ebx = 0;
unsigned int ecx = 0;
unsigned int edx = 0;
unsigned int maxCpuId = 0;
#if _MSC_VER <= 1310
if(! IsCpuidSupported())
{
CStringA modelName = "";
if (! Is486orAbove())
{
modelName = "386 Generation Processor";
}
else if (IsFMTOWNS())
{
}
else if (IsCyrixCPU())
{
modelName = "Cyrix Unknown CPU";
if (IsWin9x() && !IsPC98() && !IsFMTOWNS()) // PC-98 and FM TOWNS are not supported.
{
modelName = getCyrixModelName();
}
}
else if (IsWin9x())
{
if (IsAmd486())
{
modelName = "AMD Am486/Am5x86";
}
}
if (modelName.IsEmpty())
{
SYSTEM_INFO si = { 0 };
GetSystemInfo(&si);
switch (si.dwProcessorType)
{
case PROCESSOR_INTEL_386:
modelName = "386 Generation Processor";
break;
case PROCESSOR_INTEL_486:
modelName = "486 Generation Processor";
break;
case PROCESSOR_INTEL_PENTIUM:
modelName = "586 Generation Processor";
break;
case PROCESSOR_ARCHITECTURE_UNKNOWN:
default:
modelName = "Unknown Processor";
break;
}
}
sprintf(cpuName, "%s", modelName.GetString());
return;
}
#endif
char vendorString[13] = {0};
GetCpuid(0x00, &eax, &ebx, &ecx, &edx);
memcpy(vendorString, &ebx, 4);
memcpy(vendorString + 4, &edx, 4);
memcpy(vendorString + 8, &ecx, 4);
GetCpuid(0x80000000, &eax, &ebx, &ecx, &edx);
maxCpuId = eax;
if (maxCpuId >= 0x80000004)
{
getProcessorBrandString(cpuName);
}
else
{
CStringA vendor = vendorString;
GetCpuid(0x1, &eax, &ebx, &ecx, &edx);
unsigned int version = eax;
unsigned int family = (version >> 8) & 0xF;
unsigned int model = (version >> 4) & 0xF;
unsigned int stepping = version & 0xF;
unsigned int type = (version >> 12) & 0x3;
unsigned int fpu = 1; // Under Construction
unsigned int cacheL2 = 0;
unsigned int temp = 0;
if (vendor.Find("GenuineIntel") == 0)
{
GetCpuid(0x2, &eax, &ebx, &ecx, &edx);
temp = getCacheInfoIntel((eax & 0xFF000000) >> 24); if (temp > 0) { cacheL2 = temp; }
temp = getCacheInfoIntel((eax & 0x00FF0000) >> 16); if (temp > 0) { cacheL2 = temp; }
temp = getCacheInfoIntel((eax & 0x0000FF00) >> 8); if (temp > 0) { cacheL2 = temp; }
temp = getCacheInfoIntel((eax & 0x000000FF) >> 0); if (temp > 0) { cacheL2 = temp; }
temp = getCacheInfoIntel((ebx & 0xFF000000) >> 24); if (temp > 0) { cacheL2 = temp; }
temp = getCacheInfoIntel((ebx & 0x00FF0000) >> 16); if (temp > 0) { cacheL2 = temp; }
temp = getCacheInfoIntel((ebx & 0x0000FF00) >> 8); if (temp > 0) { cacheL2 = temp; }
temp = getCacheInfoIntel((ebx & 0x000000FF) >> 0); if (temp > 0) { cacheL2 = temp; }
temp = getCacheInfoIntel((ecx & 0xFF000000) >> 24); if (temp > 0) { cacheL2 = temp; }
temp = getCacheInfoIntel((ecx & 0x00FF0000) >> 16); if (temp > 0) { cacheL2 = temp; }
temp = getCacheInfoIntel((ecx & 0x0000FF00) >> 8); if (temp > 0) { cacheL2 = temp; }
temp = getCacheInfoIntel((ecx & 0x000000FF) >> 0); if (temp > 0) { cacheL2 = temp; }
temp = getCacheInfoIntel((edx & 0xFF000000) >> 24); if (temp > 0) { cacheL2 = temp; }
temp = getCacheInfoIntel((edx & 0x00FF0000) >> 16); if (temp > 0) { cacheL2 = temp; }
temp = getCacheInfoIntel((edx & 0x0000FF00) >> 8); if (temp > 0) { cacheL2 = temp; }
temp = getCacheInfoIntel((edx & 0x000000FF) >> 0); if (temp > 0) { cacheL2 = temp; }
}
if(maxCpuId >= 0x80000006)
{
GetCpuid(0x80000006, &eax, &ebx, &ecx, &edx);
cacheL2 = ((ebx >> 12) & 0xF) * 256;
}
CStringA modelName = getCpuModelName(vendor, family, model, stepping, type, cacheL2, fpu);
sprintf(cpuName, "%s", modelName.GetString());
}
}
unsigned int getCacheInfoIntel(int test)
{
unsigned int CacheL2 = 0;
switch (test)
{
case 0x39:CacheL2 = 128;break;
case 0x3A:CacheL2 = 192;break;
case 0x3B:CacheL2 = 128;break;
case 0x3C:CacheL2 = 256;break;
case 0x3D:CacheL2 = 384;break;
case 0x3E:CacheL2 = 512;break;
case 0x41:CacheL2 = 128;break;
case 0x42:CacheL2 = 256;break;
case 0x43:CacheL2 = 512;break;
case 0x44:CacheL2 = 1024;break;
case 0x45:CacheL2 = 2048;break;
case 0x48:CacheL2 = 3072;break;
case 0x49:CacheL2 = 4096;break;
case 0x4E:CacheL2 = 6144;break;
case 0x78:CacheL2 = 1024;break;
case 0x79:CacheL2 = 128;break;
case 0x7A:CacheL2 = 256;break;
case 0x7B:CacheL2 = 512;break;
case 0x7C:CacheL2 = 1024;break;
case 0x7D:CacheL2 = 2048;break;
case 0x7E:CacheL2 = 256;break;
case 0x7F:CacheL2 = 512;break;
case 0x81:CacheL2 = 128;break;
case 0x82:CacheL2 = 256;break;
case 0x83:CacheL2 = 512;break;
case 0x84:CacheL2 = 1024;break;
case 0x85:CacheL2 = 2048;break;
case 0x86:CacheL2 = 512;break;
case 0x87:CacheL2 = 1024;break;
default:;
}
return CacheL2;
}
CStringA getCpuModelName(CStringA vendor, unsigned int family, unsigned int model, unsigned int stepping, unsigned int type, unsigned int cacheL2, unsigned int fpu)
{
CStringA modelName;
int F = family;
int M = model;
int S = stepping;
int CacheL2 = cacheL2;
char* n = NULL;
char* v = NULL;
if (vendor.Find("GenuineIntel") == 0)
{
v = "Intel";
switch (family)
{
case 0x06:
switch (model)
{
/////////////
// Cascades
/////////////
case 0xA:
n = "Pentium III Xeon";
break;
///////////
// Banias
///////////
case 9:
if (CacheL2 == 1024) {
n = "Pentium M";
} else {
n = "Celeron M";
}
break;
///////////////
// Coppermine
///////////////
case 8:
if (CacheL2 >= 256) {
n = "Pentium III";
} else if (CacheL2 <= 128) {
n = "Celeron";
}
break;
///////////
// Katmai
///////////
case 7:
if (CacheL2 == 1024) {
n = "Pentium III Xeon";
} else {
n = "Pentium III";
}
break;
//////////////////////
// Dixon & Mendocino
//////////////////////
case 6:
if ((S == 0xA || S == 0xD) && CacheL2 == 256) {
n = "Mobile Pentium II";
} else if ((S == 0xA || S == 0xD) && CacheL2 == 128) {
n = "Mobile Celeron";
} else {
n = "Celeron";
}
break;
//////////////
// Deschutes
//////////////
case 5:
if (CacheL2 > 512) {
n = "Pentium II Xeon";
} else if (CacheL2 == 512 && type == 0x1) {
n = "Pentium II OverDrive";
} else if (CacheL2 == 512) {
n = "Pentium II";
} else if (CacheL2 == 0) {
n = "Celeron";
}
break;
case 4:
n = "OverDrive";
break;
case 3:
if (type == 0x1) {
n = "Pentium II OverDrive";
} else {
n = "Pentium II";
}
break;
///////
// P6
///////
case 2:
n = "Pentium Pro";
break;
case 1:
n = "Pentium Pro";
break;
case 0:
n = "Pentium Pro";
break;
}
break;
////////////
// Pentium
////////////
case 5:
switch (model) {
case 8:
n = "Pentium MMX";
break;
case 7:
n = "Pentium";
break;
case 6:
n = "Pentium OverDrive";
break;
case 5:
n = "Pentium OverDrive";
break;
case 4:
if (type == 1) {
n = "Pentium MMX OverDrive";
} else {
n = "Pentium MMX";
}
break;
case 3:
n = "Pentium OverDrive";
break;
case 2:
if (type == 1) {
n = "Pentium OverDrive";
} else {
n = "Pentium";
}
break;
case 1:
case 0:
if (type == 1) {
n = "Pentium OverDrive";
} else {
n = "Pentium";
}
break;
default:
n = "Pentium";
break;
}
break;
////////
// 486
////////
case 4:
switch (model) {
case 9:
n = "486DX4 WB";
break;
case 8:
n = "486DX4";
break;
case 7:
n = "486DX2 WB";
break;
case 5:
n = "486SX2";
break;
case 4:
n = "486SL";
break;
case 3:
n = "486DX2";
break;
case 2:
n = "486SX";
break;
case 1:
case 0:
n = "486DX";
break;
default:
n = "486";
break;
}
break;
case 3:
n = "386";
break;
default:
n = "Unknown CPU";
break;
}
}
else if (vendor.Find("AuthenticAMD") == 0)
{
v = "AMD";
switch (family)
{
case 5:
switch (model) {
case 0xD:
case 0xC:
if (CacheL2 == 256) {
n = "K6-III+";
} else {
n = "K6-2+";
}
break;
case 0xA:
n = "Geode LX";
break;
case 9:
n = "K6-III";
break;
case 8:
n = "K6-2";
break;
case 7:
n = "K6";
break;
case 3:
case 2:
case 1:
case 0:
n = "K5";
break;
default:
n = "Unknown CPU";
break;
}
break;
case 4:
switch (model) {
case 0xF:
case 0xE:
n = "Am5x86";
break;
case 9:
case 8:
n = "Am486DX4/Am5x86";
break;
case 7:
case 3:
if (fpu)
{
n = "Am486DX2";
}
else
{
n = "Am486SX2";
}
break;
default:
n = "Unknown CPU";
break;
}
break;
default:
n = "Unknown CPU";
break;
}
}
else if (vendor.Find("CentaurHauls") == 0 || vendor.Find("VIA VIA VIA") == 0)
{
v = "";
switch (family)
{
case 6:
switch (model)
{
case 0xF:
n = "VIA Nano";
break;
case 0xD:
case 0xC:
case 0xB:
case 0xA:
n = "VIA C7";
break;
case 9:
case 8:
case 7:
n = "VIA C3";
break;
case 6:
n = "VIA Cyrix III";
break;
case 5:
if (stepping == 0)
{
n = "VIA 6x86MX";
}
else
{
n = "VIA Cyrix III";
}
break;
case 4:
n = "VIA Cyrix III";
break;
case 3:
n = "VIA 6x86MX";
break;
case 2:
n = "VIA Cyrix III";
break;
case 0:
n = "VIA 6x86MX";
break;
default:
n = "VIA Unknown CPU";
break;
}
break;
case 5:
switch (model)
{
case 9:
n = "IDT WinChip 3";
break;
case 8:
n = "IDT WinChip 2";
break;
case 4:
n = "IDT WinChip C6";
break;
default:
n = "VIA Unknown CPU";
break;
}
break;
default:
n = "VIA Unknown CPU";
break;
}
}
else if (vendor.Find("CyrixInstead") == 0)
{
v = "Cyrix";
switch (family)
{
case 6:
switch (model)
{
case 0:
n = "MII";
break;
default:
n = "Unknown CPU";
break;
}
break;
case 5:
switch (model)
{
case 9:
n = "Geode";
break;
case 4:
n = "MediaGX";
break;
case 2:
n = "6x86";
break;
default:
n = "Unknown CPU";
break;
}
break;
case 4:
switch (model)
{
case 4:
n = "MediaGX";
break;
default:
n = "Unknown CPU";
break;
}
break;
default:
n = "Unknown CPU";
break;
}
}
else if (vendor.Find("SiS SiS SiS") == 0)
{
v = "SiS";
n = "55x";
}
else if (vendor.Find("Geode by NSC") == 0)
{
v = "NSC";
n = "Geode";
}
else if (vendor.Find("NexGenDriven") == 0)
{
v = "NexGen";
n = "Nx586";
}
else if (vendor.Find("RiseRiseRise") == 0)
{
v = "Rise";
n = "mP6";
}
else if (vendor.Find("UMC UMC UMC") == 0)
{
v = "UMC";
n = "Green CPU";
}
else
{
v = NULL;
n = NULL;
}
if (v != NULL && n != NULL)
{
modelName.Format("%s %s", v, n);
return modelName;
}
else
{
return "";
}
}
#endif
void GetCpuInfo(CString& cpuInfo, CString& cpuName, int* clock, int* cores, int* threads)
{
CString query = _T("Select * from Win32_Processor");
IWbemLocator* pIWbemLocator = NULL;
IWbemServices* pIWbemServices = NULL;
IEnumWbemClassObject* pEnumCOMDevs = NULL;
IWbemClassObject* pCOMDev = NULL;
ULONG uReturned = 0;
BOOL flag = FALSE;
try
{
if (SUCCEEDED(CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID*)&pIWbemLocator)))
{
long securityFlag = 0;
#if _MSC_VER > 1310
if (IsWindowsVersionOrGreaterFx(6, 0)) { securityFlag = WBEM_FLAG_CONNECT_USE_MAX_WAIT; }
#endif
if (SUCCEEDED(pIWbemLocator->ConnectServer(_bstr_t(_T("root\\cimv2")),
NULL, NULL, 0L, securityFlag, NULL, NULL, &pIWbemServices)))
{
#if _MSC_VER > 1310
if (SUCCEEDED(CoSetProxyBlanket(pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE,
NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE)))
#endif
{
if (SUCCEEDED(pIWbemServices->ExecQuery(_bstr_t(_T("WQL")),
_bstr_t(query), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumCOMDevs)))
{
while (pEnumCOMDevs && SUCCEEDED(pEnumCOMDevs->Next(10000, 1, &pCOMDev, &uReturned)) && uReturned == 1)
{
CString name;
UINT32 speed = 0;
// UINT32 cores = 0;
// UINT32 threads = 0;
#if defined(_M_IX86) || defined(_M_X64)
char brandString[49] = { 0 };
getCpuName(brandString);
//getProcessorBrandString(brandString);
name = brandString;
name.TrimLeft();
name.TrimRight();
cpuName = name;
#endif
VARIANT pVal;
VariantInit(&pVal);
if (name.IsEmpty() && pCOMDev->Get(L"Name", 0L, &pVal, NULL, NULL) == WBEM_S_NO_ERROR && pVal.vt > VT_NULL)
{
name = pVal.bstrVal;
name.TrimLeft();
name.TrimRight();
cpuName = name;
VariantClear(&pVal);
}
if (pCOMDev->Get(L"MaxClockSpeed", 0L, &pVal, NULL, NULL) == WBEM_S_NO_ERROR && pVal.vt > VT_NULL)
{
speed = pVal.intVal;
if(clock != NULL) { *clock = (int)speed; }
VariantClear(&pVal);
}
/*
if (pCOMDev->Get(L"NumberOfCores", 0L, &pVal, NULL, NULL) == WBEM_S_NO_ERROR && pVal.vt > VT_NULL)
{
*cores = pVal.intVal;
VariantClear(&pVal);
}
if (pCOMDev->Get(L"NumberOfLogicalProcessors", 0L, &pVal, NULL, NULL) == WBEM_S_NO_ERROR && pVal.vt > VT_NULL)
{
*threads = pVal.intVal;
VariantClear(&pVal);
}
*/
GetProcessorInfo(cores, threads);
if (speed > 0 && *cores > 0 && *threads > 0)
{
if (*cores > 1 && *threads > 1)
{
cpuInfo.Format(_T("%s %dMHz (%dcores/%dthreads)"), (LPCTSTR)name, speed, *cores, *threads);
}
else if (*cores == 1 && *threads == 1)
{
cpuInfo.Format(_T("%s %dMHz (%dcore/%dthread)"), (LPCTSTR)name, speed, *cores, *threads);
}
else if (*cores == 1)
{
cpuInfo.Format(_T("%s %dMHz (%dcore/%dthreads)"), (LPCTSTR)name, speed, *cores, *threads);
}
}
else if (*cores > 0 && *threads > 0)
{
if (*cores > 1 && *threads > 1)
{
cpuInfo.Format(_T("%s (%dcores/%dthreads)"), (LPCTSTR)name, *cores, *threads);
}
else if (*cores == 1 && *threads == 1)
{
cpuInfo.Format(_T("%s (%dcore/%dthread)"), (LPCTSTR)name, *cores, *threads);
}
else if (*cores == 1)
{
cpuInfo.Format(_T("%s (%dcore/%dthreads)"), (LPCTSTR)name, *cores, *threads);
}
}
else
{
cpuInfo = name;
}
break;
}
}
}
}
}
}
catch (...)
{
}
SAFE_RELEASE(pCOMDev);
SAFE_RELEASE(pEnumCOMDevs);
SAFE_RELEASE(pIWbemServices);
SAFE_RELEASE(pIWbemLocator);
if (cpuInfo.IsEmpty())
{
TCHAR str[256] = {};
DWORD value = 0;
DWORD type = REG_SZ;
ULONG size = 256 * sizeof(TCHAR);
HKEY hKey = NULL;
#if defined(_M_IX86) || defined(_M_X64)
char brandString[49] = { 0 };
getCpuName(brandString);
//getProcessorBrandString(brandString);
cpuInfo = brandString;
cpuInfo.TrimLeft();
cpuInfo.TrimRight();
#endif
if (cpuInfo.IsEmpty() && !IsWin9x())
{
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"), 0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
if (RegQueryValueEx(hKey, _T("ProcessorNameString"), NULL, &type, (LPBYTE)str, &size) == ERROR_SUCCESS)
{
cpuInfo = str;
cpuInfo.TrimLeft();
cpuInfo.TrimRight();
}
}
}
#ifdef _M_IX86
#endif
cpuName = cpuInfo;
if (!IsWin9x())
{
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"), 0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
type = REG_DWORD;
size = sizeof(DWORD);
if (RegQueryValueEx(hKey, _T("~MHz"), NULL, &type, (LPBYTE)&value, &size) == ERROR_SUCCESS)
{
cpuInfo.Format(_T("%s %dMHz"), (LPCTSTR)cpuInfo, value);
if (clock != NULL) { *clock = (int)value; }
}
RegCloseKey(hKey);
}
}
GetProcessorInfo(cores, threads);
if (*cores > 0 && *threads > 0)
{
CString cstr;
if (*cores > 1 && *threads > 1)
{
cstr.Format(_T(" (%dcores/%dthreads)"), *cores, *threads);
}
else if(*cores == 1 && *threads == 1)
{
cstr.Format(_T(" (%dcore/%dthread)"), *cores, *threads);
}
else if (*cores == 1)
{
cstr.Format(_T(" (%dcore/%dthreads)"), *cores, *threads);
}
cpuInfo += cstr;
}
}
cpuName.Replace(_T("(R)"), _T(""));
cpuName.Replace(_T("(r)"), _T(""));
cpuName.Replace(_T("(TM)"), _T(""));
cpuName.Replace(_T("(tm)"), _T(""));
cpuInfo.Replace(_T("(R)"), _T(""));
cpuInfo.Replace(_T("(TM)"), _T(""));
cpuInfo.Replace(_T("(t)"), _T(""));
cpuInfo.Replace(_T("(tm)"), _T(""));
}
void GetGpuInfo(CString& gpuInfo)
{
#if _MSC_VER > 1310
#pragma comment(lib, "dxgi.lib")
HMODULE hModule = LoadLibraryEx(_T("dxgi.dll"), NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
typedef HRESULT(WINAPI* FuncCreateDXGIFactory)(REFIID, void**);
FuncCreateDXGIFactory pCreateDXGIFactory = NULL;
if (hModule != NULL)
{
pCreateDXGIFactory = (FuncCreateDXGIFactory)GetProcAddress(hModule, "CreateDXGIFactory");
}
if (pCreateDXGIFactory != NULL)
{
IDXGIFactory* pFactory = nullptr;
if (SUCCEEDED(pCreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&pFactory)))
{
IDXGIAdapter* pAdapter = nullptr;
DXGI_ADAPTER_DESC adapterDesc;
for (UINT i = 0; pFactory->EnumAdapters(i, &pAdapter) != DXGI_ERROR_NOT_FOUND; ++i)
{
pAdapter->GetDesc(&adapterDesc);
CString cstr;
cstr.Format(L"%s [%dMB]", adapterDesc.Description, (int)(adapterDesc.DedicatedVideoMemory / (1024 * 1024)));
if (cstr.Find(L"Microsoft Basic Render Driver") == 0)
{
pAdapter->Release();
continue;
}
if (gpuInfo.IsEmpty())
{
gpuInfo = cstr;
}
else if (gpuInfo.Find(cstr) >= 0)
{
// Duplication
}
else
{
gpuInfo += _T(" | ") + cstr;
}
pAdapter->Release();
}
pFactory->Release();
}
}
if (! gpuInfo.IsEmpty())
{
gpuInfo.Replace(_T("(R)"), _T(""));
gpuInfo.Replace(_T("(TM)"), _T(""));
return;
}
#endif
CString query = _T("Select * from Win32_VideoController");
IWbemLocator* pIWbemLocator = NULL;
IWbemServices* pIWbemServices = NULL;
IEnumWbemClassObject* pEnumCOMDevs = NULL;
IWbemClassObject* pCOMDev = NULL;
ULONG uReturned = 0;
BOOL flag = FALSE;
try
{
if (SUCCEEDED(CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID*)&pIWbemLocator)))
{
long securityFlag = 0;
#if _MSC_VER > 1310
if (IsWindowsVersionOrGreaterFx(6, 0)) { securityFlag = WBEM_FLAG_CONNECT_USE_MAX_WAIT; }
#endif
if (SUCCEEDED(pIWbemLocator->ConnectServer(_bstr_t(_T("root\\cimv2")),
NULL, NULL, 0L, securityFlag, NULL, NULL, &pIWbemServices)))
{
#if _MSC_VER > 1310
if (SUCCEEDED(CoSetProxyBlanket(pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE,
NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE)))
#endif
{
if (SUCCEEDED(pIWbemServices->ExecQuery(_bstr_t(_T("WQL")),
_bstr_t(query), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumCOMDevs)))
{
while (pEnumCOMDevs && SUCCEEDED(pEnumCOMDevs->Next(10000, 1, &pCOMDev, &uReturned)) && uReturned == 1)
{
CString name;
VARIANT pVal;
VariantInit(&pVal);
if (pCOMDev->Get(L"Name", 0L, &pVal, NULL, NULL) == WBEM_S_NO_ERROR && pVal.vt > VT_NULL)
{
name = pVal.bstrVal;
name.TrimLeft();
name.TrimRight();
VariantClear(&pVal);
}
// exclusion
// if (name.Find(_T("Virtual")) >= 0 || name.Find(_T("Remote")) >= 0 || name.Find(_T("ASPEED")) == 0)
if (gpuInfo.IsEmpty())
{
gpuInfo = name;
}
else
{
gpuInfo += _T(" | ") + name;
}
}
}
}
}
}
}
catch (...)
{
}
SAFE_RELEASE(pCOMDev);
SAFE_RELEASE(pEnumCOMDevs);
SAFE_RELEASE(pIWbemServices);
SAFE_RELEASE(pIWbemLocator);
#ifndef UNICODE
if (IsWin9x())
{
TCHAR str[256] = { 0 };
GetPrivateProfileStringFx(_T("boot.description"), _T("display.drv"), _T(""), str, 256, _T("system.ini"));
gpuInfo = str;
}
#endif
if (gpuInfo.IsEmpty())
{
TCHAR str[256] = {};
DWORD value = 0;
DWORD type = REG_SZ;
ULONG size = 256 * sizeof(TCHAR);
HKEY hKey = NULL;
// GPU
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Control\\Class\\{4d36e968-e325-11ce-bfc1-08002be10318}\\0000"), 0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
type = REG_SZ;
size = 256 * sizeof(TCHAR);
if (RegQueryValueEx(hKey, _T("DriverDesc"), NULL, &type, (LPBYTE)str, &size) == ERROR_SUCCESS)
{
gpuInfo = str;
gpuInfo.TrimLeft();
gpuInfo.TrimRight();
}
RegCloseKey(hKey);
}
if (gpuInfo.IsEmpty())
{
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Control\\Class\\{4d36e968-e325-11ce-bfc1-08002be10318}\\0001"), 0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
type = REG_SZ;
size = 256 * sizeof(TCHAR);
if (RegQueryValueEx(hKey, _T("DriverDesc"), NULL, &type, (LPBYTE)str, &size) == ERROR_SUCCESS)
{
gpuInfo = str;
gpuInfo.TrimLeft();
gpuInfo.TrimRight();
}
RegCloseKey(hKey);
}
}
if (gpuInfo.IsEmpty())
{
TCHAR str[256] = {};
DWORD value = 0;
DWORD type = REG_SZ;
ULONG size = 256 * sizeof(TCHAR);
HKEY hKey = NULL;
HKEY hKey2 = NULL;
type = REG_SZ;
size = 256 * sizeof(TCHAR);
CString videoKey, key;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DEVICEMAP\\VIDEO"), 0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
for (int i = 0; i < 10; i++)
{
videoKey.Format(_T("\\Device\\Video%d"), i);
key = _T("");
if (RegQueryValueEx(hKey, videoKey, NULL, &type, (LPBYTE)str, &size) == ERROR_SUCCESS)
{
key = str;
}
if (!key.IsEmpty())
{
key.MakeLower().Replace(_T("\\registry\\machine\\"), _T(""));
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hKey2) == ERROR_SUCCESS)
{
type = REG_SZ;
size = 256 * sizeof(TCHAR);
if (RegQueryValueEx(hKey2, _T("DriverDesc"), NULL, &type, (LPBYTE)str, &size) == ERROR_SUCCESS)
{
CString cstr = str;
cstr.TrimLeft();
cstr.TrimRight();
if (gpuInfo.IsEmpty())
{
gpuInfo = cstr;
}
else
{
gpuInfo += _T(" | ") + cstr;
}
RegCloseKey(hKey2);
break;
}
type = REG_BINARY;
if (RegQueryValueEx(hKey2, _T("HardwareInformation.AdapterString"), NULL, &type, (LPBYTE)str, &size) == ERROR_SUCCESS)
{
#ifndef UNICODE
char buf[256] = {};
WideCharToMultiByte(CP_ACP, 0, (WCHAR*)str, size, buf, 256, 0, 0);
CString cstr = buf;
#else
CString cstr = str;
#endif
cstr.TrimLeft();
cstr.TrimRight();
if (gpuInfo.IsEmpty())
{
gpuInfo = cstr;
}
else
{
gpuInfo += _T(" | ") + cstr;
}
RegCloseKey(hKey2);
break;
}
else
{
_tcscpy(str, key);
#if _MSC_VER > 1310
PathRemoveFileSpec(str);
CString cstr = PathFindFileName(str);
#else
PathRemoveFileSpecFx(str);
CString cstr = PathFindFileNameFx(str);
#endif
cstr += _T(" compatible device");
if (gpuInfo.IsEmpty())
{
gpuInfo = cstr;
}
else
{
gpuInfo += _T(" | ") + cstr;
}
RegCloseKey(hKey2);
break;
}
}
}
}
RegCloseKey(hKey);
}
}
}
gpuInfo.Replace(_T("(R)"), _T(""));
gpuInfo.Replace(_T("(TM)"), _T(""));
}
void GetBaseBoardInfo(CString& baseBoardInfo)
{
CString query = _T("Select * from Win32_BaseBoard");
IWbemLocator* pIWbemLocator = NULL;
IWbemServices* pIWbemServices = NULL;
IEnumWbemClassObject* pEnumCOMDevs = NULL;
IWbemClassObject* pCOMDev = NULL;
ULONG uReturned = 0;
BOOL flag = FALSE;
try
{
if (SUCCEEDED(CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID*)&pIWbemLocator)))
{
long securityFlag = 0;
#if _MSC_VER > 1310
if (IsWindowsVersionOrGreaterFx(6, 0)) { securityFlag = WBEM_FLAG_CONNECT_USE_MAX_WAIT; }
#endif
if (SUCCEEDED(pIWbemLocator->ConnectServer(_bstr_t(_T("root\\cimv2")),
NULL, NULL, 0L, securityFlag, NULL, NULL, &pIWbemServices)))
{
#if _MSC_VER > 1310
if (SUCCEEDED(CoSetProxyBlanket(pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE,
NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE)))
#endif
{
if (SUCCEEDED(pIWbemServices->ExecQuery(_bstr_t(_T("WQL")),
_bstr_t(query), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumCOMDevs)))
{
while (pEnumCOMDevs && SUCCEEDED(pEnumCOMDevs->Next(10000, 1, &pCOMDev, &uReturned)) && uReturned == 1)
{
CString manufacturer;
CString product;
VARIANT pVal;
VariantInit(&pVal);
if (pCOMDev->Get(L"Manufacturer", 0L, &pVal, NULL, NULL) == WBEM_S_NO_ERROR && pVal.vt > VT_NULL)
{
manufacturer = pVal.bstrVal;
manufacturer.TrimLeft();
manufacturer.TrimRight();
VariantClear(&pVal);
}
if (pCOMDev->Get(L"Product", 0L, &pVal, NULL, NULL) == WBEM_S_NO_ERROR && pVal.vt > VT_NULL)
{
product = pVal.bstrVal;
product.TrimLeft();
product.TrimRight();
VariantClear(&pVal);
}
baseBoardInfo = manufacturer + _T(" ") + product;
baseBoardInfo.Replace(_T("To Be Filled By O.E.M."), _T(""));
baseBoardInfo.Replace(_T("To be filled by O.E.M."), _T(""));
baseBoardInfo.Replace(_T("Not Available"), _T(""));
baseBoardInfo.TrimLeft();
baseBoardInfo.TrimRight();
}
}
}
}
}
}
catch (...)
{
}
SAFE_RELEASE(pCOMDev);
SAFE_RELEASE(pEnumCOMDevs);
SAFE_RELEASE(pIWbemServices);
SAFE_RELEASE(pIWbemLocator);
if (baseBoardInfo.IsEmpty())
{
TCHAR str[256] = {};
DWORD value = 0;
DWORD type = REG_SZ;
ULONG size = 256 * sizeof(TCHAR);
HKEY hKey = NULL;
// BaseBoard/System
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DESCRIPTION\\System\\BIOS"), 0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
size = 256 * sizeof(TCHAR);
if (RegQueryValueEx(hKey, _T("BaseBoardManufacturer"), NULL, &type, (LPBYTE)str, &size) == ERROR_SUCCESS)
{
baseBoardInfo = str;
}
size = 256 * sizeof(TCHAR);
if (RegQueryValueEx(hKey, _T("BaseBoardProduct"), NULL, &type, (LPBYTE)str, &size) == ERROR_SUCCESS)
{
baseBoardInfo += _T(" ");
baseBoardInfo += str;
}
baseBoardInfo.Replace(_T("To Be Filled By O.E.M."), _T(""));
baseBoardInfo.Replace(_T("To be filled by O.E.M."), _T(""));
baseBoardInfo.Replace(_T("Not Available"), _T(""));
baseBoardInfo.TrimLeft();
baseBoardInfo.TrimRight();
RegCloseKey(hKey);
}
}
}
void GetComputerSystemInfo(CString& computerSystemInfo)
{
CString query = _T("Select * from Win32_ComputerSystem");
IWbemLocator* pIWbemLocator = NULL;
IWbemServices* pIWbemServices = NULL;
IEnumWbemClassObject* pEnumCOMDevs = NULL;
IWbemClassObject* pCOMDev = NULL;
ULONG uReturned = 0;
BOOL flag = FALSE;
try
{
if (SUCCEEDED(CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID*)&pIWbemLocator)))
{
long securityFlag = 0;
#if _MSC_VER > 1310
if (IsWindowsVersionOrGreaterFx(6, 0)) { securityFlag = WBEM_FLAG_CONNECT_USE_MAX_WAIT; }
#endif
if (SUCCEEDED(pIWbemLocator->ConnectServer(_bstr_t(_T("root\\cimv2")),
NULL, NULL, 0L, securityFlag, NULL, NULL, &pIWbemServices)))
{
#if _MSC_VER > 1310
if (SUCCEEDED(CoSetProxyBlanket(pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE,
NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE)))
#endif
{
if (SUCCEEDED(pIWbemServices->ExecQuery(_bstr_t(_T("WQL")),
_bstr_t(query), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumCOMDevs)))
{
while (pEnumCOMDevs && SUCCEEDED(pEnumCOMDevs->Next(10000, 1, &pCOMDev, &uReturned)) && uReturned == 1)
{
CString manufacturer;
CString model;
VARIANT pVal;
VariantInit(&pVal);
if (pCOMDev->Get(L"Manufacturer", 0L, &pVal, NULL, NULL) == WBEM_S_NO_ERROR && pVal.vt > VT_NULL)
{
manufacturer = pVal.bstrVal;
manufacturer.TrimLeft();
manufacturer.TrimRight();
VariantClear(&pVal);
}
if (pCOMDev->Get(L"Model", 0L, &pVal, NULL, NULL) == WBEM_S_NO_ERROR && pVal.vt > VT_NULL)
{
model = pVal.bstrVal;
model.TrimLeft();
model.TrimRight();
VariantClear(&pVal);
}
computerSystemInfo = manufacturer + _T(" ") + model;
computerSystemInfo.Replace(_T("To Be Filled By O.E.M."), _T(""));
computerSystemInfo.Replace(_T("To be filled by O.E.M."), _T(""));
computerSystemInfo.Replace(_T("System manufacturer"), _T(""));
computerSystemInfo.Replace(_T("System Product Name"), _T(""));
computerSystemInfo.Replace(_T("Not Available"), _T(""));
computerSystemInfo.TrimLeft();
computerSystemInfo.TrimRight();
}
}
}
}
}
}
catch (...)
{
}
SAFE_RELEASE(pCOMDev);
SAFE_RELEASE(pEnumCOMDevs);
SAFE_RELEASE(pIWbemServices);
SAFE_RELEASE(pIWbemLocator);
if (computerSystemInfo.IsEmpty())
{
TCHAR str[256] = {};
DWORD value = 0;
DWORD type = REG_SZ;
ULONG size = 256 * sizeof(TCHAR);
HKEY hKey = NULL;
// BaseBoard/System
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DESCRIPTION\\System\\BIOS"), 0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
size = 256 * sizeof(TCHAR);
if (RegQueryValueEx(hKey, _T("SystemManufacturer"), NULL, &type, (LPBYTE)str, &size) == ERROR_SUCCESS)
{
computerSystemInfo = str;
}
size = 256 * sizeof(TCHAR);
if (RegQueryValueEx(hKey, _T("SystemProductName"), NULL, &type, (LPBYTE)str, &size) == ERROR_SUCCESS)
{
computerSystemInfo += _T(" ");
computerSystemInfo += str;
}
computerSystemInfo.Replace(_T("To Be Filled By O.E.M."), _T(""));
computerSystemInfo.Replace(_T("To be filled by O.E.M."), _T(""));
computerSystemInfo.Replace(_T("Not Available"), _T(""));
computerSystemInfo.Replace(_T("System Product Name"), _T(""));
computerSystemInfo.Replace(_T("System manufacturer"), _T(""));
computerSystemInfo.TrimLeft();
computerSystemInfo.TrimRight();
RegCloseKey(hKey);
}
}
#if _MSC_VER <= 1310
if (IsPC98())
{
computerSystemInfo = _T("[PC-98] ") + computerSystemInfo;
}
else if (IsFMTOWNS())
{
computerSystemInfo = _T("[FM TOWNS] ") + computerSystemInfo;
}
#endif
}
void GetScreenInfo(CString& screenInfo, int* width, int* height, int* color, CString& smoothing)
{
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
int screenHeight = GetSystemMetrics(SM_CYSCREEN);
if(width != NULL){*width = screenWidth;}
if(height != NULL){*height = screenHeight;}
HDC hDC = ::GetDC(NULL);
int bitsPerPixel = ::GetDeviceCaps(hDC, BITSPIXEL);
int planes = ::GetDeviceCaps(hDC, PLANES);
int colorDepth = bitsPerPixel * planes;
if(color != NULL){*color = colorDepth;}
::ReleaseDC(NULL, hDC);
DWORD fontSmoothingType = 0;
SystemParametersInfoW(SPI_GETFONTSMOOTHINGTYPE, 0, &fontSmoothingType, 0);
screenInfo.Format(_T("%dx%d %dbit"), screenWidth, screenHeight, colorDepth);
if (fontSmoothingType == FE_FONTSMOOTHINGSTANDARD)
{
screenInfo += _T(" (Smoothing)");
smoothing = _T("Smoothing");
}
else if (fontSmoothingType == FE_FONTSMOOTHINGCLEARTYPE)
{
screenInfo += _T(" (ClearType)");
smoothing = _T("ClearType");
}
}
void GetMemoryInfo(CString& memoryInfo, int* size)
{
#if _MSC_VER > 1310
MEMORYSTATUSEX memory = {};
memory.dwLength = sizeof(memory);
GlobalMemoryStatusEx(&memory);
if ((int)(memory.ullTotalPhys / 1024 / 1024 / 1024 + 1) > 1)
{
memoryInfo.Format(_T("%.1fGB"), (memory.ullTotalPhys / 1024.0 / 1024 / 1024));
}
else
{
memoryInfo.Format(_T("%dMB"), (int)(memory.ullTotalPhys / 1024.0 / 1024 + 1));
}
if(size != NULL){*size = (int)(memory.ullTotalPhys / 1024.0 / 1024 + 1);}
#else
// for Windows 2000
typedef BOOL(WINAPI* FuncGlobalMemoryStatusEx)(LPMEMORYSTATUSEX);
HMODULE hModule = GetModuleHandle(_T("kernel32.dll"));
FuncGlobalMemoryStatusEx pGlobalMemoryStatusEx = NULL;
if (hModule)
{
pGlobalMemoryStatusEx = (FuncGlobalMemoryStatusEx)GetProcAddress(hModule, "GlobalMemoryStatusEx");
}
if (pGlobalMemoryStatusEx != NULL) // for Windows 2000
{
MEMORYSTATUSEX memory;
memory.dwLength = sizeof(memory);
pGlobalMemoryStatusEx(&memory);
if ((int)(memory.ullTotalPhys / 1024 / 1024 / 1024 + 1) > 1)
{
memoryInfo.Format(_T("%.1fGB"), (memory.ullTotalPhys / 1024.0 / 1024 / 1024));
}
else
{
memoryInfo.Format(_T("%dMB"), (int)(memory.ullTotalPhys / 1024.0 / 1024 + 1));
}
if (size != NULL) { *size = (int)(memory.ullTotalPhys / 1024.0 / 1024 + 1); }
}
else
{
MEMORYSTATUS memory;
memory.dwLength = sizeof(memory);
GlobalMemoryStatus(&memory);
if ((int)(memory.dwTotalPhys / 1024 / 1024 / 1024 + 1) > 1)
{
memoryInfo.Format(_T("%.1fGB"), (memory.dwTotalPhys / 1024.0 / 1024 / 1024));
}
else
{
memoryInfo.Format(_T("%dMB"), (int)(memory.dwTotalPhys / 1024.0 / 1024 + 1));
}
if (size != NULL) { *size = (int)(memory.dwTotalPhys / 1024.0 / 1024 + 1); }
}
#endif
}
#if _MSC_VER <= 1310
/// https://www.betaarchive.com/wiki/index.php/Microsoft_KB_Archive/124207
BOOL IsCoProcessorPresent()
{
#define MY_ERROR_WRONG_OS 0x20000000
HKEY hKey;
SYSTEM_INFO SystemInfo;
// return FALSE if we are not running under Windows NT
// this should be expanded to cover alternative Win32 platforms
if (!(GetVersion() & 0x7FFFFFFF))
{
SetLastError(MY_ERROR_WRONG_OS);
return(FALSE);
}
// we return TRUE if we're not running on x86
// other CPUs have built in floating-point, with no registry entry
GetSystemInfo(&SystemInfo);
if ((SystemInfo.dwProcessorType != PROCESSOR_INTEL_386) &&
(SystemInfo.dwProcessorType != PROCESSOR_INTEL_486) &&
(SystemInfo.dwProcessorType != PROCESSOR_INTEL_PENTIUM))
{
return(TRUE);
}
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DESCRIPTION\\System\\FloatingPointProcessor"),
0, KEY_EXECUTE, &hKey) != ERROR_SUCCESS)
{
// GetLastError() will indicate ERROR_RESOURCE_DATA_NOT_FOUND
// if we can't find the key. This indicates no coprocessor present
return(FALSE);
}
RegCloseKey(hKey);
return(TRUE);
}
#endif