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 -