From 9565675488c51133e85627e5e610bf631eca6289 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Sat, 23 Dec 2023 18:46:54 +0100 Subject: [PATCH] various: use correct PATH_MAX for win32 In commit c09245cdf2491211f3e0bfe47f28cc0e0a2e05c8 long-path support was enabled for mpv without actually making sure that there was no code left that used the old limit (260 Unicode chars) for buffer sizes. This commit fixes all but one case. --- audio/out/ao_wasapi_utils.c | 5 +++-- osdep/io.h | 10 ++++++++++ osdep/path-uwp.c | 10 +++++++--- osdep/path-win.c | 11 +++++------ osdep/win32-console-wrapper.c | 8 ++++++-- video/out/w32_common.c | 6 ++++-- 6 files changed, 35 insertions(+), 15 deletions(-) diff --git a/audio/out/ao_wasapi_utils.c b/audio/out/ao_wasapi_utils.c index 8578b8a863..7e85f75eab 100644 --- a/audio/out/ao_wasapi_utils.c +++ b/audio/out/ao_wasapi_utils.c @@ -576,9 +576,10 @@ static void init_session_display(struct wasapi_state *state, const char *name) { (void **)&state->pSessionControl); EXIT_ON_ERROR(hr); - wchar_t path[MAX_PATH] = {0}; - GetModuleFileNameW(NULL, path, MAX_PATH); + wchar_t *path = talloc_array(NULL, wchar_t, MP_PATH_MAX); + GetModuleFileNameW(NULL, path, MP_PATH_MAX); hr = IAudioSessionControl_SetIconPath(state->pSessionControl, path, NULL); + talloc_free(path); if (FAILED(hr)) { // don't goto exit_label here since SetDisplayName might still work MP_WARN(state, "Error setting audio session icon: %s\n", diff --git a/osdep/io.h b/osdep/io.h index ca07bdbfb3..0a0d01eb05 100644 --- a/osdep/io.h +++ b/osdep/io.h @@ -80,9 +80,19 @@ int mp_make_wakeup_pipe(int pipes[2]); void mp_flush_wakeup_pipe(int pipe_end); #ifdef _WIN32 + #include wchar_t *mp_from_utf8(void *talloc_ctx, const char *s); char *mp_to_utf8(void *talloc_ctx, const wchar_t *s); + +// Use this in win32-specific code rather than PATH_MAX or MAX_PATH. +// This is necessary because we declare long-path aware support which raises +// the effective limit without affecting any defines. +// The actual limit is 32767 but there's a few edge cases that reduce +// it. So pick this nice round number. +// Note that this is wchars, not chars. +#define MP_PATH_MAX (32000) + #endif #ifdef __CYGWIN__ diff --git a/osdep/path-uwp.c b/osdep/path-uwp.c index 7eafb03a98..e21c9d1084 100644 --- a/osdep/path-uwp.c +++ b/osdep/path-uwp.c @@ -27,9 +27,13 @@ WINBASEAPI DWORD WINAPI GetCurrentDirectoryW(DWORD nBufferLength, LPWSTR lpBuffe const char *mp_get_platform_path_uwp(void *talloc_ctx, const char *type) { if (strcmp(type, "home") == 0) { - wchar_t homeDir[_MAX_PATH]; - if (GetCurrentDirectoryW(_MAX_PATH, homeDir) != 0) - return mp_to_utf8(talloc_ctx, homeDir); + DWORD count = GetCurrentDirectoryW(0, NULL); + wchar_t *home_dir = talloc_array(NULL, wchar_t, count); + if (GetCurrentDirectoryW(count, home_dir) != 0) { + char *ret = mp_to_utf8(talloc_ctx, home_dir); + talloc_free(home_dir); + return ret; + } } return NULL; } diff --git a/osdep/path-win.c b/osdep/path-win.c index bddf5a5e19..3b104cac03 100644 --- a/osdep/path-win.c +++ b/osdep/path-win.c @@ -24,17 +24,15 @@ #include "osdep/path.h" #include "osdep/threads.h" -// Warning: do not use PATH_MAX. Cygwin messed it up. - static mp_once path_init_once = MP_STATIC_ONCE_INITIALIZER; static char *portable_path; static char *mp_get_win_exe_dir(void *talloc_ctx) { - wchar_t w_exedir[MAX_PATH + 1] = {0}; + wchar_t *w_exedir = talloc_array(NULL, wchar_t, MP_PATH_MAX); - int len = (int)GetModuleFileNameW(NULL, w_exedir, MAX_PATH); + int len = (int)GetModuleFileNameW(NULL, w_exedir, MP_PATH_MAX); int imax = 0; for (int i = 0; i < len; i++) { if (w_exedir[i] == '\\') { @@ -42,10 +40,11 @@ static char *mp_get_win_exe_dir(void *talloc_ctx) imax = i; } } - w_exedir[imax] = '\0'; - return mp_to_utf8(talloc_ctx, w_exedir); + char *ret = mp_to_utf8(talloc_ctx, w_exedir); + talloc_free(w_exedir); + return ret; } static char *mp_get_win_exe_subdir(void *ta_ctx, const char *name) diff --git a/osdep/win32-console-wrapper.c b/osdep/win32-console-wrapper.c index 4e74daca47..787abafb23 100644 --- a/osdep/win32-console-wrapper.c +++ b/osdep/win32-console-wrapper.c @@ -19,6 +19,9 @@ #include #include +// copied from osdep/io.h since this file is standalone +#define MP_PATH_MAX (32000) + int wmain(int argc, wchar_t **argv, wchar_t **envp); static void cr_perror(const wchar_t *prefix) @@ -75,10 +78,11 @@ static int cr_runproc(wchar_t *name, wchar_t *cmdline) int wmain(int argc, wchar_t **argv, wchar_t **envp) { wchar_t *cmd; - wchar_t exe[MAX_PATH]; + wchar_t *exe; cmd = GetCommandLineW(); - GetModuleFileNameW(NULL, exe, MAX_PATH); + exe = LocalAlloc(LPTR, MP_PATH_MAX * sizeof(wchar_t)); + GetModuleFileNameW(NULL, exe, MP_PATH_MAX); wcscpy(wcsrchr(exe, '.') + 1, L"exe"); // Set an environment variable so the child process can tell whether it diff --git a/video/out/w32_common.c b/video/out/w32_common.c index c7b34d36f7..e15ead8f68 100644 --- a/video/out/w32_common.c +++ b/video/out/w32_common.c @@ -578,18 +578,20 @@ static double get_refresh_rate_from_gdi(const wchar_t *device) static char *get_color_profile(void *ctx, const wchar_t *device) { char *name = NULL; + wchar_t *wname = NULL; HDC ic = CreateICW(device, NULL, NULL, NULL); if (!ic) goto done; - wchar_t wname[MAX_PATH + 1]; - if (!GetICMProfileW(ic, &(DWORD){ MAX_PATH }, wname)) + wname = talloc_array(NULL, wchar_t, MP_PATH_MAX); + if (!GetICMProfileW(ic, &(DWORD){ MP_PATH_MAX - 1 }, wname)) goto done; name = mp_to_utf8(ctx, wname); done: if (ic) DeleteDC(ic); + talloc_free(wname); return name; }