| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- #include "system_version.h"
- #include <Windows.h>
- #include "log_helper.h"
- #include "utils_string.h"
- #define WINVER_REG_KEY L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"
- typedef DWORD(WINAPI *get_file_version_info_size_w_t)(LPCWSTR module, LPDWORD unused);
- typedef BOOL(WINAPI *get_file_version_info_w_t)(LPCWSTR module,
- DWORD unused,
- DWORD len,
- LPVOID data);
- typedef BOOL(WINAPI *ver_query_value_w_t)(LPVOID data, LPCWSTR subblock, LPVOID *buf, PUINT sizeout);
- static get_file_version_info_size_w_t get_file_version_info_size = NULL;
- static get_file_version_info_w_t get_file_version_info = NULL;
- static ver_query_value_w_t ver_query_value = NULL;
- static bool ver_initialized = false;
- static bool ver_initialize_success = false;
- static bool initialize_version_functions(void)
- {
- HMODULE ver = GetModuleHandleW(L"version");
- ver_initialized = true;
- if (!ver) {
- ver = LoadLibraryW(L"version");
- if (!ver) {
- al_error("failed to load windows version library");
- return false;
- }
- }
- get_file_version_info_size = (get_file_version_info_size_w_t)
- GetProcAddress(ver, "GetFileVersionInfoSizeW");
- get_file_version_info = (get_file_version_info_w_t) GetProcAddress(ver, "GetFileVersionInfoW");
- ver_query_value = (ver_query_value_w_t) GetProcAddress(ver, "VerQueryValueW");
- if (!get_file_version_info_size || !get_file_version_info || !ver_query_value) {
- al_error("failed to load windows version functions");
- return false;
- }
- ver_initialize_success = true;
- return true;
- }
- namespace am {
- bool system_version::get_dll(const std::string tar, winversion_info *info)
- {
- VS_FIXEDFILEINFO *file_info = NULL;
- UINT len = 0;
- BOOL success;
- LPVOID data;
- DWORD size;
- std::wstring wtar = utils_string::ascii_unicode(tar);
- if (!ver_initialized && !initialize_version_functions())
- return false;
- if (!ver_initialize_success)
- return false;
- size = get_file_version_info_size(wtar.c_str(), NULL);
- if (!size) {
- al_error("failed to get %s version info size", tar.c_str());
- return false;
- }
- data = malloc(size);
- if (!get_file_version_info(wtar.c_str(), 0, size, data)) {
- al_error("failed to get %s version info", tar.c_str());
- free(data);
- return false;
- }
- success = ver_query_value(data, L"\\", (LPVOID *) &file_info, &len);
- if (!success || !file_info || !len) {
- al_error("failed to get %s version info value", tar.c_str());
- free(data);
- return false;
- }
- info->major = (int) HIWORD(file_info->dwFileVersionMS);
- info->minor = (int) LOWORD(file_info->dwFileVersionMS);
- info->build = (int) HIWORD(file_info->dwFileVersionLS);
- info->revis = (int) LOWORD(file_info->dwFileVersionLS);
- free(data);
- return true;
- }
- void system_version::get_win(winversion_info *info)
- {
- static winversion_info ver = {0};
- static bool got_version = false;
- if (!info)
- return;
- if (!got_version) {
- get_dll("kernel32", &ver);
- got_version = true;
- if (ver.major == 10) {
- HKEY key;
- DWORD size, win10_revision;
- LSTATUS status;
- status = RegOpenKeyW(HKEY_LOCAL_MACHINE, WINVER_REG_KEY, &key);
- if (status != ERROR_SUCCESS)
- return;
- size = sizeof(win10_revision);
- status = RegQueryValueExW(key, L"UBR", NULL, NULL, (LPBYTE) &win10_revision, &size);
- if (status == ERROR_SUCCESS)
- ver.revis = (int) win10_revision > ver.revis ? (int) win10_revision : ver.revis;
- RegCloseKey(key);
- }
- }
- *info = ver;
- }
- bool system_version::is_win8_or_above()
- {
- winversion_info info;
- get_win(&info);
- return info.major > 6 || (info.major == 6 && info.minor >= 2);
- }
- bool system_version::is_win10_or_above(int build_number)
- {
- winversion_info info;
- get_win(&info);
- return info.major > 6 || (info.major == 6 && info.minor >= 2);
- }
- bool system_version::is_32()
- {
- #if defined(_WIN64)
- return false;
- #elif defined(_WIN32)
- BOOL b64 = false;
- return !(IsWow64Process(GetCurrentProcess(), &b64) && b64);
- #endif
- }
- } // namespace am
|