Mail Archives: djgpp-workers/2000/12/30/01:57:17
Hi Martin! Hi everyone!
Ok, I think I got it... now with network drives support.
From: "Martin Stromberg" <eplmst AT lu DOT erisoft DOT se>
> > 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------------
- Raw text -