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 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 Content-Type: multipart/mixed; boundary="------------070805020203010402000104" 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--