X-Originating-IP: [200.42.4.138] From: "Norberto Alfredo Bensa" To: "Martin Stromberg" Cc: References: <200012291357 DOT OAA08308 AT lws256 DOT lu DOT erisoft DOT se> Subject: Re: Fw: Patch for statfs.c Date: Sat, 30 Dec 2000 03:52:55 -0300 Organization: nBens@ Computers X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 5.50.4522.1200 X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4522.1200 Message-ID: X-OriginalArrivalTime: 30 Dec 2000 06:56:26.0546 (UTC) FILETIME=[A0EE9920:01C0722D] Reply-To: djgpp-workers AT delorie DOT com Hi Martin! Hi everyone! Ok, I think I got it... now with network drives support. From: "Martin Stromberg" > > BTW, what does rescaling do? You're calling two services (2136 and > > It's been a while but I think it had something to do with me noticing > that INT 21, AX=0x7302 wasn't quite accurate so I falled back to the ahhhh... that's it!... 322197*4096/32768 isn't integer, i.e. 322197 is not a power of 2!!!... Can you please tell me if you remember at least one case where 217302 wasn't giving accurate info? I have "#if 0...#endif"the rescaling for now, but it *must* be tested. > > Yes, but on the network drives... > I think I got it... test it please. Best regards, Norberto Now the patch... ------CUT---------8<---------CUT------------ --- src/libc/compat/sys/vfs/statfs.c.~ Mon Jun 19 19:00:56 2000 +++ src/libc/compat/sys/vfs/statfs.c Sat Dec 30 02:41:26 2000 @@ -108,73 +108,116 @@ if (!cdrom_calls_used) { - /* Get free space info from DOS. */ - regs.h.ah = 0x36; /* DOS Get Free Disk Space call */ - regs.h.dl = drive_number + 1; - __dpmi_int(0x21, ®s); - - /* Check for errors */ - if ((regs.x.ax & 0xffff) == 0xffff) - { - errno = ENODEV; - return -1; - } - bsize = regs.x.cx * regs.x.ax; - free = regs.x.bx; - blocks = regs.x.dx; -#if 0 - printf("First: bsize = %ld, free = %ld, blocks = %ld.\n" - , bsize - , free - , blocks - ); -#endif - if( 7 <= (_get_dos_version(1) >> 8) /* Is FAT32 supported? */ +#if 0 && _is_fat32(drive_number + 1) /* Is it a FAT32 drive? */ +#endif ) { - /* Get free space info from Extended Drive Parameter Block. */ - regs.x.ax = 0x7302; - regs.h.dl = drive_number + 1; - regs.x.es = __tb_segment; - regs.x.di = __tb_offset; - regs.x.cx = 0x100; /* 256 bytes should be enough (RBIL says 0x3f). */ - __dpmi_int(0x21, ®s); + /* 217303 - Win9x - Get Extended Free Drive Space: + Extended Drive Paramenter Block, seams to report the largest + block of free clusters when running under Windows (this info + is not confirmed), so I'm using this service here. BTW, it + expects a path on DS:DX and should be not an empty string or + the sevice will fail */ + if (path && !*path) + _put_path ("/"); + else + _put_path (path); - /* Errors? */ - if( regs.x.flags & 1 ) + regs.x.ax = 0x7303; + regs.x.ds = regs.x.es = __tb_segment; + regs.x.dx = regs.x.di = __tb_offset; + regs.x.cx = 0x100; /* Buffer lenght. Actually ~70 bytes would be enough */ + __dpmi_int (0x21, ®s); + + /* On plain DOS, 217303 fails (?), so here comes the old code. + Under DOS, ExtDPB returns "accurate" info (!?) */ + if (regs.x.flags & 1) { - errno = ENODEV; - return( -1 ); - } + /* Get free space info from Extended Drive Parameter Block. */ + regs.x.ax = 0x7302; + regs.h.dl = drive_number + 1; + regs.x.es = __tb_segment; + regs.x.di = __tb_offset; + regs.x.cx = 0x100; /* 256 bytes should be enough (RBIL says 0x3f). */ + __dpmi_int(0x21, ®s); + + /* Errors? */ + if( regs.x.flags & 1 ) + { + errno = ENODEV; + return( -1 ); + } - /* We trust previous int21 call more if free hasn't maxed out. */ - if( free < blocks ) +#if 0 + /* We trust previous int21 call more if free hasn't maxed out. */ + if( free < blocks ) + { + /* Previous bsize is a multiple of this bsize, so the multiplication + and division here is really a rescaling of the previous free + value. */ + free *= bsize; + bsize = _farpeekw (_dos_ds, __tb + 0x2 + 0x2) * + ( _farpeekb (_dos_ds, __tb + 0x2 + 0x4) + 1 ); + free /= bsize; + } + else +#endif + { + free = _farpeekl (_dos_ds, __tb + 0x2 + 0x1f); + bsize = _farpeekw (_dos_ds, __tb + 0x2 + 0x2) * + ( _farpeekb (_dos_ds, __tb + 0x2 + 0x4) + 1 ); + } + + /* -1, because it was reporting 1 more cluster than CHKDSK, + again, this information is not confirmed */ + blocks = _farpeekl( _dos_ds, __tb + 0x2 + 0x2d) - 1; +#if 0 + printf("217302: bsize = %ld, free = %ld, blocks = %ld.\n" + , bsize + , free + , blocks + ); +#endif + } + else /* Use information from service 217303 */ { - /* Previous bsize is a multiple of this bsize, so the multiplication - and division here is really a rescaling of the previous free - value. */ - free *= bsize; - bsize = _farpeekw (_dos_ds, __tb + 0x2 + 0x2) * - ( _farpeekb (_dos_ds, __tb + 0x2 + 0x4) + 1 ); - free /= bsize; + free = _farpeekl (_dos_ds, __tb + 0x0c); + bsize = _farpeekl (_dos_ds, __tb + 0x08) + * _farpeekl (_dos_ds, __tb + 0x04); + blocks = _farpeekl (_dos_ds, __tb + 0x10); +#if 0 + printf("217303: bsize = %ld, free = %ld, blocks = %ld.\n" + , bsize + , free + , blocks + ); +#endif } - else + } + else /* DOS version is < 7 */ + { + /* Get free space info from DOS. */ + regs.h.ah = 0x36; /* DOS Get Free Disk Space call */ + regs.h.dl = drive_number + 1; + __dpmi_int(0x21, ®s); + + /* Check for errors */ + if ((regs.x.ax & 0xffff) == 0xffff) { - free = _farpeekw (_dos_ds, __tb + 0x2 + 0x1f) + - 65536 * _farpeekw (_dos_ds, __tb + 0x2 + 0x21); - bsize = _farpeekw (_dos_ds, __tb + 0x2 + 0x2) * - ( _farpeekb (_dos_ds, __tb + 0x2 + 0x4) + 1 ); + errno = ENODEV; + return -1; } - - blocks = _farpeekl( _dos_ds, __tb + 0x2 + 0x2d); + bsize = regs.x.cx * regs.x.ax; + free = regs.x.bx; + blocks = regs.x.dx; #if 0 - printf("Second: bsize = %ld, free = %ld, blocks = %ld.\n" - , bsize - , free - , blocks - ); + printf("2136: bsize = %ld, free = %ld, blocks = %ld.\n" + , bsize + , free + , blocks + ); #endif } } ------CUT---------8<---------CUT------------