Mail Archives: djgpp-workers/2001/01/05/13:45:40
While I'm very satisfied with your work, Norberto, yet another case
has dawned on me: DVD-drives.
WINDOZE 98 says "4 634 253 213 bytes 	4,31GB" when I select
properies of my R: drive when it contains a DVD-ROM. Interestingly, if
I in EXPLORER select everything and right-click properties WINDOZE
says "Size: 	4,31GB (4 634 200 064), 4 634 476 544
bytes". Meanwhile WINDOZE "dir /v" says
" Volume in drive R is FOURWEDDING
 Volume Serial Number is 9688-FAFF
 Directory of R:\
File Name         Size        Allocated      Modified      Accessed Attrib
AUDIO_TS       <DIR>                      00-08-09  15.56  00-08-09  R  DA
AUDIO_TS
VIDEO_TS       <DIR>                      00-08-09  16.46  00-08-09  R  DA
VIDEO_TS
         0 file(s)              0 bytes
         2 dir(s)            0.00 MB free
                         4 419.57 MB total disk space, 100% in use".
So we have several right values...
Alas df compiled with our latest (the one you have made) statfs.c says
"FOURWEDDINGS         2295300 2295300        0    100%   r:/".
The one from fil316b.zip says
"FOURWEDDINGS         2295300 2295300        0    100%   r:/" so there
has been no regression.
However if I try the INT21 AX=7303 on R: I get:
"r:/ -> 0, (0), bsize = 2048, blocks = 2262819, bfree = 0." which
evaluates to 4 634 253 312 which is in accordance with the first
WINDOZE value above. (Program source last in this message.)
It would be neat if we could make this work also.
In statfs.c there is this text:
  /* For a CD-ROM drive, Int 21h/AX=3600h gives incorrect info.
     Use CD-ROM-specific calls if they are available.
     Int 2Fh/AX=1510h gives us a way of doing IOCTL with the
     CD-ROM device driver without knowing the name of the
     device (which is defined by the CONFIG.SYS line that
     installs the driver and can therefore be arbitrary).  */
So I ask the list on which platforms does Int 21h/AX=3600h give
incorrect info?
My testing seems to say that in (WINDOZE 98's) plain DOZE mode does
not support INT21 AX=7303/7302. So there we must fall back to the
earlier methods.
Right,
						MartinS
#include <stdio.h>
#include <errno.h>
#include <sys/vfs.h>
#include <libc/farptrgs.h>
#include <libc/dosio.h>
#include <go32.h>
#include <dpmi.h>
int my_statfs( char * path, struct statfs *buf )
{
  __dpmi_regs regs;
  int drive_number;
  long blocks = 0;
  long freec = 0;
  long bsize = 0;
  /* First try 217303 as 217302 reports fake free space
     (largest block of free clusters?) */
  _put_path( path );
  drive_number = (_farpeekb(_dos_ds, __tb) & 0x1f) - 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; /* 256 bytes should be enough (RBIL says
0x3f). */
  __dpmi_int (0x21, ®s);
  /* Errors? (217303 seams to fail under plain DOS) */
  if (regs.x.flags & 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 );
    }
    freec = _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 );
    blocks = _farpeekl( _dos_ds, __tb + 0x2 + 0x2d) - 1;
#if 0
      printf("Second: bsize = %ld, free = %ld, blocks = %ld.\n"
           , bsize
           , freec
           , blocks
             );
#endif
  }
  else
  {
    freec  = _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("Third: bsize = %ld, free = %ld, blocks = %ld.\n"
           , bsize
           , freec
           , blocks
             );
#endif
  }
  /* Fill in the structure */
  buf->f_bavail = freec;
  buf->f_bfree = freec;
  buf->f_blocks = blocks;
  buf->f_bsize = bsize;
  buf->f_ffree = freec;
  buf->f_files = blocks;
  buf->f_type = 0;
  buf->f_fsid[0] = drive_number;
  buf->f_fsid[1] = MOUNT_UFS;
  buf->f_magic = FS_MAGIC;
  return( 0 );
}
int main(void)
{
  int ret;
  struct statfs s;
  ret = my_statfs("c:/", &s);
  printf("c:/ -> %d, (%d), bsize = %ld, blocks = %ld, bfree = %ld.\n",
ret, errno, s.f_bsize, s.f_blocks, s.f_bfree);
  ret = my_statfs("d:/", &s);
  printf("d:/ -> %d, (%d), bsize = %ld, blocks = %ld, bfree = %ld.\n",
ret, errno, s.f_bsize, s.f_blocks, s.f_bfree);
  ret = my_statfs("f:/", &s);
  printf("f:/ -> %d, (%d), bsize = %ld, blocks = %ld, bfree = %ld.\n",
ret, errno, s.f_bsize, s.f_blocks, s.f_bfree);
  ret = my_statfs("g:/", &s);
  printf("g:/ -> %d, (%d), bsize = %ld, blocks = %ld, bfree = %ld.\n",
ret, errno, s.f_bsize, s.f_blocks, s.f_bfree);
  ret = my_statfs("r:/", &s);
  printf("r:/ -> %d, (%d), bsize = %ld, blocks = %ld, bfree = %ld.\n",
ret, errno, s.f_bsize, s.f_blocks, s.f_bfree);
  ret = my_statfs("u:/", &s);
  printf("u:/ -> %d, (%d), bsize = %ld, blocks = %ld, bfree = %ld.\n",
ret, errno, s.f_bsize, s.f_blocks, s.f_bfree);
  return(0);
}
- Raw text -