plugin-main.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #include <windows.h>
  2. #include <obs-module.h>
  3. #include <util/dstr.h>
  4. #include <util/windows/win-version.h>
  5. #include <util/platform.h>
  6. #include <file-updater/file-updater.h>
  7. #include "compat-helpers.h"
  8. #include "compat-format-ver.h"
  9. #ifdef OBS_LEGACY
  10. #include "compat-config.h"
  11. #endif
  12. #define WIN_CAPTURE_LOG_STRING "[win-capture plugin] "
  13. #define WIN_CAPTURE_VER_STRING "win-capture plugin (libobs " OBS_VERSION ")"
  14. OBS_DECLARE_MODULE()
  15. OBS_MODULE_USE_DEFAULT_LOCALE("win-capture", "en-US")
  16. MODULE_EXPORT const char *obs_module_description(void)
  17. {
  18. return "Windows game/screen/window capture";
  19. }
  20. extern struct obs_source_info duplicator_capture_info;
  21. extern struct obs_source_info monitor_capture_info;
  22. extern struct obs_source_info window_capture_info;
  23. extern struct obs_source_info game_capture_info;
  24. static HANDLE init_hooks_thread = NULL;
  25. static update_info_t *update_info = NULL;
  26. extern bool cached_versions_match(void);
  27. extern bool load_cached_graphics_offsets(bool is32bit, const char *config_path);
  28. extern bool load_graphics_offsets(bool is32bit, bool use_hook_address_cache,
  29. const char *config_path);
  30. /* temporary, will eventually be erased once we figure out how to create both
  31. * 32bit and 64bit versions of the helpers/hook */
  32. #ifdef _WIN64
  33. #define IS32BIT false
  34. #else
  35. #define IS32BIT true
  36. #endif
  37. static const bool use_hook_address_cache = false;
  38. static DWORD WINAPI init_hooks(LPVOID param)
  39. {
  40. char *config_path = param;
  41. if (use_hook_address_cache && cached_versions_match() &&
  42. load_cached_graphics_offsets(IS32BIT, config_path)) {
  43. load_cached_graphics_offsets(!IS32BIT, config_path);
  44. obs_register_source(&game_capture_info);
  45. } else if (load_graphics_offsets(IS32BIT, use_hook_address_cache,
  46. config_path)) {
  47. load_graphics_offsets(!IS32BIT, use_hook_address_cache,
  48. config_path);
  49. }
  50. bfree(config_path);
  51. return 0;
  52. }
  53. void wait_for_hook_initialization(void)
  54. {
  55. static bool initialized = false;
  56. if (!initialized) {
  57. if (init_hooks_thread) {
  58. WaitForSingleObject(init_hooks_thread, INFINITE);
  59. CloseHandle(init_hooks_thread);
  60. init_hooks_thread = NULL;
  61. }
  62. initialized = true;
  63. }
  64. }
  65. static bool confirm_compat_file(void *param, struct file_download_data *file)
  66. {
  67. if (astrcmpi(file->name, "compatibility.json") == 0) {
  68. obs_data_t *data;
  69. int format_version;
  70. data = obs_data_create_from_json((char *)file->buffer.array);
  71. if (!data)
  72. return false;
  73. format_version = (int)obs_data_get_int(data, "format_version");
  74. obs_data_release(data);
  75. if (format_version != COMPAT_FORMAT_VERSION)
  76. return false;
  77. }
  78. UNUSED_PARAMETER(param);
  79. return true;
  80. }
  81. void init_hook_files(void);
  82. bool graphics_uses_d3d11 = false;
  83. bool wgc_supported = false;
  84. bool obs_module_load(void)
  85. {
  86. struct win_version_info ver;
  87. bool win8_or_above = false;
  88. char *local_dir;
  89. char *config_dir;
  90. char update_url[128];
  91. snprintf(update_url, sizeof(update_url), "%s/v%d", COMPAT_URL,
  92. COMPAT_FORMAT_VERSION);
  93. struct win_version_info win1903 = {.major = 10,
  94. .minor = 0,
  95. .build = 18362,
  96. .revis = 0};
  97. local_dir = obs_module_file(NULL);
  98. config_dir = obs_module_config_path(NULL);
  99. if (config_dir) {
  100. os_mkdirs(config_dir);
  101. if (local_dir) {
  102. update_info = update_info_create(
  103. WIN_CAPTURE_LOG_STRING, WIN_CAPTURE_VER_STRING,
  104. update_url, local_dir, config_dir,
  105. confirm_compat_file, NULL);
  106. }
  107. }
  108. bfree(config_dir);
  109. bfree(local_dir);
  110. get_win_ver(&ver);
  111. win8_or_above = ver.major > 6 || (ver.major == 6 && ver.minor >= 2);
  112. obs_enter_graphics();
  113. graphics_uses_d3d11 = gs_get_device_type() == GS_DEVICE_DIRECT3D_11;
  114. obs_leave_graphics();
  115. if (graphics_uses_d3d11)
  116. wgc_supported = win_version_compare(&ver, &win1903) >= 0;
  117. if (win8_or_above && graphics_uses_d3d11)
  118. obs_register_source(&duplicator_capture_info);
  119. else
  120. obs_register_source(&monitor_capture_info);
  121. obs_register_source(&window_capture_info);
  122. char *config_path = obs_module_config_path(NULL);
  123. init_hook_files();
  124. init_hooks_thread =
  125. CreateThread(NULL, 0, init_hooks, config_path, 0, NULL);
  126. obs_register_source(&game_capture_info);
  127. return true;
  128. }
  129. void obs_module_unload(void)
  130. {
  131. wait_for_hook_initialization();
  132. update_info_destroy(update_info);
  133. compat_json_free();
  134. }