123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- #include "system-info.hpp"
- #include <util/dstr.hpp>
- #include <util/platform.h>
- #include <util/windows/ComPtr.hpp>
- #include <util/windows/win-registry.h>
- #include <util/windows/win-version.h>
- #include <cinttypes>
- #include <dxgi.h>
- #include <shlobj.h>
- static std::optional<std::vector<GoLiveApi::Gpu>> system_gpu_data()
- {
- ComPtr<IDXGIFactory1> factory;
- ComPtr<IDXGIAdapter1> adapter;
- HRESULT hr;
- UINT i;
- hr = CreateDXGIFactory1(IID_PPV_ARGS(&factory));
- if (FAILED(hr))
- return std::nullopt;
- std::vector<GoLiveApi::Gpu> adapter_info;
- for (i = 0; factory->EnumAdapters1(i, adapter.Assign()) == S_OK; ++i) {
- DXGI_ADAPTER_DESC desc;
- char name[512] = "";
- char driver_version[512] = "";
- hr = adapter->GetDesc(&desc);
- if (FAILED(hr))
- continue;
- /* ignore Microsoft's 'basic' renderer' */
- if (desc.VendorId == 0x1414 && desc.DeviceId == 0x8c)
- continue;
- os_wcs_to_utf8(desc.Description, 0, name, sizeof(name));
- GoLiveApi::Gpu data;
- data.model = name;
- data.vendor_id = desc.VendorId;
- data.device_id = desc.DeviceId;
- data.dedicated_video_memory = desc.DedicatedVideoMemory;
- data.shared_system_memory = desc.SharedSystemMemory;
- /* driver version */
- LARGE_INTEGER umd;
- hr = adapter->CheckInterfaceSupport(__uuidof(IDXGIDevice), &umd);
- if (SUCCEEDED(hr)) {
- const uint64_t version = umd.QuadPart;
- const uint16_t aa = (version >> 48) & 0xffff;
- const uint16_t bb = (version >> 32) & 0xffff;
- const uint16_t ccccc = (version >> 16) & 0xffff;
- const uint16_t ddddd = version & 0xffff;
- snprintf(driver_version, sizeof(driver_version), "%" PRIu16 ".%" PRIu16 ".%" PRIu16 ".%" PRIu16,
- aa, bb, ccccc, ddddd);
- data.driver_version = driver_version;
- }
- adapter_info.push_back(data);
- }
- return adapter_info;
- }
- static void get_processor_info(char **name, DWORD *speed)
- {
- HKEY key;
- wchar_t data[1024];
- DWORD size;
- LSTATUS status;
- memset(data, 0, sizeof(data));
- status = RegOpenKeyW(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", &key);
- if (status != ERROR_SUCCESS)
- return;
- size = sizeof(data);
- status = RegQueryValueExW(key, L"ProcessorNameString", NULL, NULL, (LPBYTE)data, &size);
- if (status == ERROR_SUCCESS) {
- os_wcs_to_utf8_ptr(data, 0, name);
- } else {
- *name = 0;
- }
- size = sizeof(*speed);
- status = RegQueryValueExW(key, L"~MHz", NULL, NULL, (LPBYTE)speed, &size);
- if (status != ERROR_SUCCESS)
- *speed = 0;
- RegCloseKey(key);
- }
- #define WIN10_GAME_BAR_REG_KEY L"Software\\Microsoft\\Windows\\CurrentVersion\\GameDVR"
- #define WIN10_GAME_DVR_POLICY_REG_KEY L"SOFTWARE\\Policies\\Microsoft\\Windows\\GameDVR"
- #define WIN10_GAME_DVR_REG_KEY L"System\\GameConfigStore"
- #define WIN10_GAME_MODE_REG_KEY L"Software\\Microsoft\\GameBar"
- #define WIN10_HAGS_REG_KEY L"SYSTEM\\CurrentControlSet\\Control\\GraphicsDrivers"
- static std::optional<GoLiveApi::GamingFeatures> get_gaming_features_data(const win_version_info &ver)
- {
- uint32_t win_ver = (ver.major << 8) | ver.minor;
- if (win_ver < 0xA00)
- return std::nullopt;
- GoLiveApi::GamingFeatures gaming_features;
- struct feature_mapping_s {
- std::optional<bool> *field;
- HKEY hkey;
- LPCWSTR sub_key;
- LPCWSTR value_name;
- LPCWSTR backup_value_name;
- bool non_existence_is_false;
- DWORD disabled_value;
- };
- struct feature_mapping_s features[] = {
- {&gaming_features.game_bar_enabled, HKEY_CURRENT_USER, WIN10_GAME_BAR_REG_KEY, L"AppCaptureEnabled", 0,
- false, 0},
- {&gaming_features.game_dvr_allowed, HKEY_CURRENT_USER, WIN10_GAME_DVR_POLICY_REG_KEY, L"AllowGameDVR",
- 0, false, 0},
- {&gaming_features.game_dvr_enabled, HKEY_CURRENT_USER, WIN10_GAME_DVR_REG_KEY, L"GameDVR_Enabled", 0,
- false, 0},
- {&gaming_features.game_dvr_bg_recording, HKEY_CURRENT_USER, WIN10_GAME_BAR_REG_KEY,
- L"HistoricalCaptureEnabled", 0, false, 0},
- {&gaming_features.game_mode_enabled, HKEY_CURRENT_USER, WIN10_GAME_MODE_REG_KEY, L"AutoGameModeEnabled",
- L"AllowAutoGameMode", false, 0},
- {&gaming_features.hags_enabled, HKEY_LOCAL_MACHINE, WIN10_HAGS_REG_KEY, L"HwSchMode", 0, true, 1}};
- for (int i = 0; i < sizeof(features) / sizeof(*features); ++i) {
- struct reg_dword info;
- get_reg_dword(features[i].hkey, features[i].sub_key, features[i].value_name, &info);
- if (info.status != ERROR_SUCCESS && features[i].backup_value_name) {
- get_reg_dword(features[i].hkey, features[i].sub_key, features[i].backup_value_name, &info);
- }
- if (info.status == ERROR_SUCCESS) {
- *features[i].field = info.return_value != features[i].disabled_value;
- } else if (features[i].non_existence_is_false) {
- *features[i].field = false;
- }
- }
- return gaming_features;
- }
- static inline bool get_reg_sz(HKEY key, const wchar_t *val, wchar_t *buf, DWORD size)
- {
- const LSTATUS status = RegGetValueW(key, NULL, val, RRF_RT_REG_SZ, NULL, buf, &size);
- return status == ERROR_SUCCESS;
- }
- #define MAX_SZ_LEN 256
- #define WINVER_REG_KEY L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"
- static char win_release_id[MAX_SZ_LEN] = "unavailable";
- static inline void get_reg_ver(struct win_version_info *ver)
- {
- HKEY key;
- DWORD size, dw_val;
- LSTATUS status;
- wchar_t str[MAX_SZ_LEN];
- status = RegOpenKeyW(HKEY_LOCAL_MACHINE, WINVER_REG_KEY, &key);
- if (status != ERROR_SUCCESS)
- return;
- size = sizeof(dw_val);
- status = RegQueryValueExW(key, L"CurrentMajorVersionNumber", NULL, NULL, (LPBYTE)&dw_val, &size);
- if (status == ERROR_SUCCESS)
- ver->major = (int)dw_val;
- status = RegQueryValueExW(key, L"CurrentMinorVersionNumber", NULL, NULL, (LPBYTE)&dw_val, &size);
- if (status == ERROR_SUCCESS)
- ver->minor = (int)dw_val;
- status = RegQueryValueExW(key, L"UBR", NULL, NULL, (LPBYTE)&dw_val, &size);
- if (status == ERROR_SUCCESS)
- ver->revis = (int)dw_val;
- if (get_reg_sz(key, L"CurrentBuildNumber", str, sizeof(str))) {
- ver->build = wcstol(str, NULL, 10);
- }
- const wchar_t *release_key = ver->build > 19041 ? L"DisplayVersion" : L"ReleaseId";
- if (get_reg_sz(key, release_key, str, sizeof(str))) {
- os_wcs_to_utf8(str, 0, win_release_id, MAX_SZ_LEN);
- }
- RegCloseKey(key);
- }
- void system_info(GoLiveApi::Capabilities &capabilities)
- {
- char tmpstr[1024];
- capabilities.gpu = system_gpu_data();
- {
- auto &cpu_data = capabilities.cpu;
- cpu_data.physical_cores = os_get_physical_cores();
- cpu_data.logical_cores = os_get_logical_cores();
- DWORD processorSpeed;
- char *processorName;
- get_processor_info(&processorName, &processorSpeed);
- if (processorSpeed)
- cpu_data.speed = processorSpeed;
- if (processorName)
- cpu_data.name = processorName;
- bfree(processorName);
- }
- {
- auto &memory_data = capabilities.memory;
- memory_data.total = os_get_sys_total_size();
- memory_data.free = os_get_sys_free_size();
- }
- struct win_version_info ver;
- get_win_ver(&ver);
- get_reg_ver(&ver);
- // Gaming features
- capabilities.gaming_features = get_gaming_features_data(ver);
- {
- auto &system_data = capabilities.system;
- snprintf(tmpstr, sizeof(tmpstr), "%d.%d", ver.major, ver.minor);
- system_data.version = tmpstr;
- system_data.name = "Windows";
- system_data.build = ver.build;
- system_data.release = win_release_id;
- system_data.revision = std::to_string(ver.revis);
- system_data.bits = is_64_bit_windows() ? 64 : 32;
- system_data.arm = is_arm64_windows();
- system_data.armEmulation = os_get_emulation_status();
- }
- }
|