Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

win32: support long file paths #13134

Merged
merged 1 commit into from
Dec 21, 2023

Conversation

stax76
Copy link
Contributor

@stax76 stax76 commented Dec 19, 2023

win32: support long file paths

@Hrxn
Copy link
Contributor

Hrxn commented Dec 19, 2023

For the record, there was already this PR: #12119

Although this does not propose any changes to the binary manifest on Win32.

@stax76
Copy link
Contributor Author

stax76 commented Dec 19, 2023

I didn't expect things to be complicated like that. I have this manifest option enabled in mpv.net, and it works well, if I remember correctly.

@Hrxn
Copy link
Contributor

Hrxn commented Dec 19, 2023

Yep, enabling it in the manifest should be enough - that's what I gathered from the docs as well.

The other PR was some kind of workaround, I believe.

Copy link

Download the artifacts for this pull request:

Windows

@cheater
Copy link

cheater commented Dec 19, 2023

confirming this fixes the referenced bug

@cheater
Copy link

cheater commented Dec 19, 2023

this one: #10025

@sfan5
Copy link
Member

sfan5 commented Dec 21, 2023

Worth mentioning that you have to manually enable this in the registry:
grafik

I remember this being discussed a while ago and someone discovering that certain popular applications silently enable this feature system-wide.

@sfan5 sfan5 merged commit c09245c into mpv-player:master Dec 21, 2023
13 checks passed
@kasper93
Copy link
Contributor

I couldn't comment before, but this PR is incomplete. You have to go through all affected API calls and change the hard coded buffer sizes to dynamically allocated ones, as there is no limit on the path lengths anymore. Last time I checked there were at least a few places to change.

Buffer overflow on arbitrary user input is "not ideal"(tm).

I remember this being discussed a while ago and someone discovering that certain popular applications silently enable this feature system-wide.

Indeed the Python installer does that, it is opt-out, but is enabled by default IIRC.

@cheater
Copy link

cheater commented Dec 21, 2023 via email

@sfan5
Copy link
Member

sfan5 commented Dec 21, 2023

You have to go through all affected API calls and change the hard coded buffer sizes to dynamically allocated ones, as there is no limit on the path lengths anymore

mpv uses PATH_MAX or MAX_PATH only in a few restricted cases, I couldn't find anything like you're suggesting (that should affect normal playback or so)

Buffer overflow on arbitrary user input is "not ideal"(tm).

Surely the win32 API takes buffer sizes and does not blindly write as much as it wants.

@kasper93
Copy link
Contributor

Yes, when the path is truncated, mpv should MP_WARN with instructions. We could even add a specific command to do it for the user.

@kasper93
Copy link
Contributor

kasper93 commented Dec 21, 2023

@sfan5 Doesn't change the fact that long path option is opt-in for a reason and applying it blindy is not ideal. But if you checked that's fine, it's ok. I cannot look up the code right now. But this PR looks incomplete to say the least. (There is no documentation update even...) It would have been done by now if it were so easy.

EDIT: sorry for the double post

@cheater
Copy link

cheater commented Dec 21, 2023

the warn-on-truncation thing is a good idea.

We could even add a specific command to do it for the user

i thought of suggesting that, but i thought maybe it's a little much. if you think that's a good idea, i'll defer to you.

@kasper93
Copy link
Contributor

mpv uses PATH_MAX or MAX_PATH only in a few restricted cases, I couldn't find anything like you're suggesting (that should affect normal playback or so)

The real question is. Does mpv suppose to support long paths, or just pretend to do it?

Whole osdep/io.c directory management is based on this limit, I wouldn't call it restricted cases. int wmain(...) is also rather common function to call.

mpv/osdep/io.c

Lines 553 to 575 in c09245c

