delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2011/10/02/06:37:51

X-Authentication-Warning: delorie.com: mail set sender to djgpp-workers-bounces using -f
X-Recipient: djgpp-workers AT delorie DOT com
X-Authenticated: #27081556
X-Provags-ID: V01U2FsdGVkX1/JvGMbu/TJ9DJKq9tUcHyUfj3WdFq1cqiXp9M0vX
1APhDBUonl+GH/
From: Juan Manuel Guerrero <juan DOT guerrero AT gmx DOT de>
To: djgpp-workers AT delorie DOT com
Subject: Re: [Patch] Issues concerning the INT 21 Windows95 - LONG FILENAME FUNCTIONS (0x71XX) implementation.
Date: Sun, 2 Oct 2011 12:32:59 +0200
User-Agent: KMail/1.9.10
References: <201109282235 DOT 01944 DOT juan DOT guerrero AT gmx DOT de> <8362kae5ke DOT fsf AT gnu DOT org>
In-Reply-To: <8362kae5ke.fsf@gnu.org>
MIME-Version: 1.0
Message-Id: <201110021233.00119.juan.guerrero@gmx.de>
X-Y-GMX-Trusted: 0
Reply-To: djgpp-workers AT delorie DOT com

Am Freitag, 30. September 2011 schrieb Eli Zaretskii:
> > From: Juan Manuel Guerrero <juan DOT guerrero AT gmx DOT de>
> > Date: Wed, 28 Sep 2011 22:35:01 +0200
> > 
> > This is the last version of the patch to presented by me to fix the pending
> > issues concerning the use of 0x7XX functions from the LFN API of windows.
> 
> Thanks.  A couple of minor nits:
> 
> > +@findex _use_lfn AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
> > +@findex _rename AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
> > +All these functions now check that the used LFN driver supplies the required
> 
> "All these functions" will look mysterious in the manual, because all
> the preceding @findex entries disappear without a trace from the
> manual text.  Suggest to say something like "Many low-level library
> functions..." instead.
> 
> > -    int idx = sizeof(try_char)-1;
> > +    int idx = sizeof(try_char) - 1;
> 
> This kind of whitespace changes really doesn't belong with this patch.
> 
> > -  for (i=0; i<2; i++)
> > +  for (i = 0; i < 2; i++)
> >    {
> > -    if(use_lfn)
> > +    if (use_lfn)
> 
> Likewise (here and elsewhere).
> 
> Thanks again for working on this.
> 


Everything fixed and commited.

Regards,
Jua M. Guerrero




Index: djgpp/src/docs/kb/wc204.txi
===================================================================
RCS file: /cvs/djgpp/djgpp/src/docs/kb/wc204.txi,v
retrieving revision 1.195
diff -U 5 -r1.195 wc204.txi
--- djgpp/src/docs/kb/wc204.txi	26 Feb 2011 19:52:10 -0000	1.195
+++ djgpp/src/docs/kb/wc204.txi	2 Oct 2011 02:34:36 -0000
@@ -1198,5 +1198,39 @@
 
 @pindex djtar AT r{, and empty lines in the file to change filenames}
 @code{djtar} now ignores empty lines in filename change files instead
 of skipping the extraction of the file named in the line before the
 empty line.
+
+@findex flushdc AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex dosexec AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex fixpath AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex opendir AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex getcwd AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex mkdir AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex rmdir AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex chdir AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex filelen AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex lfilelen AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex fstat AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex fchmod AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex _open AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex _chmod AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex _creat_n AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex _creat AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex remove AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex findfirs AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex findnext AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex truename AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex lfnshort AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex _use_lfn AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex _rename AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+
+Functions @code{flushdc}, @code{dosexec}, @code{fixpath}, @code{opendir}, @code{getcwd},
+@code{mkdir}, @code{rmdir}, @code{chdir}, @code{filelen}, @code{lfilelen}, @code{fstat},
+@code{fchmod}, @code{_open}, @code{_chmod}, @code{_creat_n}, @code{_creat}, @code{remove},
+@code{findfirs}, @code{findnext}, @code{truename}, @code{lfnshort}, @code{_use_lfn} and
+@code{_rename} now check that the used LFN driver supplies the required @code{0x71} function
+from the @code{Windows 95} long filename functions API by inspecting the content of the @code{AX}
+register after return from the API function call.  Depending on the function type, the function
+will ignore, fail or fall back on the corresponding SFN API function if the LFN API function
+is not provided by the LFN driver used.
Index: djgpp/src/libc/ansi/stdio/_rename.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/ansi/stdio/_rename.c,v
retrieving revision 1.10
diff -U 5 -r1.10 _rename.c
--- djgpp/src/libc/ansi/stdio/_rename.c	1 Oct 2011 21:12:35 -0000	1.10
+++ djgpp/src/libc/ansi/stdio/_rename.c	2 Oct 2011 02:34:36 -0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
@@ -88,16 +89,20 @@
       if (idx <= 0)
 	return -1;
       *pbase = try_char[--idx];
     } while (_chmod(tempfile, 0) != -1);
 
+    r.x.flags = 1;  /* Always set CF before calling a 0x71NN function. */
     r.x.ax = 0x7156;
     _put_path2(tempfile, olen);
     _put_path(old);
     __dpmi_int(0x21, &r);
