diff --git a/Common/ArmCPUDetect.cpp b/Common/ArmCPUDetect.cpp index 4a166793d8..59f5440c1b 100644 --- a/Common/ArmCPUDetect.cpp +++ b/Common/ArmCPUDetect.cpp @@ -23,6 +23,39 @@ #include "CPUDetect.h" #include "StringUtils.h" #include "FileUtil.h" +#include "util/text/utf8.h" + +#if PPSSPP_PLATFORM(WINDOWS) +#if PPSSPP_PLATFORM(UWP) +// TODO: Maybe we can move the implementation here? +std::string GetCPUBrandString(); +#else +// No CPUID on ARM, so we'll have to read the registry +#include +std::string GetCPUBrandString() { + std::string cpu_string; + + HKEY key; + LSTATUS result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, KEY_READ, &key); + if (result == ERROR_SUCCESS) { + DWORD size = 0; + DWORD type = REG_SZ; + RegQueryValueEx(key, L"ProcessorNameString", NULL, &type, NULL, &size); + LPBYTE buff = (LPBYTE)malloc(size); + if (buff != NULL) { + RegQueryValueEx(key, L"ProcessorNameString", NULL, &type, buff, &size); + cpu_string = ConvertWStringToUTF8((wchar_t*)buff); + free(buff); + } + } + + if (cpu_string.empty()) + return "Unknown"; + else + return cpu_string; +} +#endif +#endif // Only Linux platforms have /proc/cpuinfo #if PPSSPP_PLATFORM(LINUX) @@ -209,7 +242,7 @@ void CPUInfo::Detect() strcpy(brand_string, "Apple A"); num_cores = 2; #elif PPSSPP_PLATFORM(WINDOWS) - strcpy(brand_string, "Unknown"); + truncate_cpy(brand_string, GetCPUBrandString().c_str()); isVFP3 = true; isVFP4 = false; SYSTEM_INFO sysInfo; diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index b7271d5288..214566a0f6 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -36,6 +36,7 @@ using namespace Windows::Storage; using namespace Windows::Storage::Streams; using namespace Windows::System::Threading; using namespace Windows::ApplicationModel::DataTransfer; +using namespace Windows::Devices::Enumeration; using namespace Concurrency; // UGLY! @@ -465,6 +466,61 @@ bool System_InputBoxGetWString(const wchar_t *title, const std::wstring &default return false; } +std::string GetCPUBrandString() { + Platform::String^ cpu_id = nullptr; + Platform::String^ cpu_name = nullptr; + + // GUID_DEVICE_PROCESSOR: {97FADB10-4E33-40AE-359C-8BEF029DBDD0} + Platform::String^ if_filter = L"System.Devices.InterfaceClassGuid:=\"{97FADB10-4E33-40AE-359C-8BEF029DBDD0}\""; + + // Enumerate all CPU DeviceInterfaces, and get DeviceInstanceID of the first one. + auto if_task = create_task( + DeviceInformation::FindAllAsync(if_filter)).then([&](DeviceInformationCollection ^ collection) { + if (collection->Size > 0) { + auto cpu = collection->GetAt(0); + auto id = cpu->Properties->Lookup(L"System.Devices.DeviceInstanceID"); + cpu_id = dynamic_cast(id); + } + }); + + try { + if_task.wait(); + } + catch (const std::exception & e) { + const char* what = e.what(); + ILOG("%s", what); + } + + if (cpu_id != nullptr) { + // Get the Device with the same ID as the DeviceInterface + // Then get the name (description) of that Device + // We have to do this because the DeviceInterface we get doesn't have a proper description. + Platform::String^ dev_filter = L"System.Devices.DeviceInstanceID:=\"" + cpu_id + L"\""; + + auto dev_task = create_task( + DeviceInformation::FindAllAsync(dev_filter, {}, DeviceInformationKind::Device)).then( + [&](DeviceInformationCollection ^ collection) { + if (collection->Size > 0) { + cpu_name = collection->GetAt(0)->Name; + } + }); + + try { + dev_task.wait(); + } + catch (const std::exception & e) { + const char* what = e.what(); + ILOG("%s", what); + } + } + + if (cpu_name != nullptr) { + return FromPlatformString(cpu_name); + } else { + return "Unknown"; + } +} + // Emulation of TlsAlloc for Windows 10. Used by glslang. Doesn't actually seem to work, other than fixing the linking errors? extern "C" {