Re: [FFmpeg-devel] [PATCH v2] Long path support for Windows (fixes #8885)

2022-02-16 Thread nil-admirari
ANSI functions do not support long paths, so I had to change
LoadLibraryExA to LoadLibraryExW.in compat/w32dlfcn.h as well.

I cannot find other uses of WinAPI functions ending with ..A(.
Looks like FFmpeg doesn't use ANSI functions anywhere else,
but the codebase is huge, so who knows.

Previous patch generated a warning: The first line of the commit message must 
start with a context...: 
https://patchwork.ffmpeg.org/project/ffmpeg/patch/20220214095146.13432-1-nil-admir...@mailo.com/.
Patch affected multiple files, so in order to specify the context the patch had 
to be split into pieces.

A new version of the patch is at 
https://ffmpeg.org/pipermail/ffmpeg-devel/2022-February/293106.html.



___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2] Long path support for Windows (fixes #8885)

2022-02-14 Thread nihil-admirari
From: nihil-admirari <50202386+nihil-admir...@users.noreply.github.com>

Long path support is enabled by adding a manifest to all of fftools.
MAX_PATH-sized buffers are replaced with dynamically sized ones.
---
 compat/w32dlfcn.h| 61 +++-
 fftools/Makefile |  5 +++
 fftools/cmdutils.c   | 31 
 fftools/long_paths_utf8.manifest | 12 +++
 fftools/long_paths_utf8.rc   |  3 ++
 libavformat/avisynth.c   | 10 +++---
 libavutil/wchar_filename.h   | 37 +++
 7 files changed, 139 insertions(+), 20 deletions(-)
 create mode 100644 fftools/long_paths_utf8.manifest
 create mode 100644 fftools/long_paths_utf8.rc

diff --git a/compat/w32dlfcn.h b/compat/w32dlfcn.h
index 52a94ef..ba2330a 100644
--- a/compat/w32dlfcn.h
+++ b/compat/w32dlfcn.h
@@ -25,6 +25,30 @@
 #if (_WIN32_WINNT < 0x0602) || HAVE_WINRT
 #include "libavutil/wchar_filename.h"
 #endif
+
+static inline wchar_t *get_module_filename(const HMODULE module)
+{
+wchar_t *path = NULL;
+int path_size = 0, path_len = 0;
+
+do {
+path_size = path_size ? 1.5 * path_size : MAX_PATH;
+wchar_t *new_path = av_realloc_array(path, path_size, sizeof *path);
+if (!new_path) {
+av_free(path);
+return NULL;
+}
+path = new_path;
+path_len = GetModuleFileNameW(module, path, path_size);
+} while (path_len && path_size <= 32768 && path_size <= path_len);
+
+if (!path_len) {
+av_free(path);
+return NULL;
+}
+return path;
+}
+
 /**
  * Safe function used to open dynamic libs. This attempts to improve program 
security
  * by removing the current directory from the dll search path. Only dll's 
found in the
@@ -38,24 +62,43 @@ static inline HMODULE win32_dlopen(const char *name)
 // Need to check if KB2533623 is available
 if (!GetProcAddress(GetModuleHandleW(L"kernel32.dll"), 
"SetDefaultDllDirectories")) {
 HMODULE module = NULL;
-wchar_t *path = NULL, *name_w = NULL;
-DWORD pathlen;
+wchar_t *path = NULL, *new_path = NULL, *name_w = NULL;
+DWORD pathlen, pathsize, namelen;
 if (utf8towchar(name, _w))
 goto exit;
-path = (wchar_t *)av_calloc(MAX_PATH, sizeof(wchar_t));
+namelen = wcslen(name_w);
 // Try local directory first
-pathlen = GetModuleFileNameW(NULL, path, MAX_PATH);
-pathlen = wcsrchr(path, '\\') - path;
-if (pathlen == 0 || pathlen + wcslen(name_w) + 2 > MAX_PATH)
+path = get_module_filename(NULL);
+if (!path)
+goto exit;
+new_path = wcsrchr(path, '\\');
+if (!new_path)
+goto exit;
+pathlen = new_path - path;
+pathsize = pathlen + namelen + 2;
+new_path = av_realloc_array(path, pathsize, sizeof *path);
+if (!new_path)
 goto exit;
-path[pathlen] = '\\';
+path = new_path;
 wcscpy(path + pathlen + 1, name_w);
 module = LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
 if (module == NULL) {
 // Next try System32 directory
-pathlen = GetSystemDirectoryW(path, MAX_PATH);
-if (pathlen == 0 || pathlen + wcslen(name_w) + 2 > MAX_PATH)
+pathlen = GetSystemDirectoryW(path, pathsize);
+if (!pathlen)
 goto exit;
+if (pathlen + namelen + 2 > pathsize) {
+pathsize = pathlen + namelen + 2;
+new_path = av_realloc_array(path, pathsize, sizeof *path);
+if (!new_path)
+goto exit;
+path = new_path;
+// The buffer might have been not enough for system directory
+// in the first place.
+pathlen = GetSystemDirectoryW(path, pathsize);
+if (!pathlen)
+goto exit;
+}
 path[pathlen] = '\\';
 wcscpy(path + pathlen + 1, name_w);
 module = LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
diff --git a/fftools/Makefile b/fftools/Makefile
index da42078..53438b6 100644
--- a/fftools/Makefile
+++ b/fftools/Makefile
@@ -11,6 +11,11 @@ ALLAVPROGS_G = $(AVBASENAMES:%=%$(PROGSSUF)_g$(EXESUF))
 
 OBJS-ffmpeg+= fftools/ffmpeg_opt.o 
fftools/ffmpeg_filter.o fftools/ffmpeg_hw.o
 
+# Windows resource files
+OBJS-ffmpeg-$(HAVE_GNU_WINDRES) += fftools/long_paths_utf8.o
+OBJS-ffplay-$(HAVE_GNU_WINDRES) += fftools/long_paths_utf8.o
+OBJS-ffprobe-$(HAVE_GNU_WINDRES) += fftools/long_paths_utf8.o
+
 define DOFFTOOL
 OBJS-$(1) += fftools/cmdutils.o fftools/$(1).o $(OBJS-$(1)-yes)
 $(1)$(PROGSSUF)_g$(EXESUF): $$(OBJS-$(1))
diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c
index 4b50e15..ea78897 100644
--- a/fftools/cmdutils.c
+++ b/fftools/cmdutils.c
@@ -62,6 +62,7 @@
 #endif
 #ifdef _WIN32