changeset 27496:def608acdfa9

Canonicalize case of file path on Windows file systems (bug #56267). * file-ops.cc (canonicalize_file_name): Call GetLongPathNameW to get actual letter case of file name and path.
author Markus Mützel <markus.muetzel@gmx.de>
date Sat, 21 Sep 2019 18:09:29 +0200
parents 910737d41605
children 5a0543de1e47
files liboctave/system/file-ops.cc
diffstat 1 files changed, 14 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/system/file-ops.cc	Mon Oct 14 17:33:24 2019 -0700
+++ b/liboctave/system/file-ops.cc	Sat Sep 21 18:09:29 2019 +0200
@@ -32,6 +32,9 @@
 #if (defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM))
 #  include <algorithm>
 #endif
+#if defined (OCTAVE_USE_WINDOWS_API)
+#  include <windows.h>
+#endif
 
 #include <vector>
 
@@ -704,6 +707,17 @@
       std::replace (retval.begin (), retval.end (), '/', '\\');
 #endif
 
+#if defined (OCTAVE_USE_WINDOWS_API)
+      // Get a more canonical name wrt case and full names
+      std::wstring w_tmp = L"\\\\?\\" + u8_to_wstring (retval);
+      wchar_t w_long[32767] = L"";
+      int w_len = GetLongPathNameW (w_tmp.c_str (), w_long, 32767);
+      if (w_len > 4)
+        retval = u8_from_wstring (std::wstring (w_long+4, w_len-4));
+      if (retval[1] == ':')
+        retval[0] = toupper (retval[0]);
+#endif
+
       if (retval.empty ())
         msg = std::strerror (errno);