X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f From: "Wiktor S. (wswiktorSP AT Mpoczta DOT fm) [via djgpp AT delorie DOT com]" Newsgroups: comp.os.msdos.djgpp Subject: a patch for LFN on exFAT Date: Sat, 14 May 2016 19:24:45 +0200 Organization: INTERIA.PL S.A. Lines: 91 Message-ID: NNTP-Posting-Host: user-109-243-236-184.play-internet.pl Mime-Version: 1.0 Content-Type: text/plain; format=flowed; charset="utf-8"; reply-type=original Content-Transfer-Encoding: 7bit X-Trace: usenet.news.interia.pl 1463246688 6310 109.243.236.184 (14 May 2016 17:24:48 GMT) X-Complaints-To: usenet AT firma DOT interia DOT pl NNTP-Posting-Date: Sat, 14 May 2016 17:24:48 +0000 (UTC) X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2900.5931 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.6157 Bytes: 3447 To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com This patch fixes fopen() with LFN on filesystems that do not have short aliases for long names, like exFAT. I have rebuild textutils with this patch, and now cat works properly: ============= C:\>cat g:\longdirectoryname\longfilename.txt c:/djtest/bin/cat.exe: g:\longdirectoryname\longfilename.txt: Permission denied (EACCES) C:\>djtest\gnu\txtutil2.0\src\cat g:\longdirectoryname\longfilename.txt It works. ============= However, it is still not possible to do system("longfilename.exe") or system("longpathname\short.exe") on exFAT. I don't know if it is possible to execute a program using its long name only. ============= ffa8b583c4a1e552b5a9582a81b0785bf78199ee _open.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/_open.c b/_open.c index 61d5b1a..18bde56 100644 --- a/_open.c +++ b/_open.c @@ -1,3 +1,4 @@ +/* Copyright (C) 2016 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 2014 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */ @@ -17,12 +18,17 @@ #include #include +typedef enum { + false = 0, true = 1 +} bool; + int _open(const char* filename, int oflag) { __dpmi_regs r; int rv; int use_lfn = _USE_LFN; + bool retry_with_lfn = false; if (filename == 0) { @@ -50,6 +56,7 @@ _open(const char* filename, int oflag) __dpmi_int(0x21, &r); if (!(r.x.flags & 1)) /* Get short name success */ { + retry_with_lfn = true; r.x.ax = 0x6c00; r.x.bx = (oflag & 0xff); r.x.dx = 1; /* Open existing file */ @@ -83,6 +90,7 @@ _open(const char* filename, int oflag) } } } +fallback: if (use_lfn) { r.x.flags = 1; /* Always set CF before calling a 0x71NN function. */ @@ -136,6 +144,14 @@ do_open: } else if (r.x.flags & 1) { + if ((r.x.ax == 2 || r.x.ax == 3) && retry_with_lfn) + { + /* On exFAT partitions files and paths with long names do not have 8.3 + aliases. If an attempt to open the file with short name failed with + "file not found" or "path not found", retry with LFN API. */ + retry_with_lfn = false; + goto fallback; + } errno = __doserr_to_errno(r.x.ax); return -1; }