From ef332ab8b66ec8f093d33af92fe0e17e413448dd Mon Sep 17 00:00:00 2001 From: jp9000 Date: Sat, 1 Aug 2015 14:19:41 -0700 Subject: [PATCH] libobs: Add function to get the windows version Microsoft basically deprecated GetVersion/GetVersionEx, so now you have to query the file version of kernel32.dll in order to get the actual windows version. Because of the steps involved in getting the windows version are fairly complicated, this is an exported libobs helper function that can be used to get the windows version if needed. (Microsoft does have its own set of helper functions for this but the API feels a bit.. awkward, and you can't actually get the real windows version with them) --- libobs/CMakeLists.txt | 1 + libobs/util/platform-windows.c | 97 +++++++++++++++++++++++++++++++ libobs/util/windows/win-version.h | 36 ++++++++++++ 3 files changed, 134 insertions(+) create mode 100644 libobs/util/windows/win-version.h diff --git a/libobs/CMakeLists.txt b/libobs/CMakeLists.txt index 51113acbd..f8c88e393 100644 --- a/libobs/CMakeLists.txt +++ b/libobs/CMakeLists.txt @@ -60,6 +60,7 @@ elseif(APPLE) util/platform-nix.c util/platform-cocoa.m) set(libobs_PLATFORM_HEADERS + util/windows/win-version.h util/windows/ComPtr.hpp util/windows/CoTaskMemPtr.hpp util/windows/HRError.hpp diff --git a/libobs/util/platform-windows.c b/libobs/util/platform-windows.c index 919bc78c5..1048f4201 100644 --- a/libobs/util/platform-windows.c +++ b/libobs/util/platform-windows.c @@ -23,6 +23,7 @@ #include "platform.h" #include "darray.h" #include "dstr.h" +#include "windows/win-version.h" #include "../../deps/w32-pthreads/pthread.h" @@ -569,3 +570,99 @@ int os_chdir(const char *path) return ret; } + +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 void actually_get_win_ver(struct win_version_info *ver_info) +{ + HMODULE ver = GetModuleHandleW(L"version"); + VS_FIXEDFILEINFO *info = NULL; + UINT len = 0; + BOOL success; + LPVOID data; + DWORD size; + + get_file_version_info_size_w_t get_file_version_info_size; + get_file_version_info_w_t get_file_version_info; + ver_query_value_w_t ver_query_value; + + if (!ver) { + ver = LoadLibraryW(L"version"); + if (!ver) { + blog(LOG_ERROR, "Failed to load windows version " + "library"); + return; + } + } + + 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) { + blog(LOG_ERROR, "Failed to load windows version " + "functions"); + return; + } + + size = get_file_version_info_size(L"kernel32", NULL); + if (!size) { + blog(LOG_ERROR, "Failed to get windows version info size"); + return; + } + + data = bmalloc(size); + if (!get_file_version_info(L"kernel32", 0, size, data)) { + blog(LOG_ERROR, "Failed to get windows version info"); + bfree(data); + return; + } + + success = ver_query_value(data, L"\\", (LPVOID*)&info, &len); + if (!success || !info || !len) { + blog(LOG_ERROR, "Failed to get windows version info value"); + bfree(data); + return; + } + + ver_info->major = (int)HIWORD(info->dwFileVersionMS); + ver_info->minor = (int)LOWORD(info->dwFileVersionMS); + ver_info->build = (int)HIWORD(info->dwFileVersionLS); + ver_info->revis = (int)LOWORD(info->dwFileVersionLS); + + bfree(data); + return; +} + +void get_win_ver(struct win_version_info *info) +{ + static struct win_version_info ver = {0}; + static bool got_version = false; + + if (!info) + return; + + if (!got_version) { + actually_get_win_ver(&ver); + got_version = true; + } + + *info = ver; +} diff --git a/libobs/util/windows/win-version.h b/libobs/util/windows/win-version.h new file mode 100644 index 000000000..6e49de2b7 --- /dev/null +++ b/libobs/util/windows/win-version.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2015 Hugh Bailey + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#pragma once + +#include "../c99defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct win_version_info { + int major; + int minor; + int build; + int revis; +}; + +EXPORT void get_win_ver(struct win_version_info *info); + +#ifdef __cplusplus +} +#endif