From: Martin Str|mberg Message-Id: <200101051844.TAA15180@father.ludd.luth.se> Subject: Re: Fw: Patch for statfs.c In-Reply-To: <3A507A90.1936F0D6@softhome.net> from Laurynas Biveinis at "Jan 1, 2001 01:39:44 pm" To: djgpp-workers AT delorie DOT com Date: Fri, 5 Jan 2001 19:44:26 +0100 (MET) Cc: ceo AT nbensacomputers DOT com X-Mailer: ELM [version 2.4ME+ PL54 (25)] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Reply-To: djgpp-workers AT delorie DOT com Errors-To: nobody AT delorie DOT com X-Mailing-List: djgpp-workers AT delorie DOT com X-Unsubscribes-To: listserv AT delorie DOT com Precedence: bulk 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 00-08-09 15.56 00-08-09 R DA AUDIO_TS VIDEO_TS 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 #include #include #include #include #include #include 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); }