// Windows' MAX_PATH/PATH_MAX/FILENAME_MAX is fixed to 260, but this limit
// applies to unicode paths encoded with wchar_t (2 bytes on Windows). The UTF-8
// version could end up bigger in memory. In the worst case each wchar_t is
// encoded to 3 bytes in UTF-8, so in the worst case we have:
// wcslen(wpath) * 3 <= strlen(utf8path)
// Thus we need MP_PATH_MAX as the UTF-8/char version of PATH_MAX.
// Also make sure there's free space for the terminating \0.
// (For codepoints encoded as UTF-16 surrogate pairs, UTF-8 has the same length.)
#define MP_PATH_MAX (FILENAME_MAX * 3 + 1)
struct mp_dir {
DIR crap; // must be first member
_WDIR *wdir;
union {
struct dirent dirent;
// dirent has space only for FILENAME_MAX bytes. _wdirent has space for
// FILENAME_MAX wchar_t, which might end up bigger as UTF-8 in some
// cases. Guarantee we can always hold _wdirent.d_name converted to
// UTF-8 (see MP_PATH_MAX).
// This works because dirent.d_name is the last member of dirent.
char space[MP_PATH_MAX];
};
};

Some of the things will work, others will not work. That's true Microsoft takes care about API safety, so it is hard to overflow buffers, but supporting long paths sometimes can have it's own problems. If you open a file and truncated path is passed around and someone do mv in script of unexpected path.

My point was only that those restricted cases should be fixed, before enabling the longPathAware. And in general the I/O should be handled with care. But we are past this point, so I guess Windows users can expect unexpected.

@Hrxn
Copy link
Contributor

Hrxn commented Dec 22, 2023

Worth mentioning that you have to manually enable this in the registry:

Yes, but even if I somewhat repeat myself here, I don't see this as of any concern for mpv. Not at all.

Like, the hypothetical end-user™ comes asking that question, and mpv project can just say: "we support it, our job is done".

This feature, or option, exists in Windows, even if - for now - it is toggled off by default. So, the burden is on the end-user, to voluntarily change this option. Or to pester MSFT to change the defaults.

@na-na-hi
Copy link
Contributor

Whole osdep/io.c directory management is based on this limit, I wouldn't call it restricted cases.

This is a hard limit of the win32 directory enumeration API. Enabling long path also doesn't change the filename length limit of the underlying filesystem, which is 255 characters for NTFS, FAT32, exFAT, and ReFS. For all practical purposes, this isn't a case that's affected by this change.

@sfan5
Copy link
Member

sfan5 commented Dec 22, 2023

My point was only that those restricted cases should be fixed, before enabling the longPathAware.

I agree, but I forgot to check prior to merging this.

@cheater
Copy link

cheater commented Dec 22, 2023

Worth mentioning that you have to manually enable this in the registry:

Yes, but even if I somewhat repeat myself here, I don't see this as of any concern for mpv. Not at all.

Like, the hypothetical end-user™ comes asking that question, and mpv project can just say: "we support it, our job is done".

This feature, or option, exists in Windows, even if - for now - it is toggled off by default. So, the burden is on the end-user, to voluntarily change this option. Or to pester MSFT to change the defaults.

i have to disagree, it's a bad point of view for a project to take in my opinion. if i can install mpv on a windows system and a feature doesn't work because some arcane setting in a database that's supposed to be modified by programs running on that system such as mpv, then that feature is broken and needs to be fixed.

"our job is done" is the epitome of anti-user design. user-friendly design starts with what a user wants to do ("the user wants to play files on very long paths") and implements everything so that the user can do it without having to manipulate any other things. where some things are not possible for the program to do, the program should instruct the user what to do. you ought to deliver "the whole package" and not just some slapdash that no one knows how to make magically work while refusing to elaborate why it doesn't magically work.

@Hrxn
Copy link
Contributor

Hrxn commented Dec 22, 2023

[..] Enabling long path also doesn't change the filename length limit of the underlying filesystem, which is 255 characters for NTFS, FAT32, exFAT, and ReFS. For all practical purposes, this isn't a case that's affected by this change.

This is simply not true.

Since Windows 10, version 1607, the MAX_PATH limitations has been removed from the Win32 API. That is the whole point of the LongPathsEnabled / longPathAware exercise.

