diff --git a/frontend/OBSApp.cpp b/frontend/OBSApp.cpp index 0d6d0e28e35fbd..fad7570abe68de 100644 --- a/frontend/OBSApp.cpp +++ b/frontend/OBSApp.cpp @@ -38,6 +38,7 @@ #include #include +#include #if defined(_WIN32) || defined(ENABLE_SPARKLE_UPDATER) #include #endif @@ -331,10 +332,8 @@ bool OBSApp::InitGlobalConfigDefaults() bool OBSApp::InitGlobalLocationDefaults() { - char path[512]; - - int len = GetAppConfigPath(path, sizeof(path), nullptr); - if (len <= 0) { + BPtr path = GetAppConfigPathPtr(nullptr); + if (!path || !*path.Get()) { OBSErrorBox(NULL, "Unable to get global configuration path."); return false; } @@ -407,49 +406,37 @@ static bool do_mkdir(const char *path) static bool MakeUserDirs() { - char path[512]; + BPtr path; - if (GetAppConfigPath(path, sizeof(path), "obs-studio/basic") <= 0) { - return false; - } - if (!do_mkdir(path)) { + path = GetAppConfigPathPtr("obs-studio/basic"); + if (!path || !*path.Get() || !do_mkdir(path)) { return false; } - if (GetAppConfigPath(path, sizeof(path), "obs-studio/logs") <= 0) { - return false; - } - if (!do_mkdir(path)) { + path = GetAppConfigPathPtr("obs-studio/logs"); + if (!path || !*path.Get() || !do_mkdir(path)) { return false; } - if (GetAppConfigPath(path, sizeof(path), "obs-studio/profiler_data") <= 0) { - return false; - } - if (!do_mkdir(path)) { + path = GetAppConfigPathPtr("obs-studio/profiler_data"); + if (!path || !*path.Get() || !do_mkdir(path)) { return false; } #ifdef _WIN32 - if (GetAppConfigPath(path, sizeof(path), "obs-studio/crashes") <= 0) { - return false; - } - if (!do_mkdir(path)) { + path = GetAppConfigPathPtr("obs-studio/crashes"); + if (!path || !*path.Get() || !do_mkdir(path)) { return false; } #endif - if (GetAppConfigPath(path, sizeof(path), "obs-studio/updates") <= 0) { - return false; - } - if (!do_mkdir(path)) { + path = GetAppConfigPathPtr("obs-studio/updates"); + if (!path || !*path.Get() || !do_mkdir(path)) { return false; } - if (GetAppConfigPath(path, sizeof(path), "obs-studio/plugin_config") <= 0) { - return false; - } - if (!do_mkdir(path)) { + path = GetAppConfigPathPtr("obs-studio/plugin_config"); + if (!path || !*path.Get() || !do_mkdir(path)) { return false; } @@ -537,10 +524,8 @@ bool OBSApp::UpdatePre22MultiviewLayout(const char *layout) bool OBSApp::InitGlobalConfig() { - char path[512]; - - int len = GetAppConfigPath(path, sizeof(path), "obs-studio/global.ini"); - if (len <= 0) { + BPtr path = GetAppConfigPathPtr("obs-studio/global.ini"); + if (!path || !*path.Get()) { return false; } @@ -676,10 +661,8 @@ static constexpr string_view OBSUserIniPath = "/obs-studio/user.ini"; bool OBSApp::MigrateGlobalSettings() { - char path[512]; - - int len = GetAppConfigPath(path, sizeof(path), nullptr); - if (len <= 0) { + BPtr path = GetAppConfigPathPtr(nullptr); + if (!path || !*path.Get()) { OBSErrorBox(nullptr, "Unable to get global configuration path."); return false; } @@ -970,13 +953,13 @@ OBSApp::~OBSApp() static void move_basic_to_profiles(void) { - char path[512]; + BPtr path = GetAppConfigPathPtr("obs-studio/basic"); - if (GetAppConfigPath(path, 512, "obs-studio/basic") <= 0) { + if (!path || !*path.Get()) { return; } - const std::filesystem::path basicPath = std::filesystem::u8path(path); + const std::filesystem::path basicPath = std::filesystem::u8path(path.Get()); if (!std::filesystem::exists(basicPath)) { return; @@ -1034,13 +1017,13 @@ static void move_basic_to_profiles(void) static void move_basic_to_scene_collections(void) { - char path[512]; + BPtr path = GetAppConfigPathPtr("obs-studio/basic"); - if (GetAppConfigPath(path, 512, "obs-studio/basic") <= 0) { + if (!path || !*path.Get()) { return; } - const std::filesystem::path basicPath = std::filesystem::u8path(path); + const std::filesystem::path basicPath = std::filesystem::u8path(path.Get()); if (!std::filesystem::exists(basicPath)) { return; @@ -1169,9 +1152,9 @@ const char *OBSApp::GetRenderModule() const static bool StartupOBS(const char *locale, profiler_name_store_t *store) { - char path[512]; + BPtr path = GetAppConfigPathPtr("obs-studio/plugin_config"); - if (GetAppConfigPath(path, sizeof(path), "obs-studio/plugin_config") <= 0) { + if (!path || !*path.Get()) { return false; } @@ -1515,16 +1498,10 @@ bool OBSApp::notify(QObject *receiver, QEvent *e) string GenerateTimeDateFilename(const char *extension, bool noSpace) { - time_t now = time(0); - char file[256] = {}; - struct tm *cur_time; - - cur_time = localtime(&now); - snprintf(file, sizeof(file), "%d-%02d-%02d%c%02d-%02d-%02d.%s", cur_time->tm_year + 1900, cur_time->tm_mon + 1, - cur_time->tm_mday, noSpace ? '_' : ' ', cur_time->tm_hour, cur_time->tm_min, cur_time->tm_sec, - extension); + QString format = noSpace ? "yyyy-MM-dd_hh-mm-ss" : "yyyy-MM-dd hh-mm-ss"; + QString filename = QDateTime::currentDateTime().toString(format) + "." + extension; - return string(file); + return filename.toStdString(); } string GenerateSpecifiedFilename(const char *extension, bool noSpace, const char *format) @@ -1743,7 +1720,7 @@ char *GetAppConfigPathPtr(const char *name) { #if ALLOW_PORTABLE_MODE if (portable_mode) { - char path[512]; + char path[MAX_PATH_UTF8]; if (snprintf(path, sizeof(path), CONFIG_PATH "/%s", name) > 0) { return bstrdup(path); diff --git a/frontend/OBSApp_Themes.cpp b/frontend/OBSApp_Themes.cpp index 653c529a32ad91..e24b078b467fef 100644 --- a/frontend/OBSApp_Themes.cpp +++ b/frontend/OBSApp_Themes.cpp @@ -1000,9 +1000,9 @@ bool OBSApp::SetTheme(const QString &name) filename += ".out"; filesystem::path debugOut; - char configPath[512]; - if (GetAppConfigPath(configPath, sizeof(configPath), filename.c_str())) { - debugOut = absolute(filesystem::u8path(configPath)); + BPtr configPath = GetAppConfigPathPtr(filename.c_str()); + if (configPath && *configPath.Get()) { + debugOut = absolute(filesystem::u8path(configPath.Get())); filesystem::create_directories(debugOut.parent_path()); } @@ -1063,9 +1063,9 @@ bool OBSApp::InitTheme() QDir::addSearchPath("theme", absolute(installSearchDir)); } - char userDir[512]; - if (GetAppConfigPath(userDir, sizeof(userDir), "obs-studio/themes")) { - auto configSearchDir = filesystem::u8path(userDir); + BPtr userDir = GetAppConfigPathPtr("obs-studio/themes"); + if (userDir && *userDir.Get()) { + auto configSearchDir = filesystem::u8path(userDir.Get()); QDir::addSearchPath("theme", absolute(configSearchDir)); } diff --git a/frontend/dialogs/OBSLogViewer.cpp b/frontend/dialogs/OBSLogViewer.cpp index 74b3e583b98fe4..42614305c58e43 100644 --- a/frontend/dialogs/OBSLogViewer.cpp +++ b/frontend/dialogs/OBSLogViewer.cpp @@ -45,10 +45,10 @@ void OBSLogViewer::on_showStartup_clicked(bool checked) void OBSLogViewer::InitLog() { - char logDir[512]; + BPtr logDir = GetAppConfigPathPtr("obs-studio/logs"); std::string path; - if (GetAppConfigPath(logDir, sizeof(logDir), "obs-studio/logs")) { + if (logDir.Get()) { path += logDir; path += "/"; path += App()->GetCurrentLog(); @@ -114,14 +114,14 @@ void OBSLogViewer::AddLine(int type, const QString &str) void OBSLogViewer::on_openButton_clicked() { - char logDir[512]; - if (GetAppConfigPath(logDir, sizeof(logDir), "obs-studio/logs") <= 0) { + BPtr logDir = GetAppConfigPathPtr("obs-studio/logs"); + if (!logDir || !*logDir.Get()) { return; } const char *log = App()->GetCurrentLog(); - std::string path = logDir; + std::string path(logDir); path += "/"; path += log; diff --git a/frontend/importers/classic.cpp b/frontend/importers/classic.cpp index 5125e5d3b914ee..01fa7d24566ca3 100644 --- a/frontend/importers/classic.cpp +++ b/frontend/importers/classic.cpp @@ -548,9 +548,8 @@ OBSImporterFiles ClassicImporter::FindFiles() OBSImporterFiles res; #ifdef _WIN32 - char dst[512]; - int found = os_get_config_path(dst, 512, "OBS\\sceneCollection\\"); - if (found == -1) { + BPtr dst = os_get_config_path_ptr("OBS\\sceneCollection\\"); + if (!dst) { return res; } @@ -564,7 +563,7 @@ OBSImporterFiles ClassicImporter::FindFiles() string name = ent->d_name; size_t pos = name.find(".xconfig"); if (pos != -1 && pos == name.length() - 8) { - string path = dst + name; + string path = dst.Get() + name; res.push_back(path); } } diff --git a/frontend/importers/sl.cpp b/frontend/importers/sl.cpp index 7f1b2554b9b085..f8dece8d77f468 100644 --- a/frontend/importers/sl.cpp +++ b/frontend/importers/sl.cpp @@ -495,11 +495,9 @@ OBSImporterFiles SLImporter::FindFiles() { OBSImporterFiles res; #if defined(_WIN32) || defined(__APPLE__) - char dst[512]; + BPtr dst = os_get_config_path_ptr("slobs-client/SceneCollections/"); - int found = os_get_config_path(dst, 512, "slobs-client/SceneCollections/"); - - if (found == -1) { + if (!dst) { return res; } @@ -515,7 +513,7 @@ OBSImporterFiles SLImporter::FindFiles() size_t pos = name.find_last_of(".json"); size_t end_pos = name.size() - 1; if (pos != string::npos && pos == end_pos) { - string str = dst + name; + string str = dst.Get() + name; res.push_back(str); } } diff --git a/frontend/importers/studio.cpp b/frontend/importers/studio.cpp index 45c8fc102a384d..749dbc35c52757 100644 --- a/frontend/importers/studio.cpp +++ b/frontend/importers/studio.cpp @@ -143,15 +143,11 @@ void TranslateOSStudio(Json &res) static string CheckPath(const string &path, const string &rootDir) { - char root[512]; - *root = 0; - size_t rootLen = os_get_abs_path(rootDir.c_str(), root, sizeof(root)); + BPtr root = os_get_abs_path_ptr(rootDir.c_str()); - char absPath[512]; - *absPath = 0; - size_t len = os_get_abs_path((rootDir + path).c_str(), absPath, sizeof(absPath)); + BPtr absPath = os_get_abs_path_ptr((rootDir + path).c_str()); - if (len == 0) { + if (!absPath || !*absPath.Get()) { return path; } @@ -159,11 +155,11 @@ static string CheckPath(const string &path, const string &rootDir) return path; } - if (*(absPath + rootLen) != QDir::separator().toLatin1()) { + if (*(absPath + strlen(root)) != QDir::separator().toLatin1()) { return path; } - return absPath; + return string(absPath); } void TranslatePaths(Json &res, const string &rootDir) diff --git a/frontend/importers/xsplit.cpp b/frontend/importers/xsplit.cpp index f5bab6b04c8007..f88ad70b16abfc 100644 --- a/frontend/importers/xsplit.cpp +++ b/frontend/importers/xsplit.cpp @@ -503,10 +503,8 @@ OBSImporterFiles XSplitImporter::FindFiles() { OBSImporterFiles res; #ifdef _WIN32 - char dst[512]; - int found = os_get_program_data_path(dst, 512, "SplitMediaLabs\\XSplit\\Presentation2.0\\"); - - if (found == -1) { + BPtr dst = os_get_program_data_path_ptr("SplitMediaLabs\\XSplit\\Presentation2.0\\"); + if (!dst) { return res; } @@ -521,7 +519,7 @@ OBSImporterFiles XSplitImporter::FindFiles() } if (name == "Placements.bpres") { - string str = dst + name; + string str = dst.Get() + name; res.push_back(str); break; diff --git a/frontend/updater/updater.cpp b/frontend/updater/updater.cpp index fcb1248b2ddd6f..a0ba1e5027c878 100644 --- a/frontend/updater/updater.cpp +++ b/frontend/updater/updater.cpp @@ -1568,7 +1568,8 @@ static bool Update(wchar_t *cmdLine) continue; } - char outputPath[MAX_PATH]; + // Double buffer size to fit filename from wide char API + char outputPath[MAX_PATH * 2]; if (!WideToUTF8Buf(outputPath, update.outputPath.c_str())) { continue; } diff --git a/frontend/utility/platform-windows.cpp b/frontend/utility/platform-windows.cpp index 1cb1ef09db8350..1f075f2542c252 100644 --- a/frontend/utility/platform-windows.cpp +++ b/frontend/utility/platform-windows.cpp @@ -60,11 +60,11 @@ bool GetDataFilePath(const char *data, string &output) string GetDefaultVideoSavePath() { wchar_t path_utf16[MAX_PATH]; - char path_utf8[MAX_PATH] = {}; + BPtr path_utf8; SHGetFolderPathW(NULL, CSIDL_MYVIDEO, NULL, SHGFP_TYPE_CURRENT, path_utf16); - os_wcs_to_utf8(path_utf16, wcslen(path_utf16), path_utf8, MAX_PATH); + os_wcs_to_utf8_ptr(path_utf16, wcslen(path_utf16), &path_utf8); return string(path_utf8); } @@ -307,12 +307,9 @@ RunOnceMutex CheckIfAlreadyRunning(bool &already_running) if (!portable_mode) { name = "OBSStudioCore"; } else { - char path[500]; - char absPath[512]; - *path = 0; - *absPath = 0; - GetAppConfigPath(path, sizeof(path), ""); - os_get_abs_path(path, absPath, sizeof(absPath)); + BPtr path = GetAppConfigPathPtr(""); + BPtr absPath = os_get_abs_path_ptr(path); + name = "OBSStudioPortable"; name += absPath; } diff --git a/frontend/widgets/OBSBasic.cpp b/frontend/widgets/OBSBasic.cpp index b6f5445305f301..62a24b1cc6d8b3 100644 --- a/frontend/widgets/OBSBasic.cpp +++ b/frontend/widgets/OBSBasic.cpp @@ -144,20 +144,20 @@ static void AddExtraModulePaths() return; } - char base_module_dir[512]; + BPtr base_module_dir; #if defined(_WIN32) - int ret = GetProgramDataPath(base_module_dir, sizeof(base_module_dir), "obs-studio/plugins/%module%"); + base_module_dir = GetProgramDataPathPtr("obs-studio/plugins/%module%"); #elif defined(__APPLE__) - int ret = GetAppConfigPath(base_module_dir, sizeof(base_module_dir), "obs-studio/plugins/%module%.plugin"); + base_module_dir = GetAppConfigPathPtr("obs-studio/plugins/%module%.plugin"); #else - int ret = GetAppConfigPath(base_module_dir, sizeof(base_module_dir), "obs-studio/plugins/%module%"); + base_module_dir = GetAppConfigPathPtr("obs-studio/plugins/%module%"); #endif - if (ret <= 0) { + if (!base_module_dir || !*base_module_dir.Get()) { return; } - string path = base_module_dir; + string path(base_module_dir); #if defined(__APPLE__) /* User Application Support Search Path */ obs_add_module_path((path + "/Contents/MacOS").c_str(), (path + "/Contents/Resources").c_str()); diff --git a/frontend/widgets/OBSBasic_MainControls.cpp b/frontend/widgets/OBSBasic_MainControls.cpp index 40b3aef444b418..fc886eb31abf5e 100644 --- a/frontend/widgets/OBSBasic_MainControls.cpp +++ b/frontend/widgets/OBSBasic_MainControls.cpp @@ -260,12 +260,12 @@ void OBSBasic::on_actionAdvAudioProperties_triggered() static BPtr ReadLogFile(const char *subdir, const char *log) { - char logDir[512]; - if (GetAppConfigPath(logDir, sizeof(logDir), subdir) <= 0) { + BPtr logDir = GetAppConfigPathPtr(subdir); + if (!logDir || !*logDir.Get()) { return nullptr; } - string path = logDir; + string path(logDir); path += "/"; path += log; @@ -312,8 +312,8 @@ void OBSBasic::UploadLog(const char *subdir, const char *file, const LogUploadTy void OBSBasic::on_actionShowLogs_triggered() { - char logDir[512]; - if (GetAppConfigPath(logDir, sizeof(logDir), "obs-studio/logs") <= 0) { + BPtr logDir = GetAppConfigPathPtr("obs-studio/logs"); + if (!logDir || !*logDir.Get()) { return; } diff --git a/libobs/obs-win-crash-handler.c b/libobs/obs-win-crash-handler.c index 664a9c6eb12305..9f1e5cb99a7b84 100644 --- a/libobs/obs-win-crash-handler.c +++ b/libobs/obs-win-crash-handler.c @@ -212,8 +212,8 @@ static inline void init_cpu_info(struct exception_handler_data *data) static BOOL CALLBACK enum_all_modules(PCTSTR module_name, DWORD64 module_base, ULONG module_size, struct exception_handler_data *data) { - char name_utf8[MAX_PATH]; - os_wcs_to_utf8(module_name, 0, name_utf8, MAX_PATH); + char *name_utf8; + os_wcs_to_utf8_ptr(module_name, 0, &name_utf8); if (data->main_trace.instruction_ptr >= module_base && data->main_trace.instruction_ptr < module_base + module_size) { @@ -229,6 +229,7 @@ static BOOL CALLBACK enum_all_modules(PCTSTR module_name, DWORD64 module_base, U dstr_catf(&data->module_list, "%08" PRIX64 "-%08" PRIX64 " %s\r\n", module_base, module_base + module_size, name_utf8); #endif + bfree(name_utf8); return true; } @@ -271,14 +272,14 @@ static inline void write_header(struct exception_handler_data *data) struct module_info { DWORD64 addr; - char name_utf8[MAX_PATH]; + char name_utf8[MAX_PATH_UTF8]; }; static BOOL CALLBACK enum_module(PCTSTR module_name, DWORD64 module_base, ULONG module_size, struct module_info *info) { if (info->addr >= module_base && info->addr < module_base + module_size) { - os_wcs_to_utf8(module_name, 0, info->name_utf8, MAX_PATH); + os_wcs_to_utf8(module_name, 0, info->name_utf8, MAX_PATH_UTF8); strlwr(info->name_utf8); return false; } diff --git a/libobs/util/platform-nix.c b/libobs/util/platform-nix.c index 5648ca61b03a2b..d3e37a02486a63 100644 --- a/libobs/util/platform-nix.c +++ b/libobs/util/platform-nix.c @@ -403,21 +403,26 @@ size_t os_get_abs_path(const char *path, char *abspath, size_t size) char newpath[PATH_MAX]; int ret; - if (!abspath) - return 0; - if (!realpath(path, newpath)) return 0; + if (!abspath) { + return strlen(newpath); + } + ret = snprintf(abspath, min_size, "%s", newpath); return ret >= 0 ? ret : 0; } char *os_get_abs_path_ptr(const char *path) { - char *ptr = bmalloc(512); + size_t len = os_get_abs_path(path, NULL, 0); + if (!len) + return NULL; + + char* ptr = bmalloc(len + 1); - if (!os_get_abs_path(path, ptr, 512)) { + if (!os_get_abs_path(path, ptr, len + 1)) { bfree(ptr); ptr = NULL; } diff --git a/libobs/util/platform-windows.c b/libobs/util/platform-windows.c index df4efb7848dd27..fd5bfbd2b8b737 100644 --- a/libobs/util/platform-windows.c +++ b/libobs/util/platform-windows.c @@ -501,9 +501,6 @@ size_t os_get_abs_path(const char *path, char *abspath, size_t size) size_t out_len = 0; size_t len; - if (!abspath) - return 0; - len = os_utf8_to_wcs(path, 0, wpath, MAX_PATH); if (!len) return 0; @@ -515,9 +512,13 @@ size_t os_get_abs_path(const char *path, char *abspath, size_t size) char *os_get_abs_path_ptr(const char *path) { - char *ptr = bmalloc(MAX_PATH); + size_t len = os_get_abs_path(path, NULL, 0); + if (!len) + return NULL; + + char *ptr = bmalloc(len + 1); - if (!os_get_abs_path(path, ptr, MAX_PATH)) { + if (!os_get_abs_path(path, ptr, len + 1)) { bfree(ptr); ptr = NULL; } @@ -595,18 +596,21 @@ void os_closedir(os_dir_t *dir) int64_t os_get_free_space(const char *path) { ULARGE_INTEGER remainingSpace; - char abs_path[512]; - wchar_t w_abs_path[512]; + char* abs_path; + wchar_t* w_abs_path; + int64_t ret = -1; - if (os_get_abs_path(path, abs_path, 512) > 0) { - if (os_utf8_to_wcs(abs_path, 0, w_abs_path, 512) > 0) { + abs_path = os_get_abs_path_ptr(path); + if (abs_path) { + if (os_utf8_to_wcs_ptr(abs_path, 0, &w_abs_path) > 0) { BOOL success = GetDiskFreeSpaceExW(w_abs_path, (PULARGE_INTEGER)&remainingSpace, NULL, NULL); if (success) - return (int64_t)remainingSpace.QuadPart; + ret = (int64_t)remainingSpace.QuadPart; } + bfree(abs_path); } - return -1; + return ret; } static void make_globent(struct os_globent *ent, WIN32_FIND_DATA *wfd, const char *pattern) @@ -924,24 +928,26 @@ bool get_dll_ver(const wchar_t *lib, struct win_version_info *ver_info) BOOL success; LPVOID data; DWORD size; - char utf8_lib[512]; + char *utf8_lib; if (!ver_initialized && !initialize_version_functions()) return false; if (!ver_initialize_success) return false; - os_wcs_to_utf8(lib, 0, utf8_lib, sizeof(utf8_lib)); + os_wcs_to_utf8_ptr(lib, 0, &utf8_lib); size = get_file_version_info_size(lib, NULL); if (!size) { blog(LOG_ERROR, "Failed to get %s version info size", utf8_lib); + bfree(utf8_lib); return false; } data = bmalloc(size); if (!get_file_version_info(lib, 0, size, data)) { blog(LOG_ERROR, "Failed to get %s version info", utf8_lib); + bfree(utf8_lib); bfree(data); return false; } @@ -949,6 +955,7 @@ bool get_dll_ver(const wchar_t *lib, struct win_version_info *ver_info) success = ver_query_value(data, L"\\", (LPVOID *)&info, &len); if (!success || !info || !len) { blog(LOG_ERROR, "Failed to get %s version info value", utf8_lib); + bfree(utf8_lib); bfree(data); return false; } @@ -958,6 +965,7 @@ bool get_dll_ver(const wchar_t *lib, struct win_version_info *ver_info) ver_info->build = (int)HIWORD(info->dwFileVersionLS); ver_info->revis = (int)LOWORD(info->dwFileVersionLS); + bfree(utf8_lib); bfree(data); return true; } diff --git a/libobs/util/platform.c b/libobs/util/platform.c index 548afc03f73ad7..aa944396fe0e22 100644 --- a/libobs/util/platform.c +++ b/libobs/util/platform.c @@ -92,31 +92,32 @@ int64_t os_fgetsize(FILE *file) #ifdef _WIN32 int os_stat(const char *file, struct stat *st) { + int ret = -1; if (file) { - wchar_t w_file[512]; - size_t size = os_utf8_to_wcs(file, 0, w_file, sizeof(w_file)); - if (size > 0) { - struct _stat st_w32; - int ret = _wstat(w_file, &st_w32); - if (ret == 0) { - st->st_dev = st_w32.st_dev; - st->st_ino = st_w32.st_ino; - st->st_mode = st_w32.st_mode; - st->st_nlink = st_w32.st_nlink; - st->st_uid = st_w32.st_uid; - st->st_gid = st_w32.st_gid; - st->st_rdev = st_w32.st_rdev; - st->st_size = st_w32.st_size; - st->st_atime = st_w32.st_atime; - st->st_mtime = st_w32.st_mtime; - st->st_ctime = st_w32.st_ctime; - } - + wchar_t *w_file; + os_utf8_to_wcs_ptr(file, 0, &w_file); + if (!w_file || !*w_file) { return ret; } - } - return -1; + struct _stat st_w32; + ret = _wstat(w_file, &st_w32); + if (ret == 0) { + st->st_dev = st_w32.st_dev; + st->st_ino = st_w32.st_ino; + st->st_mode = st_w32.st_mode; + st->st_nlink = st_w32.st_nlink; + st->st_uid = st_w32.st_uid; + st->st_gid = st_w32.st_gid; + st->st_rdev = st_w32.st_rdev; + st->st_size = st_w32.st_size; + st->st_atime = st_w32.st_atime; + st->st_mtime = st_w32.st_mtime; + st->st_ctime = st_w32.st_ctime; + } + bfree(w_file); + } + return ret; } #endif diff --git a/libobs/util/platform.h b/libobs/util/platform.h index 592d9eca6e5c8c..33bed49bcc3245 100644 --- a/libobs/util/platform.h +++ b/libobs/util/platform.h @@ -18,6 +18,7 @@ #include #include +#include #include #include "c99defs.h" @@ -30,6 +31,27 @@ extern "C" { #endif +/* + * Windows max path is 260 chars/wchars depending on A/W api, + * Wide (UTF-16) paths are stored in UTF-8 internally, so double the buffer size + * unix file apis are UTF-8 based + */ +#ifdef _WIN32 + #define MAX_PATH_UTF8 (_MAX_PATH * 2) + #define MAX_FNAME_UTF8 (_MAX_FNAME * 2) +#else + #ifdef PATH_MAX + #define MAX_PATH_UTF8 ((PATH_MAX < 4096) ? PATH_MAX : 4096) + #else + #define MAX_PATH_UTF8 4096 + #endif + #ifdef NAME_MAX + #define MAX_FNAME_UTF8 ((NAME_MAX < 1024) ? NAME_MAX + 1 : 1024) + #else + #define MAX_FNAME_UTF8 1024 + #endif +#endif + EXPORT FILE *os_wfopen(const wchar_t *path, const char *mode); EXPORT FILE *os_fopen(const char *path, const char *mode); EXPORT int64_t os_fgetsize(FILE *file); @@ -121,7 +143,7 @@ struct os_dir; typedef struct os_dir os_dir_t; struct os_dirent { - char d_name[256]; + char d_name[MAX_FNAME_UTF8]; bool directory; }; diff --git a/plugins/nv-filters/nvafx-load.h b/plugins/nv-filters/nvafx-load.h index fde85a002aec51..1c96d0c8587def 100644 --- a/plugins/nv-filters/nvafx-load.h +++ b/plugins/nv-filters/nvafx-load.h @@ -219,22 +219,22 @@ void release_lib(void) } } -static inline bool nvafx_get_sdk_path(char *buffer, const size_t len) +static inline bool nvafx_get_sdk_path(wchar_t *buffer, const size_t len) { - DWORD ret = GetEnvironmentVariableA("NVAFX_SDK_DIR", buffer, (DWORD)len); + DWORD ret = GetEnvironmentVariableW(L"NVAFX_SDK_DIR", buffer, (DWORD)len); - if (!ret || ret >= len - 1) { - char path[MAX_PATH]; - if (!GetEnvironmentVariableA("ProgramFiles", path, MAX_PATH)) { + if (!ret || ret >= len) { + wchar_t path[MAX_PATH]; + if (!GetEnvironmentVariableW(L"ProgramFiles", path, MAX_PATH)) { buffer[0] = 0; return false; } - if (_snprintf_s(buffer, len, _TRUNCATE, "%s\\NVIDIA Corporation\\NVIDIA Audio Effects SDK", path) > 0) { - return true; + int r = _snwprintf_s(buffer, len, _TRUNCATE, L"%ls\\NVIDIA Corporation\\NVIDIA Audio Effects SDK", path); + if (r <= 0 || r >= len) { + buffer[0] = 0; + return false; } - - return false; } return true; @@ -242,19 +242,19 @@ static inline bool nvafx_get_sdk_path(char *buffer, const size_t len) static inline bool load_lib() { - char sdkPath[MAX_PATH]; - char effectsPath[MAX_PATH]; + wchar_t sdkPath[MAX_PATH]; + wchar_t effectsPath[MAX_PATH]; if (!nvafx_get_sdk_path(sdkPath, MAX_PATH)) { return false; } - if (_snprintf_s(effectsPath, _countof(effectsPath), _TRUNCATE, "%s\\NVAudioEffects.dll", sdkPath) == -1) { + if (_snwprintf_s(effectsPath, _countof(effectsPath), _TRUNCATE, L"%ls\\NVAudioEffects.dll", sdkPath) == -1) { return false; } nv_audiofx = - LoadLibraryExA(effectsPath, NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); + LoadLibraryExW(effectsPath, NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); return !!nv_audiofx; } @@ -269,14 +269,14 @@ static unsigned int get_lib_version(void) version_checked = true; - char sdkPath[MAX_PATH]; + wchar_t sdkPath[MAX_PATH]; wchar_t dllPath[MAX_PATH]; if (!nvafx_get_sdk_path(sdkPath, MAX_PATH)) { return version; } - if (_snwprintf_s(dllPath, _countof(dllPath), _TRUNCATE, L"%S\\NVAudioEffects.dll", sdkPath) == -1) { + if (_snwprintf_s(dllPath, _countof(dllPath), _TRUNCATE, L"%ls\\NVAudioEffects.dll", sdkPath) == -1) { return version; } diff --git a/plugins/nv-filters/nvidia-audiofx-filter.c b/plugins/nv-filters/nvidia-audiofx-filter.c index a9a776d13a46ba..d4709c53a39be6 100644 --- a/plugins/nv-filters/nvidia-audiofx-filter.c +++ b/plugins/nv-filters/nvidia-audiofx-filter.c @@ -583,18 +583,17 @@ static void *nvidia_audio_create(obs_data_t *settings, obs_source_t *filter) ng->context = filter; - char sdk_path[MAX_PATH]; + wchar_t sdk_path[MAX_PATH]; /* find SDK */ - if (!nvafx_get_sdk_path(sdk_path, sizeof(sdk_path))) { + if (!nvafx_get_sdk_path(sdk_path, _countof(sdk_path))) { ng->nvidia_sdk_dir_found = false; do_log(LOG_ERROR, "NVAFX redist is not installed."); nvidia_audio_destroy(ng); return NULL; } else { - size_t size = sizeof(sdk_path) + 1; - ng->sdk_path = bmalloc(size); - strcpy(ng->sdk_path, sdk_path); + + os_wcs_to_utf8_ptr(sdk_path, 0, &ng->sdk_path); ng->nvidia_sdk_dir_found = true; ng->nvafx_initialized = false; ng->nvafx_loading = false; @@ -602,7 +601,7 @@ static void *nvidia_audio_create(obs_data_t *settings, obs_source_t *filter) pthread_mutex_init(&ng->nvafx_mutex, NULL); - info("NVAFX SDK redist path was found here %s", sdk_path); + info("NVAFX SDK redist path was found here %s", ng->sdk_path); // set FX const char *method = obs_data_get_string(settings, S_METHOD); set_nv_model(ng, method); diff --git a/plugins/nv-filters/nvidia-videofx-filter.c b/plugins/nv-filters/nvidia-videofx-filter.c index 15341927fe7383..d242dd80a8ae9c 100644 --- a/plugins/nv-filters/nvidia-videofx-filter.c +++ b/plugins/nv-filters/nvidia-videofx-filter.c @@ -261,13 +261,20 @@ static bool nvvfx_filter_create_internal(struct nvvfx_data *filter) log_nverror_destroy(filter, vfxErr); if (id == S_FX_AIGS || id == S_FX_BG_BLUR) { - char buffer[MAX_PATH]; - char modelDir[MAX_PATH]; + wchar_t buffer[MAX_PATH]; + wchar_t modelDir[MAX_PATH]; nvvfx_get_sdk_path(buffer, MAX_PATH); - size_t max_len = sizeof(buffer) / sizeof(char); - snprintf(modelDir, max_len, "%s\\models", buffer); - vfxErr = NvVFX_SetString(filter->handle, NVVFX_MODEL_DIRECTORY, modelDir); + int ret = _snwprintf(modelDir, _countof(buffer), L"%ls\\models", buffer); + if (ret < 0 || ret >= MAX_PATH) { + return false; + } + + char *modelDirUtf8; + os_wcs_to_utf8_ptr(modelDir, wcslen(modelDir), &modelDirUtf8); + + vfxErr = NvVFX_SetString(filter->handle, NVVFX_MODEL_DIRECTORY, modelDirUtf8); vfxErr = NvVFX_SetCudaStream(filter->handle, NVVFX_CUDA_STREAM, filter->stream); + bfree(modelDirUtf8); if (NVCV_SUCCESS != vfxErr) log_nverror_destroy(filter, vfxErr); } diff --git a/plugins/nv-filters/nvvfx-load.h b/plugins/nv-filters/nvvfx-load.h index e27ad1e62afda4..0412ee9434480d 100644 --- a/plugins/nv-filters/nvvfx-load.h +++ b/plugins/nv-filters/nvvfx-load.h @@ -667,22 +667,22 @@ static inline void release_nv_vfx() } } -static inline bool nvvfx_get_sdk_path(char *buffer, const size_t len) +static inline bool nvvfx_get_sdk_path(wchar_t *buffer, const size_t len) { - DWORD ret = GetEnvironmentVariableA("NV_VIDEO_EFFECTS_PATH", buffer, (DWORD)len); + DWORD ret = GetEnvironmentVariableW(L"NV_VIDEO_EFFECTS_PATH", buffer, (DWORD)len); - if (!ret || ret >= len - 1) { - char path[MAX_PATH]; - if (!GetEnvironmentVariableA("ProgramFiles", path, MAX_PATH)) { + if (!ret || ret >= len) { + wchar_t path[MAX_PATH]; + if (!GetEnvironmentVariableW(L"ProgramFiles", path, MAX_PATH)) { buffer[0] = 0; return false; } - if (_snprintf_s(buffer, len, _TRUNCATE, "%s\\NVIDIA Corporation\\NVIDIA Video Effects", path) > 0) { - return true; + int r = _snwprintf_s(buffer, len, _TRUNCATE, L"%ls\\NVIDIA Corporation\\NVIDIA Video Effects", path); + if (r < 0 || r >= len) { + buffer[0] = 0; + return false; } - - return false; } return true; @@ -690,27 +690,30 @@ static inline bool nvvfx_get_sdk_path(char *buffer, const size_t len) static inline bool load_nv_vfx_libs() { - char sdkPath[MAX_PATH]; - char effectsPath[MAX_PATH]; - char imagePath[MAX_PATH]; + wchar_t sdkPath[MAX_PATH]; + wchar_t effectsPath[MAX_PATH]; + wchar_t imagePath[MAX_PATH]; + int ret; if (!nvvfx_get_sdk_path(sdkPath, MAX_PATH)) { return false; } - if (_snprintf_s(effectsPath, _countof(effectsPath), _TRUNCATE, "%s\\NVVideoEffects.dll", sdkPath) == -1) { + ret = _snwprintf_s(effectsPath, _countof(effectsPath), _TRUNCATE, L"%ls\\NVVideoEffects.dll", sdkPath); + if (ret < 0 || ret >= MAX_PATH) { return false; } - if (_snprintf_s(imagePath, _countof(imagePath), _TRUNCATE, "%s\\NVCVImage.dll", sdkPath) == -1) { + ret = _snwprintf_s(imagePath, _countof(imagePath), _TRUNCATE, L"%ls\\NVCVImage.dll", sdkPath); + if (ret < 0 || ret >= MAX_PATH) { return false; } nv_videofx = - LoadLibraryExA(effectsPath, NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); + LoadLibraryExW(effectsPath, NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); nv_cvimage = - LoadLibraryExA(imagePath, NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); + LoadLibraryExW(imagePath, NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); return !!nv_videofx && !!nv_cvimage; } @@ -725,14 +728,14 @@ static unsigned int get_lib_version(void) version_checked = true; - char sdkPath[MAX_PATH]; + wchar_t sdkPath[MAX_PATH]; wchar_t dllPath[MAX_PATH]; if (!nvvfx_get_sdk_path(sdkPath, MAX_PATH)) { return version; } - if (_snwprintf_s(dllPath, _countof(dllPath), _TRUNCATE, L"%S\\NVVideoEffects.dll", sdkPath) == -1) { + if (_snwprintf_s(dllPath, _countof(dllPath), _TRUNCATE, L"%ls\\NVVideoEffects.dll", sdkPath) == -1) { return version; } diff --git a/plugins/text-freetype2/find-font-windows.c b/plugins/text-freetype2/find-font-windows.c index 6c9fcd297b26ec..e798a6005fc062 100644 --- a/plugins/text-freetype2/find-font-windows.c +++ b/plugins/text-freetype2/find-font-windows.c @@ -170,74 +170,79 @@ char *sfnt_name_to_utf8(FT_SfntName *sfnt_name) uint32_t get_font_checksum(void) { uint32_t checksum = 0; - struct dstr path = {0}; + wchar_t path[MAX_PATH]; + wchar_t search[MAX_PATH]; HANDLE handle; - WIN32_FIND_DATAA wfd; + WIN32_FIND_DATAW wfd; - dstr_reserve(&path, MAX_PATH); - - HRESULT res = SHGetFolderPathA(NULL, CSIDL_FONTS, NULL, SHGFP_TYPE_CURRENT, path.array); + HRESULT res = SHGetFolderPathW(NULL, CSIDL_FONTS, NULL, SHGFP_TYPE_CURRENT, path); if (res != S_OK) { blog(LOG_WARNING, "Error finding windows font folder"); return 0; } - path.len = strlen(path.array); - dstr_cat(&path, "\\*.*"); - - handle = FindFirstFileA(path.array, &wfd); - if (handle == INVALID_HANDLE_VALUE) - goto free_string; + int ret = _snwprintf(search, MAX_PATH, L"%ls\\*.*", path); + if (ret < 0 || ret >= MAX_PATH) { + return checksum; + } - dstr_resize(&path, path.len - 4); + handle = FindFirstFileW(search, &wfd); + if (handle == INVALID_HANDLE_VALUE) { + return checksum; + } do { checksum = calc_crc32(checksum, &wfd.ftLastWriteTime, sizeof(FILETIME)); - checksum = calc_crc32(checksum, wfd.cFileName, strlen(wfd.cFileName)); - } while (FindNextFileA(handle, &wfd)); + checksum = calc_crc32(checksum, wfd.cFileName, wcslen(wfd.cFileName) * sizeof(wchar_t)); + } while (FindNextFileW(handle, &wfd)); FindClose(handle); - -free_string: - dstr_free(&path); return checksum; } void load_os_font_list(void) { - struct dstr path = {0}; + wchar_t path[MAX_PATH]; + wchar_t search[MAX_PATH]; HANDLE handle; - WIN32_FIND_DATAA wfd; + WIN32_FIND_DATAW wfd; + char *path_utf8; - dstr_reserve(&path, MAX_PATH); - - HRESULT res = SHGetFolderPathA(NULL, CSIDL_FONTS, NULL, SHGFP_TYPE_CURRENT, path.array); + HRESULT res = SHGetFolderPathW(NULL, CSIDL_FONTS, NULL, SHGFP_TYPE_CURRENT, path); if (res != S_OK) { blog(LOG_WARNING, "Error finding windows font folder"); return; } - path.len = strlen(path.array); - dstr_cat(&path, "\\*.*"); + int ret = _snwprintf(search, MAX_PATH, L"%ls\\*.*", path); + if (ret < 0 || ret >= MAX_PATH) { + return; + } - handle = FindFirstFileA(path.array, &wfd); + handle = FindFirstFileW(search, &wfd); if (handle == INVALID_HANDLE_VALUE) - goto free_string; + return; - dstr_resize(&path, path.len - 4); + path_utf8 = wide_to_utf8(path, MAX_PATH); do { - struct dstr full_path = {0}; FT_Face face; FT_Long idx = 0; FT_Long max_faces = 1; + char *filename; if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; - dstr_copy_dstr(&full_path, &path); + filename = wide_to_utf8(wfd.cFileName, MAX_PATH); + if (!filename) + continue; + + struct dstr full_path = {0}; + dstr_copy(&full_path, path_utf8); dstr_cat(&full_path, "\\"); - dstr_cat(&full_path, wfd.cFileName); + dstr_cat(&full_path, filename); + bfree(filename); while (idx < max_faces) { FT_Error ret = FT_New_Face(ft2_lib, full_path.array, idx, &face); @@ -250,12 +255,10 @@ void load_os_font_list(void) } dstr_free(&full_path); - } while (FindNextFileA(handle, &wfd)); + } while (FindNextFileW(handle, &wfd)); + bfree(path_utf8); FindClose(handle); save_font_list(); - -free_string: - dstr_free(&path); } diff --git a/plugins/win-capture/graphics-hook/d3d12-capture.cpp b/plugins/win-capture/graphics-hook/d3d12-capture.cpp index 991c4c6a29b417..a06a626182b9de 100644 --- a/plugins/win-capture/graphics-hook/d3d12-capture.cpp +++ b/plugins/win-capture/graphics-hook/d3d12-capture.cpp @@ -123,7 +123,7 @@ static bool d3d12_init_11on12(ID3D12Device *device) static bool initialized_func = false; if (!initialized_11 && !d3d11) { - d3d11 = load_system_library("d3d11.dll"); + d3d11 = load_system_library(L"d3d11.dll"); if (!d3d11) { hlog("d3d12_init_11on12: failed to load d3d11"); } @@ -403,7 +403,7 @@ static bool manually_get_d3d12_addrs(HMODULE d3d12_module, PFN_ExecuteCommandLis bool hook_d3d12(void) { - HMODULE d3d12_module = get_system_module("d3d12.dll"); + HMODULE d3d12_module = get_system_module(L"d3d12.dll"); if (!d3d12_module) { hlog_verbose("Failed to find d3d12.dll. Skipping hook attempt."); return false; diff --git a/plugins/win-capture/graphics-hook/d3d8-capture.cpp b/plugins/win-capture/graphics-hook/d3d8-capture.cpp index b9ac4916736a07..73c75ad4e951a9 100644 --- a/plugins/win-capture/graphics-hook/d3d8-capture.cpp +++ b/plugins/win-capture/graphics-hook/d3d8-capture.cpp @@ -174,7 +174,7 @@ static void d3d8_free() static void d3d8_init(IDirect3DDevice8 *device) { - data.d3d8 = get_system_module("d3d8.dll"); + data.d3d8 = get_system_module(L"d3d8.dll"); if (!d3d8_init_format_backbuffer(device)) { return; @@ -349,7 +349,7 @@ static bool manually_get_d3d8_present_addr(HMODULE d3d8_module, void **present_a bool hook_d3d8(void) { - HMODULE d3d8_module = get_system_module("d3d8.dll"); + HMODULE d3d8_module = get_system_module(L"d3d8.dll"); uint32_t d3d8_size; void *present_addr = nullptr; diff --git a/plugins/win-capture/graphics-hook/d3d9-capture.cpp b/plugins/win-capture/graphics-hook/d3d9-capture.cpp index b9b72b8bb933de..eb5f480b59cf50 100644 --- a/plugins/win-capture/graphics-hook/d3d9-capture.cpp +++ b/plugins/win-capture/graphics-hook/d3d9-capture.cpp @@ -121,13 +121,13 @@ static inline bool shex_init_d3d11() HMODULE dxgi; HRESULT hr; - d3d11 = load_system_library("d3d11.dll"); + d3d11 = load_system_library(L"d3d11.dll"); if (!d3d11) { hlog("d3d9_init: Failed to load D3D11"); return false; } - dxgi = load_system_library("dxgi.dll"); + dxgi = load_system_library(L"dxgi.dll"); if (!dxgi) { hlog("d3d9_init: Failed to load DXGI"); return false; @@ -429,7 +429,7 @@ static void d3d9_init(IDirect3DDevice9 *device) HWND window = nullptr; HRESULT hr; - data.d3d9 = get_system_module("d3d9.dll"); + data.d3d9 = get_system_module(L"d3d9.dll"); data.device = device; hr = device->QueryInterface(__uuidof(IDirect3DDevice9Ex), (void **)&d3d9ex); @@ -465,7 +465,7 @@ static inline HRESULT get_backbuffer(IDirect3DDevice9 *device, IDirect3DSurface9 static bool checked_exceptions = false; if (!checked_exceptions) { - if (_strcmpi(get_process_name(), "hotd_ng.exe") == 0) { + if (_wcsicmp(get_process_name(), L"hotd_ng.exe") == 0) { use_backbuffer = true; } checked_exceptions = true; @@ -792,7 +792,7 @@ static bool manually_get_d3d9_addrs(HMODULE d3d9_module, void **present_addr, vo bool hook_d3d9(void) { - HMODULE d3d9_module = get_system_module("d3d9.dll"); + HMODULE d3d9_module = get_system_module(L"d3d9.dll"); uint32_t d3d9_size; void *present_addr = nullptr; void *present_ex_addr = nullptr; diff --git a/plugins/win-capture/graphics-hook/dxgi-capture.cpp b/plugins/win-capture/graphics-hook/dxgi-capture.cpp index 28208eb8884545..b3f92d35bb824c 100644 --- a/plugins/win-capture/graphics-hook/dxgi-capture.cpp +++ b/plugins/win-capture/graphics-hook/dxgi-capture.cpp @@ -305,7 +305,7 @@ static HRESULT STDMETHODCALLTYPE hook_present1(IDXGISwapChain1 *swap, UINT sync_ bool hook_dxgi(void) { - HMODULE dxgi_module = get_system_module("dxgi.dll"); + HMODULE dxgi_module = get_system_module(L"dxgi.dll"); if (!dxgi_module) { hlog_verbose("Failed to find dxgi.dll. Skipping hook attempt."); return false; diff --git a/plugins/win-capture/graphics-hook/gl-capture.c b/plugins/win-capture/graphics-hook/gl-capture.c index 61d4efad9844d3..5c3a61d233f83f 100644 --- a/plugins/win-capture/graphics-hook/gl-capture.c +++ b/plugins/win-capture/graphics-hook/gl-capture.c @@ -266,13 +266,13 @@ static inline bool gl_shtex_init_d3d11(void) IDXGIAdapter *adapter; HRESULT hr; - HMODULE d3d11 = load_system_library("d3d11.dll"); + HMODULE d3d11 = load_system_library(L"d3d11.dll"); if (!d3d11) { hlog("gl_shtex_init_d3d11: failed to load D3D11.dll: %d", GetLastError()); return false; } - HMODULE dxgi = load_system_library("dxgi.dll"); + HMODULE dxgi = load_system_library(L"dxgi.dll"); if (!dxgi) { hlog("gl_shtex_init_d3d11: failed to load DXGI.dll: %d", GetLastError()); return false; @@ -563,7 +563,7 @@ static void gl_copy_backbuffer(GLuint dst) glReadBuffer(GL_BACK); /* darkest dungeon fix */ - darkest_dungeon_fix = glGetError() == GL_INVALID_OPERATION && _strcmpi(process_name, "Darkest.exe") == 0; + darkest_dungeon_fix = glGetError() == GL_INVALID_OPERATION && _wcsicmp(process_name, L"Darkest.exe") == 0; glDrawBuffer(GL_COLOR_ATTACHMENT0); if (gl_error("gl_copy_backbuffer", "failed to set draw buffer")) { @@ -820,16 +820,18 @@ bool hook_gl(void) void *wgl_slb_proc; void *wgl_sb_proc; - gl = get_system_module("opengl32.dll"); + gl = get_system_module(L"opengl32.dll"); if (!gl) { return false; } /* "life is feudal: your own" somehow uses both opengl and directx at * the same time, so blacklist it from capturing opengl */ - const char *process_name = get_process_name(); - if (_strcmpi(process_name, "yo_cm_client.exe") == 0 || _strcmpi(process_name, "cm_client.exe") == 0) { - hlog("Ignoring opengl for game: %s", process_name); + const wchar_t *process_name = get_process_name(); + if (_wcsicmp(process_name, L"yo_cm_client.exe") == 0 || _wcsicmp(process_name, L"cm_client.exe") == 0) { + char *process_name_utf8 = wide_to_utf8_ptr(process_name); + hlog("Ignoring opengl for game: %s", process_name_utf8 ? process_name_utf8 : ""); + free(process_name_utf8); return true; } diff --git a/plugins/win-capture/graphics-hook/graphics-hook.c b/plugins/win-capture/graphics-hook/graphics-hook.c index b6b3e9ec1f62dc..e4c0896a9c307e 100644 --- a/plugins/win-capture/graphics-hook/graphics-hook.c +++ b/plugins/win-capture/graphics-hook/graphics-hook.c @@ -45,8 +45,8 @@ static HINSTANCE dll_inst = NULL; static volatile bool stop_loop = false; static HANDLE dup_hook_mutex = NULL; static HANDLE capture_thread = NULL; -char system_path[MAX_PATH] = {0}; -char process_name[MAX_PATH] = {0}; +wchar_t system_path[MAX_PATH] = {0}; +wchar_t process_name[MAX_PATH] = {0}; wchar_t keepalive_name[64] = {0}; HWND dummy_window = NULL; @@ -147,7 +147,7 @@ static inline bool init_mutexes(void) static inline bool init_system_path(void) { - UINT ret = GetSystemDirectoryA(system_path, MAX_PATH); + UINT ret = GetSystemDirectoryW(system_path, MAX_PATH); if (!ret) { hlog("Failed to get windows system path: %lu", GetLastError()); return false; @@ -158,10 +158,12 @@ static inline bool init_system_path(void) static inline void log_current_process(void) { - DWORD len = GetModuleBaseNameA(GetCurrentProcess(), NULL, process_name, MAX_PATH); + DWORD len = GetModuleBaseNameW(GetCurrentProcess(), NULL, process_name, MAX_PATH); if (len > 0) { process_name[len] = 0; - hlog("graphics-hook.dll loaded against process: %s", process_name); + char *process_name_utf8 = wide_to_utf8_ptr(process_name); + hlog("graphics-hook.dll loaded against process: %s", process_name_utf8 ? process_name_utf8 : ""); + free(process_name_utf8); } else { hlog("graphics-hook.dll loaded"); } diff --git a/plugins/win-capture/graphics-hook/graphics-hook.h b/plugins/win-capture/graphics-hook/graphics-hook.h index 1958ae3bb6f391..e1bb0f942e7cc9 100644 --- a/plugins/win-capture/graphics-hook/graphics-hook.h +++ b/plugins/win-capture/graphics-hook/graphics-hook.h @@ -32,9 +32,9 @@ extern "C" { extern void hlog(const char *format, ...); extern void hlog_hr(const char *text, HRESULT hr); -static inline const char *get_process_name(void); -static inline HMODULE get_system_module(const char *module); -static inline HMODULE load_system_library(const char *module); +static inline const wchar_t *get_process_name(void); +static inline HMODULE get_system_module(const wchar_t *module); +static inline HMODULE load_system_library(const wchar_t *module); extern uint64_t os_gettime_ns(void); #define flog(format, ...) hlog("%s: " format, __FUNCTION__, ##__VA_ARGS__) @@ -106,25 +106,43 @@ extern HANDLE signal_stop; extern HANDLE signal_ready; extern HANDLE signal_exit; extern HANDLE tex_mutexes[2]; -extern char system_path[MAX_PATH]; -extern char process_name[MAX_PATH]; +extern wchar_t system_path[MAX_PATH]; +extern wchar_t process_name[MAX_PATH]; extern wchar_t keepalive_name[64]; extern HWND dummy_window; extern volatile bool active; -static inline const char *get_process_name(void) +static inline char *wide_to_utf8_ptr(const wchar_t* wstr) +{ + if (!wstr) + return NULL; + + int wlen = (int)wcslen(wstr); + int size = WideCharToMultiByte(CP_UTF8, 0, wstr, wlen + 1, NULL, 0, NULL, NULL); + if (size <= 0) + return NULL; + + char *str = (char *)malloc((size_t)size); + if (!str) + return NULL; + + WideCharToMultiByte(CP_UTF8, 0, wstr, wlen + 1, str, size, NULL, NULL); + return str; +} + +static inline const wchar_t *get_process_name(void) { return process_name; } -static inline HMODULE get_system_module(const char *module) +static inline HMODULE get_system_module(const wchar_t *module) { - char base_path[MAX_PATH]; + wchar_t base_path[MAX_PATH]; - strcpy(base_path, system_path); - strcat(base_path, "\\"); - strcat(base_path, module); - return GetModuleHandleA(base_path); + wcscpy(base_path, system_path); + wcscat(base_path, L"\\"); + wcscat(base_path, module); + return GetModuleHandleW(base_path); } static inline uint32_t module_size(HMODULE module) @@ -134,20 +152,20 @@ static inline uint32_t module_size(HMODULE module) return success ? info.SizeOfImage : 0; } -static inline HMODULE load_system_library(const char *name) +static inline HMODULE load_system_library(const wchar_t *name) { - char base_path[MAX_PATH]; + wchar_t base_path[MAX_PATH]; HMODULE module; - strcpy(base_path, system_path); - strcat(base_path, "\\"); - strcat(base_path, name); + wcscpy(base_path, system_path); + wcscat(base_path, L"\\"); + wcscat(base_path, name); - module = GetModuleHandleA(base_path); + module = GetModuleHandleW(base_path); if (module) return module; - return LoadLibraryA(base_path); + return LoadLibraryW(base_path); } static inline bool capture_alive(void) diff --git a/plugins/win-capture/graphics-hook/vulkan-capture.c b/plugins/win-capture/graphics-hook/vulkan-capture.c index e1eded5e3e4259..53fa9b92c807f1 100644 --- a/plugins/win-capture/graphics-hook/vulkan-capture.c +++ b/plugins/win-capture/graphics-hook/vulkan-capture.c @@ -575,13 +575,13 @@ static inline bool vk_shtex_init_d3d11(struct vk_data *data) IDXGIAdapter1 *adapter; HRESULT hr; - HMODULE d3d11 = load_system_library("d3d11.dll"); + HMODULE d3d11 = load_system_library(L"d3d11.dll"); if (!d3d11) { flog("failed to load d3d11: %d", GetLastError()); return false; } - HMODULE dxgi = load_system_library("dxgi.dll"); + HMODULE dxgi = load_system_library(L"dxgi.dll"); if (!dxgi) { flog("failed to load dxgi: %d", GetLastError()); return false;