delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2005/11/21/15:28:15

X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f
Message-ID: <438225CE.3050909@partition-saving.com>
Date: Mon, 21 Nov 2005 20:53:50 +0100
From: Damien Guibouret <damien DOT guibouret AT partition-saving DOT com>
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.2) Gecko/20040804
X-Accept-Language: en-us, en
MIME-Version: 1.0
To: djgpp AT delorie DOT com
Subject: Bug in Windows XP LFN API for findfirst/findnext
Reply-To: djgpp AT delorie DOT com

This is a multi-part message in MIME format.
--------------070805020203010402000104
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: quoted-printable

Hi,

I think there is a bug into Windows XP LFN API when requesting for file=20
with Unicode characters of code greater than 255 (those that are=20
replaced with '?' into a DOS box): it seems that Windows forget to put=20
the '\0' at end of name.
If you create a directory with two files in it: one having a name with a=20
non ASCII Unicode character (ex: =A4_euro_char) and another with a longer=
=20
name (a_longer_filename), when performing findfirst/findnext on this=20
directory you get "a_longer_filename" then "?_euro_charlename" (in case=20
file are found in this order, if not, do the findfirst/findnext twice to=20
see the problem).
A workaround is to reset the result area with '\0' before calling the=20
function as done into attached patch (be aware it is certainly not based=20
on latest sources).

Regards,

Damien

--------------070805020203010402000104
Content-Type: text/plain;
 name="patch.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="patch.txt"

diff -ru src.old/libc/dos/dir/findfirs.c src/libc/dos/dir/findfirs.c
--- src.old/libc/dos/dir/findfirs.c	Sat Aug 31 17:09:32 1996
+++ src/libc/dos/dir/findfirs.c	Mon Nov 21 18:42:52 2005
@@ -27,6 +27,7 @@
 
   _put_path(pathname);
   if(use_lfn) {
+    struct ffblklfn ffblk32;
 
     /* si = 1 indicates DOS style dates, 0 means Win32 type dates.
        DOS style dates are broken in some Win95 betas, build for either.
@@ -38,6 +39,11 @@
       extern long _Win32_to_DOS(long long WinTime);
     #endif
 
+    /* Clear result area to avoid WinXP bug not setting ending 0 into filename
+       in case it contains a Unicode character greater than 255. */
+    memset(&ffblk32, 0, sizeof(ffblk32));
+    dosmemput(&ffblk32, sizeof(ffblk32), __tb + pathlen);
+
     r.x.ax = 0x714e;
     r.x.cx = attrib;
     r.x.dx = __tb_offset;
@@ -47,7 +53,6 @@
     r.x.si = USEDOSDATE;
     __dpmi_int(0x21, &r);
     if(!(r.x.flags & 1)) {
-      struct ffblklfn ffblk32;
       /* Recover results */
       dosmemget(__tb+pathlen, sizeof(struct ffblklfn), &ffblk32);
 
diff -ru src.old/libc/dos/dir/findnext.c src/libc/dos/dir/findnext.c
--- src.old/libc/dos/dir/findnext.c	Sat Aug 31 18:09:32 1996
+++ src/libc/dos/dir/findnext.c	Mon Nov 21 18:43:02 2005
@@ -23,6 +23,8 @@
 
   if(_USE_LFN)
   {
+    struct ffblklfn ffblk32;
+
     /* si = 1 indicates DOS style dates, 0 means Win32 type dates.
        DOS style dates are broken in some Win95 betas, build for either.
        Release works with DOS date, it's faster, so use it. */
@@ -40,6 +42,12 @@
       errno = ENMFILE;
       return 1;
     }
+
+    /* Clear result area to avoid WinXP bug not setting ending 0 into filename
+       in case it contains a Unicode character greater than 255. */
+    memset(&ffblk32, 0, sizeof(ffblk32));
+    dosmemput(&ffblk32, sizeof(ffblk32), __tb);
+
     r.x.di = __tb_offset;
     r.x.es = __tb_segment;
     r.x.si = USEDOSDATE;
@@ -47,7 +55,6 @@
     __dpmi_int(0x21, &r);
     if (!(r.x.flags & 1))
     {
-      struct ffblklfn ffblk32;
       /* Recover results */
       dosmemget(__tb, sizeof(struct ffblklfn), &ffblk32);
 

--------------070805020203010402000104--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019