-    if (r.x.flags & 1)
+    if ((r.x.flags & 1) || (r.x.ax == 0x7100))
     {
+      /*  Never assume that the complete LFN API is implemented,
+          so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+          If not supported fail.  */
       errno = __doserr_to_errno(r.x.ax);
       return -1;
     }
 
     /* Now create a file with the original name.  This will
@@ -112,11 +117,14 @@
   }
 
   for (i = 0; i < 2; i++)
   {
     if (use_lfn)
+    {
+      r.x.flags |= 1;  /* Always set CF before calling a 0x71NN function. */
       r.x.ax = 0x7156;
+    }
 #if 0
     /* It seems that no version of DOS, including DOS 8, which is part
        of Windows/ME, implements this function.  Without LFN, this fails
        _rename on Windows/ME.  Disabled.  */
     else if ((_osmajor > 7 && _osmajor < 10) /* OS/2 returns v10 and above */
@@ -133,12 +141,16 @@
     else
       r.h.ah = 0x56;
     _put_path2(new, olen);
     _put_path(old);
     __dpmi_int(0x21, &r);
-    if (r.x.flags & 1)
+    if ((r.x.flags & 1) || (r.x.ax == 0x7100))
     {
+      /*  Never assume that the complete LFN API is implemented,
+          so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+          If not supported fail.  */
+
       if (i == 0
 	  && !identical_but_for_case /* don't nuke OLD! */
 	  && (r.x.ax == 5 || (r.x.ax == 2 && __file_exists(old))
 	      /* Windows 2000 returns B7h when the target file exists.  */
 	      || r.x.ax == 0xb7))
Index: djgpp/src/libc/ansi/stdio/remove.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/ansi/stdio/remove.c,v
retrieving revision 1.10
diff -U 5 -r1.10 remove.c
--- djgpp/src/libc/ansi/stdio/remove.c	1 Oct 2011 21:12:37 -0000	1.10
+++ djgpp/src/libc/ansi/stdio/remove.c	2 Oct 2011 02:34:36 -0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
@@ -59,20 +60,25 @@
     r.h.ah = 0x3a;		/* DOS Remove Directory function */
   else
     r.h.ah = 0x41;		/* DOS Remove File function */
   if (use_lfn)
   {
+    r.x.flags = 1;		/* Always set CF before calling a 0x71NN function. */
     r.h.al = r.h.ah;
     r.h.ah = 0x71;
     r.x.si = 0;			/* No Wildcards */
   }
   r.x.cx = 0;			/* Fix for ROM-DOS */
   r.x.dx = __tb_offset;
   r.x.ds = __tb_segment;
   __dpmi_int(0x21, &r);
-  if (r.x.flags & 1)
+  if ((r.x.flags & 1) || (r.x.ax == 0x7100))
   {
+    /*  Never assume that the complete LFN API is implemented,
+        so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+        If not supported fall back on SFN API 0x3A or 0x41.  */
+
     /* We failed.  Leave the things as we've found them.  */
     int e = __doserr_to_errno(r.x.ax);
 
     /* We know the file exists, so ENOENT at this point means a bug.
        Since write-protected floppies are the most probable cause,
Index: djgpp/src/libc/dos/dir/findfirs.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/dos/dir/findfirs.c,v
retrieving revision 1.7
diff -U 5 -r1.7 findfirs.c
--- djgpp/src/libc/dos/dir/findfirs.c	1 Oct 2011 21:12:38 -0000	1.7
+++ djgpp/src/libc/dos/dir/findfirs.c	2 Oct 2011 02:34:37 -0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <stdlib.h>
@@ -43,20 +44,25 @@
       #define _Win32_to_DOS (long)
     #else
       extern long _Win32_to_DOS(long long WinTime);
     #endif
 
+    r.x.flags = 1;  /* Always set CF before calling a 0x71NN function. */
     r.x.ax = 0x714e;
     r.x.cx = attrib;
     r.x.dx = __tb_offset;
     r.x.ds = __tb_segment;
     r.x.di = __tb_offset + pathlen;
     r.x.es = r.x.ds;
     r.x.si = USEDOSDATE;
     __dpmi_int(0x21, &r);
-    if (!(r.x.flags & 1))
+    if (!(r.x.flags & 1) && (r.x.ax != 0x7100))
     {
+      /*  Never assume that the complete LFN API is implemented,
+          so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+          If not supported fall back on SFN API 0x4E.  */
+
       struct ffblklfn ffblk32;
       unsigned long t1;
       /* Recover results */
       dosmemget(__tb+pathlen, sizeof(struct ffblklfn), &ffblk32);
 
@@ -71,10 +77,11 @@
       strcpy(ffblk->lfn_magic, "LFN32");
 
       /* If no wildcards, close the handle */
       if (!strchr(pathname, '*') && !strchr(pathname, '?'))
       {
+        r.x.flags |= 1;  /* Always set CF before calling a 0x71NN function. */
         r.x.bx = r.x.ax;
         r.x.ax = 0x71a1;
         __dpmi_int(0x21, &r);
         r.x.ax = 0;
       }
Index: djgpp/src/libc/dos/dir/findnext.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/dos/dir/findnext.c,v
retrieving revision 1.6
diff -U 5 -r1.6 findnext.c
--- djgpp/src/libc/dos/dir/findnext.c	1 Oct 2011 21:12:39 -0000	1.6
+++ djgpp/src/libc/dos/dir/findnext.c	2 Oct 2011 02:34:37 -0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <stdlib.h>
 #include <string.h>
@@ -31,10 +32,11 @@
       #define _Win32_to_DOS (long)
     #else
       extern long _Win32_to_DOS(long long WinTime);
     #endif
 
+    r.x.flags = 1;  /* Always set CF before calling a 0x71NN function. */
     r.x.ax = 0x714f;
     r.x.bx = ffblk->lfn_handle;
     if (!r.x.bx)
     {
       errno = ENMFILE;
@@ -43,12 +45,16 @@
     r.x.di = __tb_offset;
     r.x.es = __tb_segment;
     r.x.si = USEDOSDATE;
 
     __dpmi_int(0x21, &r);
-    if (!(r.x.flags & 1))
+    if (!(r.x.flags & 1) && (r.x.ax != 0x7100))
     {
+      /*  Never assume that the complete LFN API is implemented,
+          so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+          If not supported fall back on SFN API 0x4F.  */
+
       unsigned long t1; 
       struct ffblklfn ffblk32;
       /* Recover results */
       dosmemget(__tb, sizeof(struct ffblklfn), &ffblk32);
 
@@ -69,10 +75,11 @@
     }
     errno = __doserr_to_errno(r.x.ax);
     if (errno == ENMFILE)         /* call FindClose */
     {
       ffblk->lfn_handle = 0;
+      r.x.flags |= 1;  /* Always set CF before calling a 0x71NN function. */
       r.x.ax = 0x71a1;
       __dpmi_int(0x21, &r);
       if (r.x.flags & 1)
       {
         errno = __doserr_to_errno(r.x.ax);
Index: djgpp/src/libc/dos/dos/truename.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/dos/dos/truename.c,v
retrieving revision 1.6
diff -U 5 -r1.6 truename.c
--- djgpp/src/libc/dos/dos/truename.c	1 Oct 2011 21:12:43 -0000	1.6
+++ djgpp/src/libc/dos/dos/truename.c	2 Oct 2011 02:34:37 -0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 /*
  * This is file TRUENAME.C
@@ -105,10 +106,11 @@
   _put_path(name_start);
 
   /* Call DOS INT 21H undocumented function 60h. */
   if (use_lfn)
   {
+    regs.x.flags = 1;  /* Always set CF before calling a 0x71NN function. */
     regs.x.ax = 0x7160;
     /* Get Long Path Name (if there is one) and we want it. */
     regs.x.cx = try_lfn ? 2 : 0;
   }
   else
@@ -121,10 +123,20 @@
   regs.x.ds = regs.x.es = __tb_segment;
   regs.x.si = __tb_offset;
   regs.x.di = __tb_offset + MAX_TRUE_NAME;
   __dpmi_int(0x21, &regs);
 
+  if (regs.x.ax == 0x7100)
+  {
+    /*  Never assume that the complete LFN API is implemented,
+        so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+        If not supported fall back on 0x6000.  */
+    use_lfn = 0;
+    regs.x.ax = 0x6000;
+    goto lfn_retry;
+  }
+
   /* Now get the result from lower memory. */
   movedata(dos_mem_selector, __tb + MAX_TRUE_NAME,
            our_mem_selector, (unsigned int)true_name, MAX_TRUE_NAME);
 
   if (regs.x.flags & 1)
Index: djgpp/src/libc/dos/io/_chmod.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/dos/io/_chmod.c,v
retrieving revision 1.4
diff -U 5 -r1.4 _chmod.c
--- djgpp/src/libc/dos/io/_chmod.c	1 Oct 2011 21:12:45 -0000	1.4
+++ djgpp/src/libc/dos/io/_chmod.c	2 Oct 2011 02:34:37 -0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <io.h>
 #include <errno.h>
@@ -13,22 +14,26 @@
 {
   __dpmi_regs r;
 
   if (_USE_LFN)
   {
+    r.x.flags = 1;			/* Always set CF before calling a 0x71NN function. */
     r.x.ax = 0x7143;
     r.h.bl = func;			/* Get or Put */
   } else
     r.x.ax = 0x4300 + func;
   _put_path(filename);
   if (func == 1)
     r.x.cx = *(&func + 1);		/* Value to set */
   r.x.dx = __tb_offset;
   r.x.ds = __tb_segment;
   __dpmi_int(0x21, &r);
-  if(r.x.flags & 1)
+  if ((r.x.flags & 1) || (r.x.ax == 0x7100))
   {
+    /*  Never assume that the complete LFN API is implemented,
+        so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+        If not supported fail.  */
     errno = __doserr_to_errno(r.x.ax);
     return -1;
   }
  
   return r.x.cx;
Index: djgpp/src/libc/dos/io/_creat.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/dos/io/_creat.c,v
retrieving revision 1.13
diff -U 5 -r1.13 _creat.c
--- djgpp/src/libc/dos/io/_creat.c	1 Oct 2011 21:12:47 -0000	1.13
+++ djgpp/src/libc/dos/io/_creat.c	2 Oct 2011 02:34:37 -0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
@@ -31,10 +32,11 @@
   if (__FSEXT_call_open_handlers_wrapper(__FSEXT_creat, &rv, filename, attrib))
     return rv;
 
   if (use_lfn)
   {
+    r.x.flags = 1;		/* Always set CF before calling a 0x71NN function. */
     r.x.ax = 0x716c;
     r.x.bx = 0x0002;		/* Open r/w. */
     /* The FAT32 bit should _not_ be set on Windows 2000, because
        that bit fails function 716Ch on W2K.  The test below is
        based on the assumption that W2K returns DOS version 5.  */
@@ -61,15 +63,27 @@
     {
       r.h.ah = 0x3c;
       r.x.dx = __tb_offset;
     }
   }
+do_create:
   r.x.cx = attrib;
   r.x.ds = __tb_segment;
   _put_path(filename);
   __dpmi_int(0x21, &r);
-  if (r.x.flags & 1)
+
+  if (r.x.ax == 0x7100)
+  {
+    /*  Never assume that the complete LFN API is implemented,
+        so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+        If not supported fall back on SFN API 0x3C.  */
+    use_lfn = 0;
+    r.h.ah = 0x3c;
+    r.x.dx = __tb_offset;
+    goto do_create;
+  }
+  else if (r.x.flags & 1)
   {
     errno = __doserr_to_errno(r.x.ax);
     return -1;
   }
   if (use_lfn && _os_trueversion == 0x532)
Index: djgpp/src/libc/dos/io/_creat_n.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/dos/io/_creat_n.c,v
retrieving revision 1.9
diff -U 5 -r1.9 _creat_n.c
--- djgpp/src/libc/dos/io/_creat_n.c	1 Oct 2011 21:12:48 -0000	1.9
+++ djgpp/src/libc/dos/io/_creat_n.c	2 Oct 2011 02:34:37 -0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <stdarg.h>
@@ -40,10 +41,11 @@
   {
     if (7 <= _osmajor && _osmajor < 10)
     {
       r.x.bx |= 0x1000; 	/* FAT32 extended size. */
     }
+    r.x.flags = 1; 		/* Always set CF before calling a 0x71NN function. */
     r.x.ax = 0x716c;
   }
   else
   {
     if (7 <= _osmajor && _osmajor < 10)
@@ -62,14 +64,28 @@
       r.x.bx = 0;		/* lose support for fancy flags in DOS 3.x */
       r.x.dx = __tb_offset;
       r.x.si = 0;
     }
   }
+do_create:
   r.x.cx = attrib & 0xffff;
   r.x.ds = __tb_segment;
   __dpmi_int(0x21, &r);
-  if (r.x.flags & 1)
+
+  if (r.x.ax == 0x7100)
+  {
+    /*  Never assume that the complete LFN API is implemented,
+        so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+        If not supported fall back on SFN API 0x5B.  */
+    use_lfn = 0;
+    r.h.ah = 0x5b;
+    r.x.bx = 0;		/* lose support for fancy flags in DOS 3.x */
+    r.x.dx = __tb_offset;
+    r.x.si = 0;
+    goto do_create;
+  }
+  else if (r.x.flags & 1)
   {
     errno = __doserr_to_errno(r.x.ax);
     return -1;
   }
   if (use_lfn && _os_trueversion == 0x532)
Index: djgpp/src/libc/dos/io/_open.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/dos/io/_open.c,v
retrieving revision 1.10
diff -U 5 -r1.10 _open.c
--- djgpp/src/libc/dos/io/_open.c	1 Oct 2011 21:12:49 -0000	1.10
+++ djgpp/src/libc/dos/io/_open.c	2 Oct 2011 02:34:37 -0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
@@ -79,10 +80,11 @@
       }
     }
   }
   if (use_lfn)
   {
+    r.x.flags = 1;		/* Always set CF before calling a 0x71NN function. */
     r.x.ax = 0x716c;
     r.x.bx = (oflag & 0xff);
     /* The FAT32 bit should _not_ be set on Windows 2000, because
        that bit fails function 716Ch on W2K.  The test below is
        based on the assumption that W2K returns DOS version 5.  */
@@ -115,11 +117,23 @@
   r.x.ds = __tb_segment;
   _put_path(filename);
 do_open:
   r.x.cx = 0;
   __dpmi_int(0x21, &r);
-  if(r.x.flags & 1)
+
+  if (r.x.ax == 0x7100)
+  {
+    /*  Never assume that the complete LFN API is implemented,
+        so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+        If not supported fall back on SFN API 0x3D.  */
+    use_lfn = 0;
+    r.h.ah = 0x3d;
+    r.h.al = oflag;
+    r.x.dx = __tb_offset;
+    goto do_open;
+  }
+  else if (r.x.flags & 1)
   {
     errno = __doserr_to_errno(r.x.ax);
     return -1;
   }
 do_hset:
Index: djgpp/src/libc/dos/io/flushdc.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/dos/io/flushdc.c,v
retrieving revision 1.3
diff -U 5 -r1.3 flushdc.c
--- djgpp/src/libc/dos/io/flushdc.c	1 Oct 2011 21:12:52 -0000	1.3
+++ djgpp/src/libc/dos/io/flushdc.c	2 Oct 2011 02:34:37 -0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <fcntl.h>	/* for _USE_LFN */
 #include <io.h>		/* for the prototype of `_flush_disk_cache' */
 #include <dir.h>	/* for `getdisk' */
@@ -14,24 +15,30 @@
 
   if (_USE_LFN)
   {
     /* Windows 95 have special function to do what we want.  */
     /* FIXME: What if LFN is supported by a platform other than W95?  */
+    r.x.flags = 1;  /* Always set CF before calling a 0x71XX function. */
     r.x.ax = 0x710d;
-    r.x.cx = 1;	/* flush buffers and cache, reset drive */
+    r.x.cx = 1;      /* flush buffers and cache, reset drive */
     r.x.dx = drv + 1;
     __dpmi_int (0x21, &r);
-    /* According to docs (Interrupt list), this doesn't return
-       any error codes (??).  */
-  }
-  else
-  {
-    /* The BIOS Disk Reset function causes most DOS caches to flush.  */
-    r.x.ax = 0;
-    /* Hard disks should have 7th bit set.  */
-    /* FIXME: The mapping between DOS drive numbers and BIOS
-       drives is ignored.  The assumption is that Reset function
-       on ANY hard disk causes the cache to flush its buffers.  */
-    r.x.dx = drv > 2 ? ((drv - 2) | 0x80) : drv;
-    __dpmi_int (0x13, &r);
+    if ((r.x.flags & 1) || (r.x.ax == 0x7100))
+    {
+      /*  Never assume that the complete LFN API is implemented,
+          so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+          If not supported fall back on SFN API.  */
+      goto do_BIOS_DISK_RESET;
+    }
+    return;
   }
+
+do_BIOS_DISK_RESET:
+  /* The BIOS Disk Reset function causes most DOS caches to flush.  */
+  r.x.ax = 0;
+  /* Hard disks should have 7th bit set.  */
+  /* FIXME: The mapping between DOS drive numbers and BIOS
+     drives is ignored.  The assumption is that Reset function
+     on ANY hard disk causes the cache to flush its buffers.  */
+  r.x.dx = drv > 2 ? ((drv - 2) | 0x80) : drv;
+  __dpmi_int(0x13, &r);
 }
Index: djgpp/src/libc/dos/lfn/_use_lfn.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/dos/lfn/_use_lfn.c,v
retrieving revision 1.9
diff -U 5 -r1.9 _use_lfn.c
--- djgpp/src/libc/dos/lfn/_use_lfn.c	11 Dec 2007 07:27:39 -0000	1.9
+++ djgpp/src/libc/dos/lfn/_use_lfn.c	2 Oct 2011 02:34:37 -0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
@@ -70,19 +71,20 @@
     _farpokeb(_dos_ds, tbuf_la++, ':');
     _farpokeb(_dos_ds, tbuf_la++, '\\');
     _farpokeb(_dos_ds, tbuf_la++, '\0');
   }
 
+  r.x.flags = 1;	/* Always set CF before calling a 0x71NN function. */
   r.x.ax = 0x71a0;	/* Get Volume Information function */
   r.x.ds = tbuf_seg;	/* DS:DX points to root directory name */
   r.x.dx = 0;
   r.x.es = tbuf_seg;	/* ES:DI points to a buffer for filesys name */
   r.x.di = (tbuf_la - __tb) & 0xffff;
   r.x.cx = 32;		/* max size of filesystem name (Interrupt List) */
   __dpmi_int(0x21, &r);
 
-  if ((r.x.flags & 1) == 0 && r.x.ax != 0x7100)
+  if (!(r.x.flags & 1) && (r.x.ax != 0x7100))
   {
     char *p = fsystype, c;
 
     retval   = r.x.bx;
     if (maxfile)
Index: djgpp/src/libc/dos/lfn/lfnshort.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/dos/lfn/lfnshort.c,v
retrieving revision 1.5
diff -U 5 -r1.5 lfnshort.c
--- djgpp/src/libc/dos/lfn/lfnshort.c	2 Oct 2011 01:55:43 -0000	1.5
+++ djgpp/src/libc/dos/lfn/lfnshort.c	2 Oct 2011 02:34:37 -0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <ctype.h>
@@ -19,10 +20,11 @@
 _lfn_gen_short_fname(const char *long_fname, char *short_fname)
 {
   __dpmi_regs r;
   unsigned long tbuf = __tb;
 
+  r.x.flags = 1;	/* Always set CF before calling a 0x71NN function. */
   r.x.ax = 0x7100;
   if (_USE_LFN)
     {
       dosmemput (long_fname, strlen (long_fname) + 1, tbuf);
       r.x.ax = 0x71a8;
@@ -32,11 +34,11 @@
       r.x.di = 260;
       r.x.dx = 0x0011;	/* DH=01 would be better, but it's buggy */
       __dpmi_int (0x21, &r);
     }
 
-  if ((r.x.flags & 1) == 0 && r.x.ax != 0x7100)
+  if (!(r.x.flags & 1) && (r.x.ax != 0x7100))
     {
       char buf[13], *s = buf, *d = short_fname;
 
       dosmemget (tbuf + 260, sizeof buf, buf);
 
Index: djgpp/src/libc/dos/process/dosexec.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/dos/process/dosexec.c,v
retrieving revision 1.24
diff -U 5 -r1.24 dosexec.c
--- djgpp/src/libc/dos/process/dosexec.c	1 Oct 2011 21:12:54 -0000	1.24
+++ djgpp/src/libc/dos/process/dosexec.c	2 Oct 2011 02:34:37 -0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
@@ -211,17 +212,21 @@
      usual DOS form, and, under LFN, to the short 8+3 alias.  */
   _put_path2(program, tbuf_beg == __tb ? tbuf_ptr - tbuf_beg : 0);
   if (lfn)
   {
     unsigned pgm_name_loc = tbuf_beg == __tb ? tbuf_ptr : __tb;
+    r.x.flags = 1;			/* Always set CF before calling a 0x71NN function. */
     r.x.ax = 0x7160;			/* Truename */
     r.x.cx = 1;				/* Get short name */
     r.x.ds = r.x.es = pgm_name_loc / 16;
     r.x.si = r.x.di = pgm_name_loc & 15;
     __dpmi_int(0x21, &r);
-    if (r.x.flags & 1)
+    if ((r.x.flags & 1) || (r.x.ax == 0x7100))
     {
+      /*  Never assume that the complete LFN API is implemented,
+          so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+          If not supported fail.  */
       errno = __doserr_to_errno(r.x.ax);
       return -1;
     }
   }
   dosmemget(tbuf_beg == __tb ? tbuf_ptr : __tb, FILENAME_MAX, short_name);
Index: djgpp/src/libc/posix/dirent/opendir.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/dirent/opendir.c,v
retrieving revision 1.8
diff -U 5 -r1.8 opendir.c
--- djgpp/src/libc/posix/dirent/opendir.c	8 Dec 2008 17:48:50 -0000	1.8
+++ djgpp/src/libc/posix/dirent/opendir.c	2 Oct 2011 02:34:38 -0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
@@ -40,15 +41,19 @@
 void
 _lfn_find_close(int handle)
 {
   __dpmi_regs r;
 
+  r.x.flags = 1;  /* Always set CF before calling a 0x71NN function. */
   r.x.bx = handle;
   r.x.ax = 0x71a1;
   __dpmi_int(0x21, &r);
-  if (r.x.flags & 1)
+  if ((r.x.flags & 1) || (r.x.ax == 0x7100))
   {
+    /*  Never assume that the complete LFN API is implemented,
+        so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+        If not supported fail.  */
     errno = __doserr_to_errno(r.x.ax);
   }
 }
 
 void
Index: djgpp/src/libc/posix/sys/stat/fchmod.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/fchmod.c,v
retrieving revision 1.2
diff -U 5 -r1.2 fchmod.c
--- djgpp/src/libc/posix/sys/stat/fchmod.c	1 Oct 2011 21:12:55 -0000	1.2
+++ djgpp/src/libc/posix/sys/stat/fchmod.c	2 Oct 2011 02:34:38 -0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <string.h>
 #include <unistd.h>
 #include <sys/stat.h>
@@ -20,19 +21,23 @@
   __dpmi_regs r;
   int         mode = 0; /* Fail by default */
 
   if (_USE_LFN)
   {
+    r.x.flags = 1;   /* Always set CF before calling a 0x71NN function. */
     r.x.ax = 0x71a6; /* File info by handle */
     r.x.bx = fd;
     r.x.ds = __tb >> 4;
     r.x.dx = 0;
 
     __dpmi_int(0x21, &r);
 
-    if ((r.x.flags & 1) == 0)
+    if (!(r.x.flags & 1) && (r.x.ax != 0x7100))
     {
+      /*  Never assume that the complete LFN API is implemented,
+          so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+          If not supported fail.  */
       int attr = _farpeekl(_dos_ds, __tb);
 
       mode = S_IRUSR; /* Files are always readable. */
       if ((attr & 1) == 0)
 	mode |= S_IWUSR;
Index: djgpp/src/libc/posix/sys/stat/filelen.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/filelen.c,v
retrieving revision 1.8
diff -U 5 -r1.8 filelen.c
--- djgpp/src/libc/posix/sys/stat/filelen.c	1 Oct 2011 21:12:57 -0000	1.8
+++ djgpp/src/libc/posix/sys/stat/filelen.c	2 Oct 2011 02:34:38 -0000
@@ -34,15 +34,15 @@
      combos work properly.  This assumes this routine is called from fstat() 
      before we get the magic number or other things that do both seeks and 
      reads. */
   if (_USE_LFN && (fhandle != 0 || _os_trueversion != 0x532))
   {
+    regs.x.flags = 1;  /* Always set CF before calling a 0x71NN function. */
     regs.x.ax = 0x71A6;
     regs.x.bx = fhandle;
     regs.x.ds = __tb >> 4;
     regs.x.dx = 0;
-    regs.x.flags |= 1;
     __dpmi_int(0x21, &regs);
 
     /*  It is always necessary to test if LFN function
         has been implemented because the assumption has
         been proven false that a driver will set the CF
@@ -50,12 +50,14 @@
         E.g.: all DOSLFN drivers do not implement
         0x71A6 and DOSLFN 0.40e does not set CF
         making MSDOS 6.22 fail.  If FreeDOS 1.0 is
         used, the same LFN driver sets the CF.
         If the ax register contains 0x7100 then the
-        corresponding LFN function is not implemented.  */
-    if ((regs.x.flags & 1) == 0 && regs.x.ax != 0x7100)
+        corresponding LFN function is not implemented.
+        If the 0x71A6 function is not supported fall back
+        on 0x42NN.  */
+    if (!(regs.x.flags & 1) && (regs.x.ax != 0x7100))
     {
       /* Offset 0x24 contains the low 32-bits of the file size.
          Offset 0x20 contains the high 32-bits.  */
       retval = _farpeekl(_dos_ds, __tb + 0x24);
 
Index: djgpp/src/libc/posix/sys/stat/fixpath.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/fixpath.c,v
retrieving revision 1.12
diff -U 5 -r1.12 fixpath.c
--- djgpp/src/libc/posix/sys/stat/fixpath.c	1 Oct 2011 21:12:58 -0000	1.12
+++ djgpp/src/libc/posix/sys/stat/fixpath.c	2 Oct 2011 02:34:38 -0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
@@ -36,16 +37,26 @@
   r.x.flags = 1;		/* Set carry for safety */
   if (use_lfn)
     r.x.ax = 0x7147;
   else
     r.h.ah = 0x47;
+do_get_current_directory:
   r.h.dl = drive_number + 1;
   r.x.si = __tb_offset;
   r.x.ds = __tb_segment;
   __dpmi_int(0x21, &r);
 
-  if (r.x.flags & 1)
+  if (r.x.ax == 0x7100)
+  {
+    /*  Never assume that the complete LFN API is implemented,
+        so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+        If not supported fall back on SFN API 0x47.  */
+    use_lfn = 0;
+    r.h.ah = 0x47;
+    goto do_get_current_directory;
+  }
+  else if (r.x.flags & 1)
   {
 #ifdef TEST
     errno = __doserr_to_errno(r.x.ax);
     perror("Get dir failed in fixpath");
 #endif
@@ -348,18 +359,27 @@
   __dpmi_regs r;
 
   if (argc > 2)
   {
     _put_path(argv[1]);
+    r.x.flags = 1;		/* Set carry for safety */
     if (_USE_LFN)
       r.x.ax = 0x713b;
     else
       r.h.ah = 0x3b;
     r.x.dx = __tb_offset;
     r.x.ds = __tb_segment;
     __dpmi_int(0x21, &r);
-    if (r.x.flags & 1)
+    if (r.x.ax == 0x7100)
+    {
+      /*  Never assume that the complete LFN API is implemented,
+          so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40. */
+      errno = __doserr_to_errno(r.x.ax);
+      sprintf(fixed, "Change dir to %s failed (lfn=%d).  LFN driver does not support 0x713B", argv[1], _USE_LFN);
+      perror(fixed);
+    }
+    else if (r.x.flags & 1)
     {
       errno = __doserr_to_errno(r.x.ax);
       sprintf(fixed, "Change dir to %s failed (lfn=%d)", argv[1], _USE_LFN);
       perror(fixed);
     }
@@ -367,19 +387,28 @@
       printf("Set dir: %s\n", argv[1]);
     argc--;
     argv++;
   }
 
+  r.x.flags = 1;		/* Set carry for safety */
   if(_USE_LFN)
     r.x.ax = 0x7147;
   else
     r.h.ah = 0x47;
   r.h.dl = 0;
   r.x.si = __tb_offset;
   r.x.ds = __tb_segment;
   __dpmi_int(0x21, &r);
-  if (r.x.flags & 1)
+  if (r.x.ax == 0x7100)
+  {
+    /*  Never assume that the complete LFN API is implemented,
+        so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40. */
+    errno = __doserr_to_errno(r.x.ax);
+    printf("getcwd failed.  LFN driver does not support 0x7147");
+    perror("getcwd failed");
+  }
+  else if (r.x.flags & 1)
   {
     errno = __doserr_to_errno(r.x.ax);
     perror("getcwd failed");
   }
   else
Index: djgpp/src/libc/posix/sys/stat/fstat.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/fstat.c,v
retrieving revision 1.18
diff -U 5 -r1.18 fstat.c
--- djgpp/src/libc/posix/sys/stat/fstat.c	2 Oct 2011 01:55:44 -0000	1.18
+++ djgpp/src/libc/posix/sys/stat/fstat.c	2 Oct 2011 02:34:38 -0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
@@ -846,18 +847,23 @@
                such handles aren't supported by 71A6h call we use here.  */
             if (_USE_LFN)
             {
               __dpmi_regs r;
 
+              r.x.flags = 1;	/* Always set CF before calling a 0x71NN function. */
               r.x.ax = 0x71a6;	/* file info by handle */
               r.x.bx = fhandle;
               r.x.ds = __tb >> 4;
               r.x.dx = 0;
               __dpmi_int(0x21, &r);
-              if ((r.x.flags & 1) == 0
-                  && (_farpeekl(_dos_ds, __tb) & 0x07) == 0)
+              if (!(r.x.flags & 1) && (r.x.ax != 0x7100) &&
+                  !(_farpeekl(_dos_ds, __tb) & 0x07))
+              {
+                /*  Never assume that the complete LFN API is implemented,
+                    so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.  */
                 stat_buf->st_mode |= WRITE_ACCESS; /* no R, S or H bits set */
+              }
             }
 
             /* Executables are detected if they have magic numbers.  */
             if (!(_djstat_flags & _STAT_EXEC_MAGIC) &&
                 _is_executable((const char *)0, fhandle, (const char *)0))
Index: djgpp/src/libc/posix/sys/stat/lfilelen.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/lfilelen.c,v
retrieving revision 1.5
diff -U 5 -r1.5 lfilelen.c
--- djgpp/src/libc/posix/sys/stat/lfilelen.c	1 Oct 2011 21:13:01 -0000	1.5
+++ djgpp/src/libc/posix/sys/stat/lfilelen.c	2 Oct 2011 02:34:38 -0000
@@ -28,15 +28,15 @@
 
   /* DOS 7 provides a way to get the file size directly.
      Prefer it when available.  */
   if (_USE_LFN)
   {
+    regs.x.flags = 1;  /* Always set CF before calling a 0x71NN function. */
     regs.x.ax = 0x71A6;
     regs.x.bx = fhandle;
     regs.x.ds = __tb >> 4;
     regs.x.dx = 0;
-    regs.x.flags |= 1;
     __dpmi_int (0x21, &regs);
 
     /*  It is always necessary to test if LFN function
         has been implemented because the assumption has
         been proven false that a driver will set the CF
@@ -44,12 +44,14 @@
         E.g.: all DOSLFN drivers do not implement
         0x71A6 and DOSLFN 0.40e does not set CF
         making MSDOS 6.22 fail.  If FreeDOS 1.0 is
         used, the same LFN driver sets the CF.
         If the ax register contains 0x7100 then the
-        corresponding LFN function is not implemented.  */
-    if ((regs.x.flags & 1) == 0 && regs.x.ax != 0x7100)
+        corresponding LFN function is not implemented.
+        If the 0x71A6 function is not supported fall back
+        on 0x42NN.  */
+    if (!(regs.x.flags & 1) && (regs.x.ax != 0x7100))
     {
       /* Offset 0x24 contains the low 32-bits of the file size.
          Offset 0x20 contains the high 32-bits.  */
       long retval_l = _farpeekl (_dos_ds, __tb + 0x24);
       long retval_h = _farpeekl (_dos_ds, __tb + 0x20);
Index: djgpp/src/libc/posix/sys/stat/mkdir.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/mkdir.c,v
retrieving revision 1.6
diff -U 5 -r1.6 mkdir.c
--- djgpp/src/libc/posix/sys/stat/mkdir.c	1 Oct 2011 21:13:03 -0000	1.6
+++ djgpp/src/libc/posix/sys/stat/mkdir.c	2 Oct 2011 02:34:38 -0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
@@ -28,11 +29,14 @@
      return -1;
   
   _put_path(dir_name);
  
   if (use_lfn)
+  {
+    r.x.flags = 1;  /* Always set CF before calling a 0x71NN function. */
     r.x.ax = 0x7139;
+  }
 #if 0
   /* It seems that no version of DOS, including DOS 8, which is part
      of Windows/ME, implements this function.  Without LFN, this fails
      mkdir on Windows/ME.  Disabled.  */
   else if ((_osmajor > 7 && _osmajor < 10) /* OS/2 returns v10 and above */
@@ -46,15 +50,24 @@
     r.h.cl = 0x39;
   }
 #endif
   else
     r.h.ah = 0x39;
+do_mkdir:
   r.x.ds = __tb_segment;
   r.x.dx = __tb_offset;
   __dpmi_int(0x21, &r);
  
-  if (r.x.flags & 1)
+  if (r.x.ax == 0x7100)
+  {
+    /*  Never assume that the complete LFN API is implemented,
+        so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+        If not supported fall back on SFN API 0x39.  */
+    r.h.ah = 0x39;
+    goto do_mkdir;
+  }
+  else if (r.x.flags & 1)
   {
     int save_errno;
     save_errno = errno = __doserr_to_errno(r.x.ax);
     if (errno == EACCES)
     {
Index: djgpp/src/libc/posix/unistd/chdir.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/unistd/chdir.c,v
retrieving revision 1.7
diff -U 5 -r1.7 chdir.c
--- djgpp/src/libc/posix/unistd/chdir.c	1 Oct 2011 21:13:04 -0000	1.7
+++ djgpp/src/libc/posix/unistd/chdir.c	2 Oct 2011 02:34:38 -0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
@@ -51,17 +52,30 @@
   }
 
   if (drv_no == -1 || _farpeekb(_dos_ds, __tb + 2) != 0)
   {
     if (_USE_LFN)
+    {
+      r.x.flags = 1;  /* Always set CF before calling a 0x71NN function. */
       r.x.ax = 0x713b;
+    }
     else
       r.h.ah = 0x3b;
+do_chdir:
     r.x.dx = __tb_offset;
     r.x.ds = __tb_segment;
     __dpmi_int(0x21, &r);
-    if (r.x.flags & 1)
+
+    if (r.x.ax == 0x7100)
+    {
+      /*  Never assume that the complete LFN API is implemented,
+          so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+          If not supported fall back on SFN API 0c3B.  */
+      r.h.ah = 0x3b;
+      goto do_chdir;
+    }
+    else if (r.x.flags & 1)
     {
       errno = __doserr_to_errno(r.x.ax);
       return -1;
     }
   }
Index: djgpp/src/libc/posix/unistd/getcwd.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/unistd/getcwd.c,v
retrieving revision 1.8
diff -U 5 -r1.8 getcwd.c
--- djgpp/src/libc/posix/unistd/getcwd.c	1 Oct 2011 21:13:06 -0000	1.8
+++ djgpp/src/libc/posix/unistd/getcwd.c	2 Oct 2011 02:34:38 -0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
@@ -46,21 +47,34 @@
   if (size > __tb_size)
     size = __tb_size;
 
   /* get the path into the transfer buffer at least */
   if (use_lfn)
+  {
+    r.x.flags = 1;  /* Always set CF before calling a 0x71NN function. */
     r.x.ax = 0x7147;
+  }
   else
     r.h.ah = 0x47;
+do_getcwd:
   r.h.dl = 0;
   r.x.si = __tb_offset;
   r.x.ds = __tb_segment;
   __dpmi_int(0x21, &r);
 
-  /* current drive may be invalid (it happens) */
-  if (r.x.flags & 1)
+  if (r.x.ax == 0x7100)
+  {
+    /*  Never assume that the complete LFN API is implemented,
+        so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+        If not supported fall back on SFN API 0x47.  */
+    use_lfn = 0;
+    r.h.ah = 0x47;
+    goto do_getcwd;
+  }
+  else if (r.x.flags & 1)
   {
+    /* current drive may be invalid (it happens) */
     errno = __doserr_to_errno(r.x.ax);
     return 0;
   }
 
   /* path is ASCIIZ.  Scan it, filling in buf, watching for
Index: djgpp/src/libc/posix/unistd/rmdir.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/unistd/rmdir.c,v
retrieving revision 1.5
diff -U 5 -r1.5 rmdir.c
--- djgpp/src/libc/posix/unistd/rmdir.c	1 Oct 2011 21:13:08 -0000	1.5
+++ djgpp/src/libc/posix/unistd/rmdir.c	2 Oct 2011 02:34:38 -0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
@@ -20,20 +21,26 @@
 
   if (!__solve_dir_symlinks(mydirname, real_dir))
     return -1;
 
   if (_USE_LFN)
+  {
+    r.x.flags = 1;  /* Always set CF before calling a 0x71NN function. */
     r.x.ax = 0x713a;
+  }
   else
     r.h.ah = 0x3a;
   r.x.ds = __tb_segment;
   r.x.dx = __tb_offset;
   _put_path(real_dir);
   __dpmi_int(0x21, &r);
 
-  if (r.x.flags & 1)
+  if ((r.x.flags & 1) || (r.x.ax == 0x7100))
   {
+    /*  Never assume that the complete LFN API is implemented,
+        so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+        If not supported fail.  */
     errno = __doserr_to_errno(r.x.ax);
     return -1;
   }
   return 0;
 }

- Raw text -


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