From dd06cf54230dd62d5c675dc652ea5b862ae9933d Mon Sep 17 00:00:00 2001 From: Eric Mehl Date: Mon, 9 Oct 2023 15:33:07 -0400 Subject: [PATCH] FileSystemPath : Work around Windows exFAT bug MSVC's `std::filesystem` has a bug that causes it to fail to retrieve file information on exFAT partitions in versions prior to (roughly) 17.2. That version is the first release after merging a fix from https://github.com/microsoft/STL/pull/2373, but I'm not certain that version has the fix included. Using `std::filesystem::status` instead of `symlink_status()` seems justified because exFAT paritions don't support symlinks. If other partition types are included in the filter for error code 87, this may need to be revisited. --- Changes.md | 5 +++++ src/Gaffer/FileSystemPath.cpp | 22 +++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/Changes.md b/Changes.md index aa935d5aad2..a93f60f24d7 100644 --- a/Changes.md +++ b/Changes.md @@ -8,6 +8,11 @@ Improvements - Popups for string cells and row names are now sized to fit their column. - Added "Triple" and "Quadruple" width options to the spreadsheet row name popup menu. +Fixes +----- + +- FileSystemPath : Fixed bug on Windows where paths on an exFAT partition were not considered valid. + 1.3.4.0 (relative to 1.3.3.0) ======= diff --git a/src/Gaffer/FileSystemPath.cpp b/src/Gaffer/FileSystemPath.cpp index b9d0fce23f0..32ed087a706 100644 --- a/src/Gaffer/FileSystemPath.cpp +++ b/src/Gaffer/FileSystemPath.cpp @@ -258,7 +258,27 @@ bool FileSystemPath::isValid( const IECore::Canceller *canceller ) const std::error_code e; - const std::filesystem::file_type t = std::filesystem::symlink_status( std::filesystem::path( this->string() ), e ).type(); + std::filesystem::file_type t = std::filesystem::symlink_status( std::filesystem::path( this->string() ), e ).type(); + +#if defined(_MSC_VER) && _MSC_VER < 1932 + +// Fix MSVC bug preventing `symlink_status()` working with exFAT partitions, and possibly FAT. +// Filtering to error 87 is based on experimentation and backed up by +// https://github.com/microsoft/STL/issues/233. Using `status()` instead of `symlink_status()` +// allows exFAT partitions to be used, and because exFAT does not support symlinks, this +// should be a valid workaround provided filtering to error value `87` doesn't include +// partitions that do support symlinks. +if( + ( + t == std::filesystem::file_type::none || t == std::filesystem::file_type::not_found + ) && e.value() == 87 // "The parameter is incorrect." +) +{ + t = std::filesystem::status( std::filesystem::path( this->string() ), e ).type(); +} + +#endif + return t != std::filesystem::file_type::none && t != std::filesystem::file_type::not_found; }