home *** CD-ROM | disk | FTP | other *** search
- program DisplayWaste;
- uses
- dos;
-
- Var
- ClusterSize : word;
- TotalFiles,
- TotalBytes,
- TotalClusters : longint;
-
- procedure showhelp(const problem :byte);
- (* If any *foreseen* errors arise, we are sent here to
- give a little help and exit (relatively) peacefully *)
- const
- progdesc = 'DiskWaste v1.02 - Free DOS utility: Display disk space wasted by small files.';
- author = 'July 3, 1995. Copyright (c) 1995 by David Daniel Anderson - Reign Ware.';
- usage1 = 'Usage: DWaste <[drive:][\]directory\[filespec]>';
- usage2 = ' -OR- DWaste <filespec>';
- usage3 = ' -OR- DWaste <drive:>';
- notes1 = 'Notes: Anything bounded by square brackets ([ & ]) is optional.';
- notes2 = ' If you specify a directory, it MUST be followed by a backslash (\).';
- examples = 'Examples:';
- examp1 = ' DWaste c:\dos\*.com';
- examp2 = ' DWaste e:\speed\';
- examp3 = ' DWaste *.bat';
- examp4 = ' DWaste d:';
- var
- message : string[50];
- begin
- writeln(progdesc);
- writeln(author); writeln;
- writeln(usage1);
- writeln(usage2);
- writeln(usage3); writeln;
- writeln(notes1);
- writeln(notes2); writeln;
- writeln(examples); writeln;
- writeln(examp1);
- writeln(examp2);
- writeln(examp3);
- writeln(examp4); writeln;
- if problem > 0 then begin
- case problem of
- 1 : message := 'Invalid drive.';
- else message := 'Unanticipated error of unknown type.';
- end;
- writeln (#7,message);
- end;
- halt(problem)
- end;
-
- Function RPad(bstr: string; Const len: byte): string;
- Begin
- while (length(bstr) < len) do
- bstr := bstr + #32;
- RPad := bstr;
- End;
-
- function comma (num :longint):string; {insert commas to break up number string}
- var s : string[14];
- l : shortint;
- begin
- str (num, s);
- l:=(length (s)-2);
- while (l > 1) do begin
- insert (',', s, l);
- dec (l, 3);
- end;
- comma:=s;
- end;
-
- { SWAG routine }
- function getclustersize (drive :byte):word;
- var
- regs : registers;
- begin
- regs.cx := 0; {set for error-checking just to be sure}
- regs.ax := $3600; {get free space}
- regs.dx := drive; {0=current, 1=a:, 2=b:, etc.}
- msdos (regs);
- getclustersize := regs.ax * regs.cx; {cluster size!}
- end;
-
- { Author: Greg Estabrooks }
- { For: GetDrive, ChangeDrive, NumDrives }
- Function GetDrive :Byte;
- Var (* Routine to determine the default drive *)
- Regs :Registers; (* To hold register info for Intr() *)
- begin
- Regs.AX := $1900; (* Function to determine drive *)
- Intr($21,Regs); (* Call Dos Int 21h *)
- GetDrive := Regs.AL; (* Return proper result *)
- end; (* Returns 0 = A, 1 = B, 2 = C, ETC *)
-
- Function NumDrives :Byte;
- Var (* Routine to determine number of valid drives *)
- Regs :Registers; (* To hold register info for Intr() *)
- CurDrive :Byte; (* Temporary storage For current drive*)
- begin
- CurDrive := GetDrive; (* Find out the current drive *)
- Regs.AH := $0E; (* Function to change drives *)
- Regs.DL := CurDrive; (* Change to current drive *)
- Intr($21, Regs); (* Call Dos Int 21h *)
- NumDrives := Regs.AL; (* Return proper info to user *)
- end;
-
- Procedure ChangeDrive (Drive :Byte);
- Var (* Routine to change default drive *)
- Regs :Registers; (* To hold register info for Intr() *)
- begin
- Regs.AH := $0E; (* Function to change Drives *)
- Regs.DL := Drive; (* Drive to change to *)
- Intr($21,Regs); (* Call Dos Int 21h *)
- end;
-
- Procedure CalculateWaste (var SR: SearchRec);
- begin
- if ((SR.Attr AND Directory) <> Directory)
- and ((SR.Attr AND VolumeID) <> VolumeID)
- then begin
- Inc(TotalFiles);
- TotalBytes := TotalBytes + SR.Size;
- TotalClusters := TotalClusters + (Sr.size div ClusterSize);
- if ((Sr.size mod ClusterSize) <> 0) then Inc(TotalClusters,1);
- end;
- end;
-
- Procedure FindTheFiles(FileDir :PathStr);
- var
- FileRec : SearchRec;
- TFiles : longint;
- OnlyOne : char;
- DosErr : integer;
- begin
- DosErr := DosError;
- OnlyOne := 's';
- write('Tallying ',RPad(FileDir,58));
- TFiles := TotalFiles;
- FindFirst(FileDir, AnyFile, FileRec);
- while DosError = 0 do
- begin
- CalculateWaste(FileRec);
- FindNext(FileRec);
- end;
- if ((TotalFiles-TFiles) = 1) then OnlyOne := #32;
- writeln('(',(TotalFiles-TFiles):3,' file',OnlyOne,')');
- DosError := DosErr;
- end;
-
- procedure ScanPath (Path, FileMask : PathStr); { Scans given path for subdirectories }
- { Based on a procedure posted by Alexander Staubo on ILink Pascal,
- January, 1994; ... in response to Eddy Thilleman's "AllDirs" procedure }
- var
- Dta : SearchRec;
- begin
- if Path[Length(Path)] <> '\' then
- Path := Path + '\';
- FindFirst(Path + '*.*', Directory, Dta);
- FindTheFiles(Path+FileMask);
- while DosError = 0 do
- begin
- if (Dta.Name[1] <> '.') and (Dta.Attr and Directory = Directory) then
- ScanPath(Path + Dta.Name + '\',FileMask); { ** RECURSION ** }
- FindNext(Dta);
- end;
- end;
-
- var
- pstr : pathstr;
- pdir : dirstr;
- pname : namestr;
- pext : extstr;
-
- sDrive, { starting Drive }
- nDrive : byte; { Drive to examine }
- WasteSpace,
- TotalSpace : longint;
-
- begin
-
- {===========================================================================}
- (** Initialize global vars **)
- {===========================================================================}
-
- TotalFiles := 0; TotalBytes := 0; TotalClusters := 0;
-
- {===========================================================================}
- (** Determine directories **)
- {===========================================================================}
-
- sDrive:=GetDrive; { save original, so that we can return }
- if (ParamCount=0)
- then showhelp(0)
- else pstr:=ParamStr(1);
- fsplit(fexpand(pstr),pdir,pname,pext);
- pstr:=pdir+pname+pext;
-
- {===========================================================================}
- (** Change to selected drive **)
- {===========================================================================}
-
-
- nDrive := Ord(UpCase(pdir[1]))-64;
- if NOT (nDrive in [0..NumDrives])
- then showhelp(1)
- else ChangeDrive(Ord(pdir[1])-65);
-
- {===========================================================================}
- (** Determine cluster size **)
- {===========================================================================}
-
- ClusterSize := (GetClusterSize(nDrive));
- if ClusterSize=0
- then showhelp(1);
-
- {===========================================================================}
- (** Write introduction **)
- {===========================================================================}
-
- Writeln;
- Writeln (' Now analyzing - ', pstr);
- Writeln;
-
- {===========================================================================}
- (** Scan the files **)
- {===========================================================================}
-
- if pname=''
- then ScanPath(pdir,'*.*')
- else FindTheFiles(pstr); {only check specified files}
-
- {===========================================================================}
- (** Report on what we found **)
- {===========================================================================}
-
- TotalSpace := (TotalClusters * ClusterSize);
- WasteSpace := (TotalSpace - TotalBytes);
- writeln;
- writeln (comma(ClusterSize):15, ' - bytes per cluster');
- writeln (comma(TotalFiles ):15, ' - total files tallied');
- writeln (comma(TotalBytes ):15, ' - total bytes in files');
- writeln (comma(WasteSpace ):15, ' - total bytes wasted by slack space');
- writeln (comma(TotalSpace ):15, ' - total bytes allocated by files');
- if TotalBytes=0
- then write ('0.00':14)
- else write (100*(WasteSpace/TotalSpace):14:2);
- writeln ('% - percent of disk space wasted');
-
- {===========================================================================}
- (** Return to original drive **)
- {===========================================================================}
-
- ChangeDrive(sDrive);
- end.
-