The maximum total path length post Windows 10 v1607 change is 32 767 characters.
You mention the filename length limit of the underlying filesystem. What you write here is misleading. There is no "filename" length limit that is part of the filesystem itself. The filesystem has a path component limitation, which is 255 characters for all common/modern filesystems, but again, this is a limit per path component, not a limit of a full file name.

@cheater
Copy link

cheater commented Dec 22, 2023 via email

@Hrxn
Copy link
Contributor

Hrxn commented Dec 22, 2023

i have to disagree, it's a bad point of view for a project to take in my opinion. if i can install mpv on a windows system and a feature doesn't work because some arcane setting in a database that's supposed to be modified by programs running on that system such as mpv, then that feature is broken and needs to be fixed.

"our job is done" is the epitome of anti-user design. user-friendly design starts with what a user wants to do ("the user wants to play files on very long paths") and implements everything so that the user can do it without having to manipulate any other things. where some things are not possible for the program to do, the program should instruct the user what to do. you ought to deliver "the whole package" and not just some slapdash that no one knows how to make magically work while refusing to elaborate why it doesn't magically work.

Look, I'm not going to write a treatise here on what does or does not constitute "user-friendly" design, not because I don't hold any qualified opinions on this subject matter, no, I simply do not have the time to do so, so I'm going straight to the significant omissions of what you have written here.

The assumption you made here is entirely wrong. You cannot "install" mpv on a Windows system, you cannot do the same on any other operating system, for that matter. Simply because mpv is what you can see on here (github.com/mpv-player/mpv), a program that exists and is distributed in source code form only. There are no official installers, no official binaries, no official builds, no official anything. Which is a very reasonable strategy for any open-source project that got its priorities straight, but that is a matter for another discussion.

You cannot simply have the same expectation here as of the official Windows installers for Python, as provided by the official Python project / The Python Software Foundation, which do indeed check for LongPathsEnabled during installation time and offer the end-user to make this change on their behalf.

Once there is an official installer for mpv on Windows provided by this project, we can have this discussion again (hint: never).

Also, it is definitely not some "arcane" setting. It's quick and easy to make this change. Asking the end-user to fetch a registry (.reg) file, double click on that and to click "confirm" is a very common practice, you will literally find this on any Windows support website or forum on the entire Internet.

Considering this as a broken feature is something you would have to take up with Microsoft. They don't made the step (yet) to make this change as a default, whatever the reasoning. Probably just not that high up their or their customer's priority list. But I would not be surprised if this will indeed become the new default in a new version of Windows.

@Hrxn
Copy link
Contributor

Hrxn commented Dec 22, 2023

@Hrxn "file name" is usually understood as what you call "path component". "file name" is usually not understood to mean "file path", especially not "full absolute file path". hope that puts everyone on the same page now.

Completely irrelevant distraction to the issue at hand here.

Any program (hint: this includes mpv) that opens a file needs to be able to uniquely address the file it is directed to open. And what makes a file uniquely addressable? It's what is colloquially called the "full name", in other words, the full path name, or, to be even more exact: the Fully qualified path name. It does not work with a file name alone.

Also, if I may remind everyone, you, in your very own comment, confirmed this as fixed for you.

@cheater
Copy link

cheater commented Dec 22, 2023

@Hrxn your recent comments are adversarial to everyone trying to just get this stuff done and irrelevant to the work. You have exactly one commit in the mpv repository, which is "OSC: fix indentation and stray whitepace". It removes two spaces from code indentation. You are tied for place 408 in the list of contributors with regards to amount of commits. Yet you act like you own the project and everyone in this PR. You don't know how to work collaboratively. Please leave and let us do our work.

@na-na-hi
Copy link
Contributor

na-na-hi commented Dec 22, 2023 via email

@Hrxn
Copy link
Contributor

Hrxn commented Dec 22, 2023

This one?
https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-win32_find_dataa

WIN32_FIND_DATAA structure (minwinbase.h)
Contains information about the file that is found by the FindFirstFile, FindFirstFileEx, or FindNextFile function.

https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findfirstfilea

