www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2001/01/26/17:06:49

From: skb AT xmission DOT com (Scott Brown)
Newsgroups: comp.os.msdos.djgpp
Subject: getdfree fails & long longs interfere with DOS interrupt call
Date: Fri, 26 Jan 2001 21:57:09 GMT
Organization: (none)
Lines: 104
Message-ID: <3a71e643.26318843@news.xmission.com>
NNTP-Posting-Host: 144.35.126.99
X-Trace: news.xmission.com 980546131 27777 144.35.126.99 (26 Jan 2001 21:55:31 GMT)
X-Complaints-To: abuse AT xmission DOT com
NNTP-Posting-Date: 26 Jan 2001 21:55:31 GMT
X-Newsreader: Forte Free Agent 1.11/32.235
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

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.

I wrote a function that calls the Win9x FAT32 extended-free-space
function (int 0x21, func 0x7303).  It works, but I've found that it
can be made to fail by making unrelated changes in the calling
function (in this case, main).

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.  I found an article indicating
that long long isn't well-supported by djgpp's COFF output, but I
don't pretend to really understand what that means, either.

Anyway, I'm posting my program below.  If anyone can point out where I
went wrong, I would really appreciate it.

Thanks,
-Scott



======cut here======
#include <stdio.h>
#include <dpmi.h>
#include <dir.h>
#include <go32.h>
#include <ctype.h>

struct dj_dfree {
	unsigned long df_avail;  /* Available clusters */
	unsigned long df_total;  /* Total clusters */
	unsigned long df_bsec;   /* Bytes per sector */
	unsigned long df_sclus;  /* Sectors per cluster */
};


void dj_getdfree(unsigned char drive, struct dj_dfree *dtable) {
	__dpmi_regs r;
	char path[] = "X:\\";
	unsigned char buffer[44];

	dtable->df_sclus = -1;

	/* set up the drive name buffer */
	if (drive == 0) drive = getdisk() + 1;
	path[0] = drive + 'A' - 1;

	*(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;

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

	if (r.x.flags & 1) {
		printf("error %li\n", (long)r.x.ax);  /*FIXME*/
	} else {
		dtable->df_avail = *(unsigned long *)(buffer + 12);
		dtable->df_total = *(unsigned long *)(buffer + 16);
		dtable->df_bsec = *(unsigned long *)(buffer + 8);
		dtable->df_sclus = *(unsigned long *)(buffer + 4);
	}
}



#if 0  /* use long long */
	typedef long long DTYPE;
#else  /* use double */
	typedef float DTYPE;
#endif


int main(int argc, char **argv) {
	struct dj_dfree df;
	int drv = 0;
	DTYPE csize, total, avail;

	if (argc >= 2) drv = toupper(*argv[1]) - 'A' + 1;

	dj_getdfree(drv, &df);

	csize = (DTYPE)df.df_bsec * (DTYPE)df.df_sclus;
	total = csize * (DTYPE)df.df_total;
	avail = csize * (DTYPE)df.df_avail;

	printf("Cluster size = %.0f\n", (double)csize);
	printf("Total %12.0f\n", (double)total);
	printf(" Free %12.0f\n", (double)avail);
	return 0;
}
======cut here======

- Raw text -


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