Skip to content

Commit

Permalink
FileStream: Fix opening long paths on Windows (taglib#1216)
Browse files Browse the repository at this point in the history
To make sure paths longer than MAX_PATH (260) can be opened, prefix local
paths with `\\?\`, and UNC paths with `\\?\UNC\`.

I've tested on Windows 10 22H2 (Build 19045.3930), even when setting
LongPathsEnabled to 1 in the registry, it still won't open files with long
paths without prefixing them.

For more information see:
https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry
  • Loading branch information
jonaski authored Jan 28, 2024
1 parent 0d2c31b commit 920d976
Showing 1 changed file with 15 additions and 1 deletion.
16 changes: 15 additions & 1 deletion taglib/toolkit/tfilestream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,21 @@ namespace
#if defined (PLATFORM_WINRT)
return CreateFile2(path.wstr().c_str(), access, FILE_SHARE_READ, OPEN_EXISTING, nullptr);
#else
return CreateFileW(path.wstr().c_str(), access, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
constexpr wchar_t LongLocalPathPrefix[] = L"\\\\?\\";
constexpr wchar_t UNCPathPrefix[] = L"\\\\";
constexpr wchar_t LongUNCPathPrefix[] = L"\\\\?\\UNC\\";
std::wstring pathWStr = path.wstr();
if(pathWStr.length() > MAX_PATH &&
pathWStr.compare(0, std::size(LongLocalPathPrefix) - 1, LongLocalPathPrefix) != 0 &&
pathWStr.compare(0, std::size(LongUNCPathPrefix) - 1, LongUNCPathPrefix) != 0) {
if(pathWStr.compare(0, std::size(UNCPathPrefix) - 1, UNCPathPrefix) == 0) {
pathWStr = LongUNCPathPrefix + pathWStr.substr(2);
}
else {
pathWStr = LongLocalPathPrefix + pathWStr;
}
}
return CreateFileW(pathWStr.c_str(), access, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
#endif
}

Expand Down

0 comments on commit 920d976

Please sign in to comment.