By default, the name is limited to MAX_PATH characters. To extend this limit to 32,767 wide characters, prepend "\?" to the path. For more information, see Naming Files, Paths, and Namespaces.

https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation

These are the file management functions that no longer have MAX_PATH restrictions if you opt-in to long path behavior: CopyFileW, CopyFile2, CopyFileExW, CreateFileW, CreateFile2, CreateHardLinkW, CreateSymbolicLinkW, DeleteFileW, FindFirstFileW, FindFirstFileExW, FindNextFileW, GetFileAttributesW, GetFileAttributesExW, SetFileAttributesW, GetFullPathNameW, GetLongPathNameW, MoveFileW, MoveFileExW, MoveFileWithProgressW, ReplaceFileW, SearchPathW, FindFirstFileNameW, FindNextFileNameW, FindFirstStreamW, FindNextStreamW, GetCompressedFileSizeW, GetFinalPathNameByHandleW.

learn.microsoft.com says you're wrong.
Sorry, I don't make the rules.

@Hrxn
Copy link
Contributor

Hrxn commented Dec 22, 2023

@Hrxn your recent comments are adversarial to everyone trying to just get this stuff done and irrelevant to the work. You have exactly one commit in the mpv repository, which is "OSC: fix indentation and stray whitepace". It removes two spaces from code indentation. You are tied for place 408 in the list of contributors with regards to amount of commits. Yet you act like you own the project and everyone in this PR. You don't know how to work collaboratively. Please leave and let us do our work.

lmao, there's a place in the list of contributors? like a ranking? first time i've heard of such a thing.
not sure why you, or anyone else, would really care about such a thing.
if you can cite any sources, any facts, that show were i'm wrong, please for the sake of all that is holy, let he have my defeat.
othewise, this is duly noted for what it really is: really lame attempt at ad hominem.

@na-na-hi
Copy link
Contributor

na-na-hi commented Dec 22, 2023 via email

@cheater
Copy link

cheater commented Dec 22, 2023

@na-na-hi please don't feed the troll

@Hrxn just get lost already

@kasper93
Copy link
Contributor

Please limit personal remarks/attacks to minimum. This is not a good way of communicating. There are more important things to discuss, no need to include unnecessary remarks.

@cheater
Copy link

cheater commented Dec 22, 2023

@kasper93 hrxn shows up out of nowhere and starts bossing people around and wastes people's time by being snarky about docs he doesn't understand. this needed to be nipped in the bud, hopefully it'll stick.

@Hrxn
Copy link
Contributor

Hrxn commented Dec 22, 2023

The following code shows a minimal use of FindFirstFileEx. This program is equivalent to the example in the FindFirstFile topic.

#include <windows.h>
#include <tchar.h>
#include <stdio.h>

void _tmain(int argc, TCHAR *argv[])
{
   WIN32_FIND_DATA FindFileData;
   HANDLE hFind;

   if( argc != 2 )
   {
      _tprintf(TEXT("Usage: %s [target_file]\n"), argv[0]);
      return;
   }

   _tprintf (TEXT("Target file is %s\n"), argv[1]);
   hFind = FindFirstFileEx(argv[1], FindExInfoStandard, &FindFileData,
             FindExSearchNameMatch, NULL, 0);
   if (hFind == INVALID_HANDLE_VALUE) 
   {
      printf ("FindFirstFileEx failed (%d)\n", GetLastError());
      return;
   } 
   else 
   {
      _tprintf (TEXT("The first file found is %s\n"), 
                FindFileData.cFileName);
      FindClose(hFind);
   }
}

FindFileData is of type WIN32_FIND_DATA
FindFileData has the property cFileName (fourth line from below).

MSFT docs say this API function supports LongFilePaths.

Who is wrong?
Microsoft?
Random commenter on GitHub?
What should be my priors?

@Andarwinux
Copy link
Contributor

shinchiro/mpv-packaging@1c534ce

The built-in installer for mpv-winbuild-cmake now auto enable windows long path support. Hopefully this will help solve the problem here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants