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; }