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)
This commit is contained in:
jp9000 2015-08-01 14:19:41 -07:00
parent 9a93e4b859
commit ef332ab8b6
3 changed files with 134 additions and 0 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2015 Hugh Bailey <obs.jim@gmail.com>
*
* 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