From: sandmann AT clio DOT rice DOT edu (Charles Sandmann) Message-Id: <10108150556.AA15511@clio.rice.edu> Subject: Win2000 _open hack, rev 2 - working prototype To: acottrel AT ihug DOT com DOT au (Andrew Cottrell) Date: Wed, 15 Aug 2001 00:56:45 -0500 (CDT) Cc: djgpp-workers AT delorie DOT com, eliz AT is DOT elta DOT co DOT il (Eli Zaretskii) In-Reply-To: <015401c124c4$d13fbdd0$0a02a8c0@acceleron> from "Andrew Cottrell" at Aug 14, 2001 11:27:06 PM X-Mailer: ELM [version 2.5 PL2] Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Reply-To: djgpp-workers AT delorie DOT com Errors-To: nobody AT delorie DOT com X-Mailing-List: djgpp-workers AT delorie DOT com X-Unsubscribes-To: listserv AT delorie DOT com Precedence: bulk Test code. But I think it does what we need! 1) If SFN available from 7160 we use it. 2) If SFN name create fails, try LFN _chmod call to see if exists (this will also show existence of devices on Win2K) 3) If exists try to open with name using SFN interrupt. This should handle NUL, /dev/null (translated to NUL) or CON, etc. 4) If fail, just use LFN open call. This will then succeed for ./nul (or any-existing-directory/nul) for checking existence. If anyone fstat() the handle or dev info it it will be bogus, but this is our last shot. Note, if they call access instead we should be OK. fstat() on the handles from this code look good, as do dev info calls. What do you guys think? I can re-write this tomorrow for review if it seems sound. For files we do one extra interrupt (sfn translation). For devices 2-3 extra, but that's pretty rare. *** _open.c_ Tue Aug 14 23:14:02 2001 --- _open.c Wed Aug 15 00:50:00 2001 *************** *** 2,5 **** --- 2,6 ---- /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ + #include #include #include *************** _open(const char* filename, int oflag) *** 29,32 **** --- 30,77 ---- return rv; + if(use_lfn && _osmajor == 5 && _get_dos_version(1) == 0x532) { + /* Windows 2000 or XP; or NT with LFN TSR. Windows 2000 behaves + badly when using IOCTL and write-truncate calls on LFN handles. + We convert the long name to a short name and open existing files + via short name. New files use LFN, but we know they aren't + character devices. */ + r.x.ax = 0x7160; + r.x.cx = 1; /* Get short name equivalent */ + r.x.ds = __tb_segment; + r.x.si = __tb_offset; + r.x.es = __tb_segment; + r.x.di = __tb_offset + _put_path(filename); + __dpmi_int(0x21, &r); + if(!(r.x.flags & 1)) { + r.x.ax = 0x6c00; + r.x.bx = (oflag & 0xff); + r.x.dx = 1; /* Open existing file */ + r.x.si = r.x.di; + goto do_open; + } else { + /* If it failed, either file doesn't exist or is device */ + printf("Tried 7160 on \"%s\" and it failed (%d).\n",filename,r.x.ax); + /* r.x.ax = 0x7143; + r.h.bl = 0; + r.x.dx = __tb_offset; + _put_path(filename); + __dpmi_int(0x21, &r); + if(!(r.x.flags & 1)) { */ + if(_chmod(filename,0) != -1) { + printf("Tried 7143 on \"%s\" OK.\n",filename); + _put_path(filename); /* since printf above nuked it */ + r.x.ax = 0x6c00; + r.x.bx = (oflag & 0xff); + r.x.dx = 1; /* Open existing file */ + r.x.cx = 0; + r.x.si = __tb_offset; + __dpmi_int(0x21, &r); + if(!(r.x.flags & 1)) { /* Fail on open. Must be directory? */ + goto do_hset; + } + } + } + /* On failure we try the old way */ + } if(use_lfn) { r.x.ax = 0x716c; *************** _open(const char* filename, int oflag) *** 55,61 **** } } - r.x.cx = 0; r.x.ds = __tb_segment; _put_path(filename); __dpmi_int(0x21, &r); if(r.x.flags & 1) --- 100,107 ---- } } r.x.ds = __tb_segment; _put_path(filename); + do_open: + r.x.cx = 0; __dpmi_int(0x21, &r); if(r.x.flags & 1) *************** _open(const char* filename, int oflag) *** 64,67 **** --- 110,114 ---- return -1; } + do_hset: __file_handle_set(r.x.ax, O_BINARY); return r.x.ax;