Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: ffmpegagent <ffmpegagent@gmail.com>
To: ffmpeg-devel@ffmpeg.org
Cc: softworkz <softworkz@hotmail.com>
Subject: [FFmpeg-devel] [PATCH v2 0/2] Support long file names on Windows
Date: Sun, 15 May 2022 22:17:49 +0000
Message-ID: <pull.28.v2.ffstaging.FFmpeg.1652653071.ffmpegagent@gmail.com> (raw)
In-Reply-To: <pull.28.ffstaging.FFmpeg.1652435595.ffmpegagent@gmail.com>

This patchset adds support for long file and directory paths on Windows. The
implementation follows the same logic that .NET is using internally, with
the only exception that it doesn't expand short path components in 8.3
format. .NET does this as the same function is also used for other purposes,
but in our case, that's not required. Short (8.3) paths are working as well
with the extended path prefix, even when longer than 260.

Successfully tested:

 * Regular paths wth drive letter
 * Regular UNC paths
 * Long paths wth drive letter
 * Long paths wth drive letter and forward slashes
 * Long UNC paths
 * Prefixed paths wth drive letter
 * Prefixed UNC paths

I have kept the individual functions separate on purpose, to make it easy to
compare with the .NET impl. (compilers should inlinie those anyway)

v2

 * wchar_filename: Improve comments and function documentation
 * os_support: adjust defines to use win32_stat

softworkz (2):
  avutil/wchar_filename,file_open: Support long file names on Windows
  avformat/os_support: Support long file names on Windows

 libavformat/os_support.h   |  26 +++++--
 libavutil/file_open.c      |   2 +-
 libavutil/wchar_filename.h | 156 +++++++++++++++++++++++++++++++++++++
 3 files changed, 178 insertions(+), 6 deletions(-)


base-commit: d2d8b9b972ba2df6b2a2ebe29f5307cbb7a69c33
Published-As: https://github.com/ffstaging/FFmpeg/releases/tag/pr-ffstaging-28%2Fsoftworkz%2Fsubmit_long_filenames-v2
Fetch-It-Via: git fetch https://github.com/ffstaging/FFmpeg pr-ffstaging-28/softworkz/submit_long_filenames-v2
Pull-Request: https://github.com/ffstaging/FFmpeg/pull/28

