delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2001/01/27/03:35:46

Date: Sat, 27 Jan 2001 10:34:39 +0200
From: "Eli Zaretskii" <eliz AT is DOT elta DOT co DOT il>
Sender: halo1 AT zahav DOT net DOT il
To: skb AT xmission DOT com (Scott Brown)
Message-Id: <7458-Sat27Jan2001102214+0200-eliz@is.elta.co.il>
X-Mailer: Emacs 20.6 (via feedmail 8.3.emacs20_6 I) and Blat ver 1.8.6
CC: djgpp AT delorie DOT com
In-reply-to: <3a71e643.26318843@news.xmission.com> (skb@xmission.com)
Subject: Re: getdfree fails & long longs interfere with DOS interrupt call
References: <3a71e643 DOT 26318843 AT news DOT xmission DOT com>
Reply-To: djgpp AT delorie DOT com
Errors-To: nobody AT delorie DOT com
X-Mailing-List: djgpp AT delorie DOT com
X-Unsubscribes-To: listserv AT delorie DOT com

> From: skb AT xmission DOT com (Scott Brown)
> Newsgroups: comp.os.msdos.djgpp
> Date: Fri, 26 Jan 2001 21:57:09 GMT
> 
> First off, is getdfree really broken when run against large FAT32
> drives?  I can't get it to report more than 2Gb for any drive.

getdfree calls function 36h of Int 21h, and that function doesn't
support FAT32 drives.

DJGPP v2.03 doesn't support FAT32, but the current development sources
do include that support, although not in getdfree.

> My first test program used doubles to calculate and display the total
> space/free space reported by my getdfree function.  When I changed
> main to use 'long long' instead of 'double', my getdfree function
> stopped working -- __dpmi_int succeeds, but the returned cflag
> indicates an error, and AX contains an invalid error code.
> 
> I don't understand what's happening.

Your program has a bug, which makes it behave unpredictably, depending
on what random garbage do you have in memory.  Changing the type of a
variable shifts the other variables in memory, so the random garbage
is different and you get different behavior.  On my machine, your
program doesn't work even with float's.  See below.

> I found an article indicating that long long isn't well-supported by
> djgpp's COFF output

I'm not aware of any problems with long long support in DJGPP.

> 	*(unsigned short *)(buffer) = 0;
> 
> 	dosmemput(path, sizeof(path), __tb);
> 	dosmemput(buffer, sizeof(buffer), __tb + sizeof(path));
> 
> 	r.x.ax = 0x7303;
> 	r.x.dx = __tb;
> 	r.x.di = __tb + sizeof(path);
> 	r.x.cx = sizeof(buffer);
> 	if (__dpmi_int(0x21, &r)) return;

This is wrong.  Function 7303h needs the _second_ 16-bit word of the
buffer to be zeroed out, but you only zero out the first 16-bit word
of your buffer[] variable.  This leaves the second word at random
value (whatever was on the stack).

In addition, 7303h needs DS:DX to point to the drive string in the
transfer buffer, and ES:DI to point to the data buffer in the transfer
buffer, but your program didn't assign anything to DS and ES.

Here's the correct way of doing this:

	buffer[2] = buffer[3] = 0;

	dosmemput(path, sizeof(path), __tb);
	dosmemput(buffer, sizeof(buffer), __tb + sizeof(path));

	r.x.ax = 0x7303;
	r.x.ds = r.x.es = __tb >> 4;
	r.x.dx = __tb & 15;
	r.x.di = (__tb & 15) + sizeof(path);
	r.x.cx = sizeof(buffer);
	if (__dpmi_int(0x21, &r)) return;

This works for me, both with float's and with long long's.

Note that on some Windows 9X systems, if the DOS box loads a TSR that
hooks Int 21h, the reported values will never exceed 2GB.  This is a
Windows misfeature/bug, mentioned in RBIL.

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019