changeset 80376:6e2a0297b94d

(readdir): If FindFirstFile/FindNextFile return in cFileName a file name that includes `?' characters, use the 8+3 alias in cAlternateFileName instead.
author Eli Zaretskii <eliz@gnu.org>
date Wed, 26 Mar 2008 19:04:25 +0000
parents ae64208efa27
children 5e17443b4045
files src/w32.c
diffstat 1 files changed, 17 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/w32.c	Wed Mar 26 16:49:50 2008 +0000
+++ b/src/w32.c	Wed Mar 26 19:04:25 2008 +0000
@@ -1779,6 +1779,8 @@
 struct direct *
 readdir (DIR *dirp)
 {
+  int downcase = !NILP (Vw32_downcase_file_names);
+
   if (wnet_enum_handle != INVALID_HANDLE_VALUE)
     {
       if (!read_unc_volume (wnet_enum_handle,
@@ -1816,11 +1818,23 @@
   dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3 +
     dir_static.d_namlen - dir_static.d_namlen % 4;
 
-  dir_static.d_namlen = strlen (dir_find_data.cFileName);
-  strcpy (dir_static.d_name, dir_find_data.cFileName);
+  /* If the file name in cFileName[] includes `?' characters, it means
+     the original file name used characters that cannot be represented
+     by the current ANSI codepage.  To avoid total lossage, retrieve
+     the short 8+3 alias of the long file name.  */
+  if (_mbspbrk (dir_find_data.cFileName, "?"))
+    {
+      strcpy (dir_static.d_name, dir_find_data.cAlternateFileName);
+      /* 8+3 aliases are returned in all caps, which could break
+	 various alists that look at filenames' extensions.  */
+      downcase = 1;
+    }
+  else
+    strcpy (dir_static.d_name, dir_find_data.cFileName);
+  dir_static.d_namlen = strlen (dir_static.d_name);
   if (dir_is_fat)
     _strlwr (dir_static.d_name);
-  else if (!NILP (Vw32_downcase_file_names))
+  else if (downcase)
     {
       register char *p;
       for (p = dir_static.d_name; *p; p++)