From: sandmann AT clio DOT rice DOT edu (Charles Sandmann) Message-Id: <10108150440.AA14928@clio.rice.edu> Subject: _open.c development dif - Win2000 hacking To: djgpp-workers AT delorie DOT com (DJGPP developers) Date: Tue, 14 Aug 2001 23:40:26 -0500 (CDT) 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 Included below is the SFN open code I've been working with on Windows 2000. For existing files this causes the device info to be correct, so the device in fstat() is correct. What's interesting is on my test code I get extra 7160 failures to the screen - from fstat() ? Is this looking for magic numbers or something? More interesting stuff - if 7160 fails, but _chmod succeeds I think this is a way under Windows 2000 to know it's a device! One thing I need to know - how do people use the directoryname/nul detection to determine if a directory exists? This works fine with LFN handles but not with SFN handles. 7143 also gets attrs OK. So, if I force all device _open() calls to SFN then _open() would fail. If _open() works then the dev info will be bogus. Better to fail (not support dirname/nul) or better to have it succeed and cause dev info problems later (appear as a disk file instead of a device). *** _open.c Tue Aug 14 23:14:02 2001 --- _openn.c Tue Aug 14 23:02:30 2001 *************** *** 1,6 **** --- 1,7 ---- /* 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 #include #include #include *************** _open(const char* filename, int oflag) *** 28,33 **** --- 29,58 ---- if (__FSEXT_call_open_handlers(__FSEXT_open, &rv, &filename)) 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 { + printf("Tried 7160 and it failed (%d).\n",r.x.ax); + } + /* On failure we try the old way */ + } if(use_lfn) { r.x.ax = 0x716c; r.x.bx = (oflag & 0xff); *************** _open(const char* filename, int oflag) *** 54,62 **** r.x.dx = __tb_offset; } } - r.x.cx = 0; r.x.ds = __tb_segment; _put_path(filename); __dpmi_int(0x21, &r); if(r.x.flags & 1) { --- 79,88 ---- r.x.dx = __tb_offset; } } r.x.ds = __tb_segment; _put_path(filename); + do_open: + r.x.cx = 0; __dpmi_int(0x21, &r); if(r.x.flags & 1) {