Range-diff vs v1:

 1:  26c579e4ee ! 1:  b66dbdf40c avutil/wchar_filename,file_open: Support long file names on Windows
     @@ libavutil/wchar_filename.h: static inline int utf8towchar(const char *filename_u
           return 0;
       }
      +
     ++/**
     ++ * Checks for extended path prefixes for which normalization needs to be skipped.
     ++ * see .NET6: PathInternal.IsExtended()
     ++ */
      +static inline int path_is_extended(const wchar_t *path)
      +{
     -+    // see .NET6: PathInternal.IsExtended()
      +    size_t len = wcslen(path);
      +    if (len >= 4  && path[0] == L'\\' && (path[1] == L'\\' || path[1] == L'?') && path[2] == L'?' && path[3] == L'\\')
      +        return 1;
     @@ libavutil/wchar_filename.h: static inline int utf8towchar(const char *filename_u
      +    return 0;
      +}
      +
     ++/**
     ++ * Performs path normalization by calling GetFullPathNameW().
     ++ * see .NET6: PathHelper.GetFullPathName()
     ++ */
      +static inline int get_full_path_name(wchar_t **ppath_w)
      +{
      +    int num_chars;
      +    wchar_t *temp_w;
      +
     -+    // see .NET6: PathHelper.GetFullPathName()
      +    num_chars = GetFullPathNameW(*ppath_w, 0, NULL, NULL);
      +    if (num_chars <= 0) {
      +        errno = EINVAL;
     @@ libavutil/wchar_filename.h: static inline int utf8towchar(const char *filename_u
      +    return 0;
      +}
      +
     ++/**
     ++ * Normalizes a Windows file or folder path.
     ++ * Expansion of short paths (with 8.3 path components) is currently omitted
     ++ * as it is not required for accessing long paths.
     ++ * see .NET6: PathHelper.Normalize().
     ++ */
      +static inline int path_normalize(wchar_t **ppath_w)
      +{
      +    int ret;
      +
     -+    // see .NET6: PathHelper.Normalize()
      +    if ((ret = get_full_path_name(ppath_w)) < 0)
      +        return ret;
      +
      +    /* What .NET does at this point is to call PathHelper.TryExpandShortFileName()
     -+       in case the path contains a '~' character.
     -+       We don't need to do this as we don't need to normalize the file name
     -+       for presentation, and the extended path prefix works with 8.3 path
     -+       components as well */
     ++     * in case the path contains a '~' character.
     ++     * We don't need to do this as we don't need to normalize the file name
     ++     * for presentation, and the extended path prefix works with 8.3 path
     ++     * components as well
     ++     */
      +    return 0;
      +}
      +
     ++/**
     ++ * Adds an extended path or UNC prefix to longs paths or paths ending
     ++ * with a space or a dot. (' ' or '.').
     ++ * This function expects that the path has been normalized before by
     ++ * calling path_normalize().
     ++ * see .NET6: PathInternal.EnsureExtendedPrefix() *
     ++ */
      +static inline int add_extended_prefix(wchar_t **ppath_w)
      +{
      +    const wchar_t *unc_prefix           = L"\\\\?\\UNC\\";
     @@ libavutil/wchar_filename.h: static inline int utf8towchar(const char *filename_u
      +    if (len < 2)
      +        return 0;
      +
     -+    // see .NET6: PathInternal.EnsureExtendedPrefix()
     ++    /* We're skipping the check IsPartiallyQualified() because
     ++     * we know we have called GetFullPathNameW() already, also
     ++     * we don't check IsDevice() because device paths are not
     ++     * allowed to be long paths and we're calling this only
     ++     * for long paths.
     ++     */
      +    if (path_w[0] == L'\\' && path_w[1] == L'\\') {
     ++        // The length of unc_prefix is 6 plus 1 for terminating zeros
      +        temp_w = (wchar_t *)av_calloc(len + 6 + 1, sizeof(wchar_t));
      +        if (!temp_w) {
      +            errno = ENOMEM;
     @@ libavutil/wchar_filename.h: static inline int utf8towchar(const char *filename_u
      +        wcscpy(temp_w, unc_prefix);
      +        wcscat(temp_w, path_w + 2);
      +    } else {
     ++        // The length of extended_path_prefix is 4 plus 1 for terminating zeros
      +        temp_w = (wchar_t *)av_calloc(len + 4 + 1, sizeof(wchar_t));
      +        if (!temp_w) {
      +            errno = ENOMEM;
     @@ libavutil/wchar_filename.h: static inline int utf8towchar(const char *filename_u
      +    return 0;
      +}
      +
     ++/**
     ++ * Converts a file or folder path to wchar_t for use with Windows file
     ++ * APIs. Paths with extended path prefix (either '\\?\' or \??\') are
     ++ * left unchanged.
     ++ * All other paths are normalized and converted to absolute paths.
     ++ * Longs paths (>= 260) are prefixed with the extended path or extended
     ++ * UNC path prefix.
     ++ * see .NET6: Path.GetFullPath() and Path.GetFullPathInternal()
     ++ */
      +static inline int get_extended_win32_path(const char *path, wchar_t **ppath_w)
      +{
      +    int ret;
      +    size_t len;
      +
     -+    // see .NET6: Path.GetFullPath() and Path.GetFullPathInternal()
      +    if ((ret = utf8towchar(path, ppath_w)) < 0)
      +        return ret;
      +
      +    if (path_is_extended(*ppath_w)) {
     -+        /* \\?\ paths are considered normalized by definition. Windows doesn't normalize \\?\
     -+           paths and neither should we. Even if we wanted to, GetFullPathName does not work
     -+           properly with device paths. If one wants to pass a \\?\ path through normalization
     -+           one can chop off the prefix, pass it to GetFullPath and add it again. */
     ++        /* Paths prefixed with '\\?\' or \??\' are considered normalized by definition.
     ++         * Windows doesn't normalize those paths and neither should we.
     ++         */
      +        return 0;
      +    }
      +
 2:  acd81c61c3 ! 2:  8ecbafe2b7 avformat/os_support: Support long file names on Windows
     @@ Commit message
          Signed-off-by: softworkz <softworkz@hotmail.com>
      
       ## libavformat/os_support.h ##
     +@@
     + #  ifdef stat
     + #   undef stat
     + #  endif
     +-#  define stat _stati64
     ++#  define stat win32_stat
     ++
     ++    struct win32_stat
     ++    {
     ++        _dev_t         st_dev;
     ++        _ino_t         st_ino;
     ++        unsigned short st_mode;
     ++        short          st_nlink;
     ++        short          st_uid;
     ++        short          st_gid;
     ++        _dev_t         st_rdev;
     ++        __int64        st_size;
     ++        __time64_t     st_atime;
     ++        __time64_t     st_mtime;
     ++        __time64_t     st_ctime;
     ++    };
     ++
     + #  ifdef fstat
     + #   undef fstat
     + #  endif
      @@ libavformat/os_support.h: static inline int win32_##name(const char *filename_utf8) \
           wchar_t *filename_w;                                  \
           int ret;                                              \

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

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

  parent reply	other threads:[~2022-05-15 22:18 UTC|newest]

Thread overview: 83+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-13  9:53 [FFmpeg-devel] [PATCH " ffmpegagent
2022-05-13  9:53 ` [FFmpeg-devel] [PATCH 1/2] avutil/wchar_filename, file_open: " softworkz
2022-05-15 19:02   ` nil-admirari
2022-05-15 20:24     ` Soft Works
2022-05-16  8:34       ` nil-admirari
2022-05-13  9:53 ` [FFmpeg-devel] [PATCH 2/2] avformat/os_support: " softworkz
2022-05-15 19:13   ` nil-admirari
2022-05-15 22:14     ` Soft Works
2022-05-16  8:19       ` nil-admirari
2022-05-13 10:02 ` [FFmpeg-devel] [PATCH 0/2] " Soft Works
2022-05-15 19:36 ` nil-admirari
2022-05-15 20:31   ` Soft Works
2022-05-16  8:45     ` nil-admirari
2022-05-17  0:37       ` Soft Works
2022-05-15 22:17 ` ffmpegagent [this message]
2022-05-15 22:17   ` [FFmpeg-devel] [PATCH v2 1/2] avutil/wchar_filename, file_open: " softworkz
2022-05-16  8:12     ` nil-admirari
2022-05-16 21:14       ` Soft Works
2022-05-17 15:06         ` nil-admirari
2022-05-17 15:28           ` Soft Works
2022-05-17 15:43             ` Soft Works
2022-05-20 17:51               ` nil-admirari
2022-05-20 18:03                 ` Soft Works
2022-05-21 11:08                   ` nil-admirari
2022-05-21 11:12                     ` Soft Works
2022-05-23 15:35                       ` nil-admirari
2022-05-23 15:47                         ` Soft Works
2022-05-23 17:12                           ` Hendrik Leppkes
2022-05-24  5:32                             ` Soft Works
2022-05-24  5:54                               ` Soft Works
2022-05-24  9:47                           ` Soft Works
2022-05-24 12:11                             ` nil-admirari
2022-05-15 22:17   ` [FFmpeg-devel] [PATCH v2 2/2] avformat/os_support: " softworkz
2022-05-16 21:23   ` [FFmpeg-devel] [PATCH v3 0/2] " ffmpegagent
2022-05-16 21:23     ` [FFmpeg-devel] [PATCH v3 1/2] avutil/wchar_filename, file_open: " softworkz
2022-05-16 21:23     ` [FFmpeg-devel] [PATCH v3 2/2] avformat/os_support: " softworkz
2022-05-23 11:29     ` [FFmpeg-devel] [PATCH v4 0/2] " ffmpegagent
2022-05-23 11:29       ` [FFmpeg-devel] [PATCH v4 1/2] avutil/wchar_filename, file_open: " softworkz
2022-05-23 11:29       ` [FFmpeg-devel] [PATCH v4 2/2] avformat/os_support: " softworkz
2022-05-24  8:43       ` [FFmpeg-devel] [PATCH v5 0/2] " ffmpegagent
2022-05-24  8:43         ` [FFmpeg-devel] [PATCH v5 1/2] avutil/wchar_filename, file_open: " softworkz
2022-05-24  9:09           ` Martin Storsjö
2022-05-24  8:43         ` [FFmpeg-devel] [PATCH v5 2/2] avformat/os_support: " softworkz
2022-05-24  9:23           ` Martin Storsjö
2022-05-24  9:33             ` Soft Works
2022-05-24 10:25               ` Martin Storsjö
2022-05-24 11:15                 ` Soft Works
2022-05-24 11:26                   ` Martin Storsjö
2022-05-24 12:31                     ` Soft Works
2022-05-24 12:44                       ` Martin Storsjö
2022-05-24 13:41                         ` Soft Works
2022-05-24 13:58         ` [FFmpeg-devel] [PATCH v6 0/2] " ffmpegagent
2022-05-24 13:58           ` [FFmpeg-devel] [PATCH v6 1/2] avutil/wchar_filename, file_open: " softworkz
2022-05-24 20:55             ` Martin Storsjö
2022-05-24 13:58           ` [FFmpeg-devel] [PATCH v6 2/2] avformat/os_support: " softworkz
2022-05-24 20:58             ` Martin Storsjö
2022-05-24 22:12               ` Soft Works
2022-05-25  7:09                 ` Martin Storsjö
2022-05-24 22:20           ` [FFmpeg-devel] [PATCH v7 0/3] " ffmpegagent
2022-05-24 22:20             ` [FFmpeg-devel] [PATCH v7 1/3] avutil/wchar_filename, file_open: " softworkz
2022-05-24 22:20             ` [FFmpeg-devel] [PATCH v7 2/3] avformat/os_support: " softworkz
2022-05-25 14:47               ` nil-admirari
2022-05-25 15:28                 ` Soft Works
2022-05-25 19:17                   ` nil-admirari
2022-05-26  5:09                     ` Soft Works
2022-05-25 18:50                 ` Martin Storsjö
2022-05-24 22:20             ` [FFmpeg-devel] [PATCH v7 3/3] avformat/file: remove _WIN32 condition softworkz
2022-05-25  7:34             ` [FFmpeg-devel] [PATCH v7 0/3] Support long file names on Windows Martin Storsjö
2022-05-26  9:28             ` [FFmpeg-devel] [PATCH v8 " ffmpegagent
2022-05-26  9:28               ` [FFmpeg-devel] [PATCH v8 1/3] avutil/wchar_filename, file_open: " softworkz
2022-05-26  9:28               ` [FFmpeg-devel] [PATCH v8 2/3] avformat/os_support: " softworkz
2022-05-26  9:28               ` [FFmpeg-devel] [PATCH v8 3/3] avformat/file: remove _WIN32 condition softworkz
2022-05-26 21:26               ` [FFmpeg-devel] [PATCH v8 0/3] Support long file names on Windows Martin Storsjö
2022-06-09 10:03               ` Martin Storsjö
2022-06-09 19:37                 ` nil-admirari
2022-06-09 20:15                   ` Soft Works
2022-06-09 20:22                     ` nil-admirari
2022-06-09 21:32                     ` Soft Works
2022-06-09 20:21                   ` Martin Storsjö
2022-06-09 20:57                     ` nil-admirari
2022-06-09 21:02                       ` Martin Storsjö
2022-06-13 16:42                         ` nil-admirari
2022-06-09 21:03                       ` Soft Works

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=pull.28.v2.ffstaging.FFmpeg.1652653071.ffmpegagent@gmail.com \
    --to=ffmpegagent@gmail.com \
    --cc=ffmpeg-devel@ffmpeg.org \
    --cc=softworkz@hotmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git