home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Zodiac Super OZ
/
MEDIADEPOT.ISO
/
FILES
/
16
/
UDISK.ZIP
/
UDISK.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-13
|
7KB
|
223 lines
/*
╔════════════════════════════════════════╗
║ UDISK ║
║ Copyright (c) 1996 L.I.Williams ║
║ All rights reserved ║
║ Issue 1.0 Date: 13Jul96 ║
╚════════════════════════════════════════╝
*~ UDISK.C
*~ 08Jul96 Iss 1.0 Created by LIW
*~ Reports disk size, space used and free
*~ Use CL /AT /W4 UDISK.C to compile this file
*~
*/
/***********************************************************************
* HISTORY:
* Date Iss Who Comment
* 08Jul96 1.0 LIW Created
***********************************************************************/
/* Include files: */
#include <stdio.h>
#include <dos.h>
#include <string.h>
#include <process.h>
#include <stdlib.h>
#include <setjmp.h>
/* global variables */
char error_handler[4] = { 0xb8, 0, 0, 0xcf };
union REGS iregs, oregs;
struct SREGS segregs;
/* prototypes */
void print_size(long);
void drv_info(int);
void explain(void);
/***********************************************************************
* main sorts out error handling and calls drv_info for each drive
***********************************************************************/
void main(int argc, char *argv[])
{
int drives;
unsigned int olderr_offset, olderr_segment;
int i;
/* initialize for error handling */
iregs.x.ax = 0x3524; /* get error handler vector */
intdosx(&iregs, &oregs, &segregs);
olderr_offset = oregs.x.bx;
olderr_segment= segregs.es;
segread(&segregs); /* pick up segment registers */
iregs.x.ax = 0x2524; /* set our error handler vector */
iregs.x.dx = (unsigned int)error_handler;
intdosx(&iregs, &oregs, &segregs);
/* sort out command */
if (argc > 1)
{
explain();
exit(1);
}
/* determine number of logical drives in system */
iregs.h.ah = 0x19; /* get current disk */
intdos(&iregs, &oregs);
iregs.h.dl = oregs.h.al;
iregs.h.ah = 0x0e; /* select disk */
intdos(&iregs, &oregs);
drives = oregs.h.al;
/* this is the number of drives set by lastdrive, default 5 */
printf ("\nUDISK 1.0, Freeware, (c) 1996 L. I. Williams.\n");
printf ("\n Disk Usage Information\n\n");
printf("Drive Volume Total Space Used Space Free Space Used%% Free%%\n\n");
/* now output drive info */
for (i = 0; i < drives; i++)
drv_info(i);
printf("\
\n\
/? for help. (1k=1000 not 1024 1m=1,000,000 not 1,048,576)\n\
");
/* restore vector for error handling */
iregs.x.ax = 0x2524; /* get error handler vector */
oregs.x.dx = olderr_offset;
segregs.ds = olderr_segment;
intdosx(&iregs, &oregs, &segregs);
exit(0);
}
/***********************************************************************
drv_info. Information for each drive if present
***********************************************************************/
void drv_info(int drive)
{
long total, free, used;
double percent;
struct find_t find;
int found;
char *p;
int i;
char spec[20];
char ch;
struct diskfree_t drvinfo;
/*
Try to print the statistics. When a non-existant drive is read the
operating system calls its fatal error handler (via INT 24h). This
has been redirected and returns, this routine returns too, and the
drive is skipped.
*/
if (_dos_getdiskfree( drive+1, &drvinfo )!=0)
return;
total = (long)drvinfo.total_clusters *
(long)drvinfo.sectors_per_cluster *
(long)drvinfo.bytes_per_sector;
free = (long)drvinfo.avail_clusters *
(long)drvinfo.sectors_per_cluster *
(long)drvinfo.bytes_per_sector;
used = total - free;
/* Output disk letter. numeric 0 = drive A */
printf(" %c: ", drive + 'A');
/* Scan files in root directory of disk for one with volume id
attribute. It's name is the disk label. Find first matching file,
then find additional matches. */
sprintf(spec,"%c:\\*.*",drive + 'A'); /* pathname of root */
found = !_dos_findfirst( spec, 0xffff, &find ); /* first file name */
while (found)
{
if ( find.attrib & _A_VOLID ) /* is it the volume id ? */
break; /* yes, leave loop */
found = !_dos_findnext( &find ); /* no, try another */
}
*spec = '\0'; /* preset null string */
if (found) /* did we get it ? */
{
p = spec; /* yes, copy name, ommiting '.' character */
for (i=0;i<=14;i++)
{
ch = find.name[i];
if (ch != '.')
*p++=ch; /* copy non '.' characters */
if (ch == '\0') /* stop after null */
break;
}
}
printf( "%-13s",spec); /* output name or null to 13 spaces */
print_size(total);
print_size(used);
print_size(free);
percent = (double)used / (double)total * 100.0;
printf(" %5.0f%% ", percent);
percent = (double)free / (double)total * 100.0;
printf("%5.0f%%\n", percent);
/* Try to deal with CDROM, network drives etc. This does not work if
there is no CD in the drive, so commented out.
iregs.h.ah = 0x44; determine if unusual drive
iregs.h.al = 0x09;
iregs.h.bl = drive +1;
intdos(&iregs,&oregs);
if (oregs.x.dx & 0x1000)
{
sprintf(spec,"vol %c:",drive + 'A');
system(spec);
printf("\n");
}
*/
}
/***********************************************************************
prints a disk size in a sensible way
***********************************************************************/
void print_size(long n)
{
if (n >= 10000000) /* 10m or more */
printf("%7.0fm ",(double)n/1000000.0);
else if (n >= 1000000) /* 1m to 10m */
printf("%7.1fm ",(double)n/1000000.0);
else if (n >= 10000) /* 10k to 999k */
printf("%7.0fk ",(double)n/1000);
else /* < 10k */
printf("%7ld ",n);
printf(" ");
}
/***********************************************************************
Help output
***********************************************************************/
void explain(void)
{
char filebuf[80];
_searchenv( "MORE.COM", "PATH", filebuf );
if (*filebuf)
{
_searchenv( "UDISK.DOC", "PATH", filebuf );
if (*filebuf)
{
system("type UDISK.DOC | more");
exit(0);
}
}
printf("See the documentation file 'UDISK.DOC' for more information.\n");
}
/***********************************************************************
End of code
***********************************************************************/