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 #include #include #include #include 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======