X-Authentication-Warning: new-smtp2.ihug.com.au: Host p18-max14.syd.ihug.com.au [203.173.154.18] claimed to be acceleron Message-ID: <00de01c12d06$82e2cd40$0a02a8c0@acceleron> From: "Andrew Cottrell" To: , "Charles Sandmann" Cc: Subject: Read 3F00 STDIN problem on Win 2K ( was Re: Fseek on STDIN problem on Win 2K) Date: Sat, 25 Aug 2001 11:37:13 +1000 MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 5.50.4807.1700 X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4807.1700 Reply-To: djgpp-workers AT delorie DOT com > > > > fstat() doesn't cause this problem in 2.03 which might explain why > > > > it's more rare). > > > > > > So perhaps we should find out which change since v2.03 triggers this. > > > > Yes. > From my test above 203 also exhibits the problem. Probably the reason 203 > does not show up the problem in is_executable() is that thre are other calls > somewhere else in the code that "fix" the problem, in a similar way to when > the extra call to 4200 is inserted into the sample code. > > I wonder if the 3700 call is broken in Windows 2K. I am going to have a look > at this and get back with my results in a few hours. > I may be going off on a tangent, but it will only take a few hours to check > and satisfy my hunch. Sorry the call is 3F00 not 3700. And my hunch is correct in that the 3F00 call is broken on WIn 2K and it depends on what other calls are made after this as to whether thje problem is seen or not. This is why you go nuts trying to figure out why it works and then it does not etc.... grrr MS... or if you try it in another app or in another package it stops working or starts working. I have greped the LIBC and the places that call 3F00 are: a) is_exec.c b) _read.c c) d_read.c d) int86.c A quick fix is outlined below thanks to Charles finding that a fix for is_executable() is to add a call to 4201 with an offset of 0 after the 3F00 call, this also fixes _read(). If this is okay I can also include a similar change to d_read.c and int86.c What do people think about this? A proposal to fix this is to modify _read.c and is_exec.c as follows: *** _read_orig.c Sun Mar 11 00:08:58 2001 --- _read.c Sat Aug 25 11:11:18 2001 *************** *** 1,3 **** --- 1,4 ---- + /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ #include #include *************** *** 7,12 **** --- 8,15 ---- #include #include #include + #include + #include #include *************** *** 17,22 **** --- 20,26 ---- int ngot; unsigned long tbsize; __dpmi_regs r; + unsigned use_lfn = _USE_LFN; __FSEXT_Function *func = __FSEXT_get_function(handle); if (func) *************** *** 48,52 **** --- 52,73 ---- dosmemget(__tb, k, buffer); buffer = (void *)((int)buffer + k); } while(count && j == k); /* if not == on DOS then no more */ + + 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 3F00 call. We need to seek to the current + position in order for subseqent calls to work. */ + memset(&r,0,sizeof(r)); + r.x.ax = 0x4201; /* 4201h current file position */ + r.x.bx = handle; /* BX = file handle */ + r.x.cx = r.x.dx =0; /* CX:DX = (signed) offset from origin of new file position */ + __dpmi_int(0x21, &r); + if (r.x.flags & 1) + { + errno = __doserr_to_errno(r.x.ax); + return -1; + } + } return ngot; } *** is_exec_orig.c Sat Aug 25 11:15:22 2001 --- is_exec.c Sat Aug 25 11:14:06 2001 *************** *** 1,3 **** --- 1,4 ---- + /* 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 */ /* IS_EXEC.C *************** *** 26,31 **** --- 27,35 ---- #include #include #include + #include + #include + extern unsigned short _djstat_flags; unsigned short _get_magic(const char *, int); *************** *** 45,50 **** --- 49,55 ---- unsigned short retval; unsigned short fpos_high = 0, fpos_low = 0; int read_fail = 0; + unsigned use_lfn = _USE_LFN; /* If given a pathname, open the file. */ if (s) *************** *** 91,96 **** --- 96,120 ---- or (3) fail to read at all. */ if (regs.x.ax != 2) read_fail = (regs.x.flags & 1) ? regs.x.ax : -1; + else + { + 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 3F00 call. We need to seek to the current + position in order for subseqent calls to work. */ + memset(®s,0,sizeof(regs)); + regs.x.ax = 0x4201; /* 4201h current file position */ + regs.x.bx = fh; /* BX = file handle */ + regs.x.cx = regs.x.dx =0; /* CX:DX = (signed) offset from origin of new file position */ + __dpmi_int(0x21, ®s); + if (regs.x.flags & 1) + { + errno = __doserr_to_errno(regs.x.ax); + return 0; + } + } + } /* If called with filename, close the file. */ if (s)