init-hook-files.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #include <windows.h>
  2. #include <strsafe.h>
  3. #include <shlobj.h>
  4. #include <stdbool.h>
  5. #include <aclapi.h>
  6. #include <sddl.h>
  7. static bool add_aap_perms(const wchar_t *dir)
  8. {
  9. PSECURITY_DESCRIPTOR sd = NULL;
  10. SID *aap_sid = NULL;
  11. SID *bu_sid = NULL;
  12. PACL new_dacl1 = NULL;
  13. PACL new_dacl2 = NULL;
  14. bool success = false;
  15. PACL dacl;
  16. if (GetNamedSecurityInfoW(dir, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &dacl, NULL, &sd) !=
  17. ERROR_SUCCESS) {
  18. goto fail;
  19. }
  20. EXPLICIT_ACCESSW ea = {0};
  21. ea.grfAccessPermissions = GENERIC_READ | GENERIC_EXECUTE;
  22. ea.grfAccessMode = GRANT_ACCESS;
  23. ea.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
  24. ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
  25. /* ALL_APP_PACKAGES */
  26. ConvertStringSidToSidW(L"S-1-15-2-1", &aap_sid);
  27. ea.Trustee.ptstrName = (wchar_t *)aap_sid;
  28. if (SetEntriesInAclW(1, &ea, dacl, &new_dacl1) != ERROR_SUCCESS) {
  29. goto fail;
  30. }
  31. ea.grfAccessPermissions = GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE;
  32. /* BUILTIN_USERS */
  33. ConvertStringSidToSidW(L"S-1-5-32-545", &bu_sid);
  34. ea.Trustee.ptstrName = (wchar_t *)bu_sid;
  35. DWORD s = SetEntriesInAclW(1, &ea, new_dacl1, &new_dacl2);
  36. if (s != ERROR_SUCCESS) {
  37. goto fail;
  38. }
  39. if (SetNamedSecurityInfoW((wchar_t *)dir, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, new_dacl2,
  40. NULL) != ERROR_SUCCESS) {
  41. goto fail;
  42. }
  43. success = true;
  44. fail:
  45. if (sd)
  46. LocalFree(sd);
  47. if (new_dacl1)
  48. LocalFree(new_dacl1);
  49. if (new_dacl2)
  50. LocalFree(new_dacl2);
  51. if (aap_sid)
  52. LocalFree(aap_sid);
  53. if (bu_sid)
  54. LocalFree(bu_sid);
  55. return success;
  56. }
  57. static inline bool file_exists(const wchar_t *path)
  58. {
  59. WIN32_FIND_DATAW wfd;
  60. HANDLE h = FindFirstFileW(path, &wfd);
  61. if (h == INVALID_HANDLE_VALUE)
  62. return false;
  63. FindClose(h);
  64. return true;
  65. }
  66. static LSTATUS get_reg(HKEY hkey, LPCWSTR sub_key, LPCWSTR value_name, bool b64)
  67. {
  68. HKEY key;
  69. LSTATUS status;
  70. DWORD flags = b64 ? KEY_WOW64_64KEY : KEY_WOW64_32KEY;
  71. DWORD size = sizeof(DWORD);
  72. DWORD val;
  73. status = RegOpenKeyEx(hkey, sub_key, 0, KEY_READ | flags, &key);
  74. if (status == ERROR_SUCCESS) {
  75. status = RegQueryValueExW(key, value_name, NULL, NULL, (LPBYTE)&val, &size);
  76. RegCloseKey(key);
  77. }
  78. return status;
  79. }
  80. #define get_programdata_path(path, subpath) \
  81. do { \
  82. SHGetFolderPathW(NULL, CSIDL_COMMON_APPDATA, NULL, SHGFP_TYPE_CURRENT, path); \
  83. StringCbCatW(path, sizeof(path), L"\\"); \
  84. StringCbCatW(path, sizeof(path), subpath); \
  85. } while (false)
  86. #define make_filename(str, name, ext) \
  87. do { \
  88. StringCbCatW(str, sizeof(str), name); \
  89. StringCbCatW(str, sizeof(str), b64 ? L"64" : L"32"); \
  90. StringCbCatW(str, sizeof(str), ext); \
  91. } while (false)
  92. #define IMPLICIT_LAYERS L"SOFTWARE\\Khronos\\Vulkan\\ImplicitLayers"
  93. #define HOOK_LOCATION L"\\data\\obs-plugins\\win-capture\\"
  94. static bool update_hook_file(bool b64)
  95. {
  96. wchar_t temp[MAX_PATH];
  97. wchar_t src[MAX_PATH];
  98. wchar_t dst[MAX_PATH];
  99. wchar_t src_json[MAX_PATH];
  100. wchar_t dst_json[MAX_PATH];
  101. GetCurrentDirectoryW(_countof(src_json), src_json);
  102. StringCbCat(src_json, sizeof(src_json), HOOK_LOCATION);
  103. make_filename(src_json, L"obs-vulkan", L".json");
  104. GetCurrentDirectoryW(_countof(src), src);
  105. StringCbCat(src, sizeof(src), HOOK_LOCATION);
  106. make_filename(src, L"graphics-hook", L".dll");
  107. get_programdata_path(temp, L"obs-studio-hook\\");
  108. StringCbCopyW(dst_json, sizeof(dst_json), temp);
  109. StringCbCopyW(dst, sizeof(dst), temp);
  110. make_filename(dst_json, L"obs-vulkan", L".json");
  111. make_filename(dst, L"graphics-hook", L".dll");
  112. if (!file_exists(src)) {
  113. return false;
  114. }
  115. CreateDirectoryW(temp, NULL);
  116. add_aap_perms(temp);
  117. CopyFileW(src, dst, false);
  118. CopyFileW(src_json, dst_json, false);
  119. return true;
  120. }
  121. static void update_vulkan_registry(bool b64)
  122. {
  123. DWORD flags = b64 ? KEY_WOW64_64KEY : KEY_WOW64_32KEY;
  124. wchar_t path[MAX_PATH];
  125. DWORD temp;
  126. LSTATUS s;
  127. HKEY key;
  128. get_programdata_path(path, L"obs-studio-hook\\");
  129. make_filename(path, L"obs-vulkan", L".json");
  130. s = get_reg(HKEY_CURRENT_USER, IMPLICIT_LAYERS, path, b64);
  131. if (s == ERROR_SUCCESS) {
  132. s = RegOpenKeyEx(HKEY_CURRENT_USER, IMPLICIT_LAYERS, 0, KEY_WRITE | flags, &key);
  133. if (s == ERROR_SUCCESS) {
  134. RegDeleteValueW(key, path);
  135. RegCloseKey(key);
  136. }
  137. }
  138. s = get_reg(HKEY_LOCAL_MACHINE, IMPLICIT_LAYERS, path, b64);
  139. if (s == ERROR_SUCCESS) {
  140. return;
  141. }
  142. /* ------------------- */
  143. s = RegCreateKeyExW(HKEY_LOCAL_MACHINE, IMPLICIT_LAYERS, 0, NULL, 0, KEY_WRITE | flags, NULL, &key, &temp);
  144. if (s != ERROR_SUCCESS) {
  145. goto finish;
  146. }
  147. DWORD zero = 0;
  148. s = RegSetValueExW(key, path, 0, REG_DWORD, (const BYTE *)&zero, sizeof(zero));
  149. if (s != ERROR_SUCCESS) {
  150. goto finish;
  151. }
  152. finish:
  153. if (key)
  154. RegCloseKey(key);
  155. }
  156. void UpdateHookFiles(void)
  157. {
  158. if (update_hook_file(true))
  159. update_vulkan_registry(true);
  160. if (update_hook_file(false))
  161. update_vulkan_registry(false);
  162. }