diff --git a/plugins/win-capture/load-graphics-offsets.c b/plugins/win-capture/load-graphics-offsets.c index d66197c09451a59f38588395e2e265ad4bfd5cdd..6ad4021a397a2c627a4a6db52c244710972f7576 100644 --- a/plugins/win-capture/load-graphics-offsets.c +++ b/plugins/win-capture/load-graphics-offsets.c @@ -1,11 +1,13 @@ #define _CRT_SECURE_NO_WARNINGS #include +#include #include #include #include #include #include +#include #include "graphics-hook-info.h" extern struct graphics_offsets offsets32; @@ -45,10 +47,115 @@ static inline bool load_offsets_from_string(struct graphics_offsets *offsets, return true; } +static inline bool load_offsets_from_file(struct graphics_offsets *offsets, + const char *file) +{ + char *str = os_quick_read_utf8_file(file); + bool success = false; + if (str && *str) + success = load_offsets_from_string(offsets, str); + bfree(str); + return success; +} + +static inline bool config_ver_mismatch( + config_t *ver_config, + const char *section, + struct win_version_info *ver) +{ + struct win_version_info config_ver; + bool mismatch = false; + +#define get_sub_ver(subver) \ + config_ver.subver = (int)config_get_int(ver_config, section, #subver); \ + mismatch |= config_ver.subver != ver->subver; + + get_sub_ver(major); + get_sub_ver(minor); + get_sub_ver(build); + get_sub_ver(revis); + +#undef get_sub_ver + + return mismatch; +} + +static inline void write_config_ver(config_t *ver_config, const char *section, + struct win_version_info *ver) +{ +#define set_sub_ver(subver) \ + config_set_int(ver_config, section, #subver, ver->subver); + + set_sub_ver(major); + set_sub_ver(minor); + set_sub_ver(build); + set_sub_ver(revis); + +#undef set_sub_ver +} + +static bool get_32bit_system_dll_ver(const wchar_t *system_lib, + struct win_version_info *ver) +{ + wchar_t path[MAX_PATH]; + + HRESULT hr = SHGetFolderPathW(NULL, CSIDL_SYSTEMX86, NULL, + SHGFP_TYPE_CURRENT, path); + if (hr != S_OK) { + blog(LOG_ERROR, "Failed to get windows 32bit system path: " + "%08lX", hr); + return false; + } + + wcscat(path, L"\\"); + wcscat(path, system_lib); + return get_dll_ver(path, ver); +} + +bool cached_versions_match(void) +{ + struct win_version_info d3d8_ver = {0}; + struct win_version_info d3d9_ver = {0}; + struct win_version_info dxgi_ver = {0}; + bool ver_mismatch = false; + config_t *config; + char *ver_file; + int ret; + + ver_mismatch |= !get_32bit_system_dll_ver(L"d3d8.dll", &d3d8_ver); + ver_mismatch |= !get_32bit_system_dll_ver(L"d3d9.dll", &d3d9_ver); + ver_mismatch |= !get_32bit_system_dll_ver(L"dxgi.dll", &dxgi_ver); + + ver_file = obs_module_config_path("version.ini"); + if (!ver_file) + return false; + + ret = config_open(&config, ver_file, CONFIG_OPEN_ALWAYS); + if (ret != CONFIG_SUCCESS) + goto failed; + + ver_mismatch |= config_ver_mismatch(config, "d3d8", &d3d8_ver); + ver_mismatch |= config_ver_mismatch(config, "d3d9", &d3d9_ver); + ver_mismatch |= config_ver_mismatch(config, "dxgi", &dxgi_ver); + + if (ver_mismatch) { + write_config_ver(config, "d3d8", &d3d8_ver); + write_config_ver(config, "d3d9", &d3d9_ver); + write_config_ver(config, "dxgi", &dxgi_ver); + config_save_safe(config, "tmp", NULL); + } + +failed: + bfree(ver_file); + config_close(config); + return !ver_mismatch; +} + bool load_graphics_offsets(bool is32bit) { char *offset_exe_path = NULL; struct dstr offset_exe = {0}; + char *config_ini = NULL; struct dstr str = {0}; os_process_pipe_t *pp; bool success = false; @@ -73,6 +180,11 @@ bool load_graphics_offsets(bool is32bit) dstr_ncat(&str, data, len); } + config_ini = obs_module_config_path(is32bit ? "32.ini" : "64.ini"); + os_quick_write_utf8_file_safe(config_ini, str.array, str.len, false, + "tmp", NULL); + bfree(config_ini); + success = load_offsets_from_string(is32bit ? &offsets32 : &offsets64, str.array); if (!success) { @@ -87,3 +199,18 @@ error: dstr_free(&str); return success; } + +bool load_cached_graphics_offsets(bool is32bit) +{ + char *config_ini = NULL; + bool success; + + config_ini = obs_module_config_path(is32bit ? "32.ini" : "64.ini"); + success = load_offsets_from_file(is32bit ? &offsets32 : &offsets64, + config_ini); + if (!success) + success = load_graphics_offsets(is32bit); + + bfree(config_ini); + return success; +} diff --git a/plugins/win-capture/plugin-main.c b/plugins/win-capture/plugin-main.c index 8ee5a60cae1d3bb42f4cbfe1456a59f190abe0c3..6bde908b619a96fd67016983dda4da1c9bcfc4d8 100644 --- a/plugins/win-capture/plugin-main.c +++ b/plugins/win-capture/plugin-main.c @@ -1,6 +1,7 @@ #include #include #include +#include OBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE("win-capture", "en-US") @@ -10,6 +11,8 @@ extern struct obs_source_info monitor_capture_info; extern struct obs_source_info window_capture_info; extern struct obs_source_info game_capture_info; +extern bool cached_versions_match(void); +extern bool load_cached_graphics_offsets(bool is32bit); extern bool load_graphics_offsets(bool is32bit); /* temporary, will eventually be erased once we figure out how to create both @@ -24,6 +27,13 @@ bool obs_module_load(void) { struct win_version_info ver; bool win8_or_above = false; + char *config_dir; + + config_dir = obs_module_config_path(NULL); + if (config_dir) { + os_mkdirs(config_dir); + bfree(config_dir); + } get_win_ver(&ver); @@ -40,7 +50,11 @@ bool obs_module_load(void) obs_register_source(&window_capture_info); - if (load_graphics_offsets(IS32BIT)) { + if (cached_versions_match() && load_cached_graphics_offsets(IS32BIT)) { + load_cached_graphics_offsets(!IS32BIT); + obs_register_source(&game_capture_info); + + } else if (load_graphics_offsets(IS32BIT)) { load_graphics_offsets(!IS32BIT); obs_register_source(&game_capture_info); }