home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / Issue51 / System / UFileSys.pas < prev   
Encoding:
Pascal/Delphi Source File  |  1999-09-23  |  7.1 KB  |  234 lines

  1. unit UFileSys;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  7.   StdCtrls, Grids, RzLstBox;
  8.  
  9. type
  10.   TForm1 = class(TForm)
  11.     DriveList: TRzTabbedListBox;
  12.     procedure FormCreate(Sender: TObject);
  13.   private
  14.     { Private declarations }
  15.   public
  16.     { Public declarations }
  17.   end;
  18.  
  19. var
  20.   Form1: TForm1;
  21.  
  22. implementation
  23.  
  24. {$R *.DFM}
  25.  
  26. type
  27.     EFileSystem = class (Exception);
  28.     TDriveType = ( fsUnknown, fsNoRoot, fsRemovable, fsFixed, fsRemote, fsCDROM, fsRAMDisk );
  29.     TDriveTypes = set of TDriveType;
  30.  
  31.     TFileSystem = class (TComponent)
  32.     private
  33.         fDriveLetter: Char;
  34.         fSerialNumber: DWord;
  35.         fDriveType: TDriveType;
  36.         fDriveTypes: TDriveTypes;
  37.         fFileSystem, fDrives, fVolumeName: String;
  38.         fTotalSize, fAvailableSpace, fFreeSpace: TLargeInteger;
  39.         procedure InitDrivesList;
  40.         function GetDriveCount: Integer;
  41.         function GetIsReady: Boolean;
  42.         procedure SetDriveLetter (Value: Char);
  43.         function GetDriveChar (Index: Integer): Char;
  44.         function GetUsedSpace: TLargeInteger;
  45.         function GetSerialNumber: String;
  46.         procedure SetVolumeName (Value: String);
  47.         procedure SetDriveTypes (Value: TDriveTypes);
  48.     public
  49.         constructor Create (AOwner: TComponent); override;
  50.         destructor Destroy; override;
  51.         procedure Refresh;
  52.         property Drives [Index: Integer]: Char read GetDriveChar;
  53.     published
  54.         // Drive-specific stuff....
  55.         property DriveLetter: Char read fDriveLetter write SetDriveLetter;
  56.         property DriveType: TDriveType read fDriveType;
  57.         property IsReady: Boolean read GetIsReady;
  58.         property VolumeName: String read fVolumeName write SetVolumeName;
  59.         property FileSystem: String read fFileSystem;
  60.         property SerialNumber: String read GetSerialNumber;
  61.         property SerialNum: DWord read fSerialNumber;
  62.         property TotalSize: TLargeInteger read fTotalSize;
  63.         property FreeSpace: TLargeInteger read fFreeSpace;
  64.         property UsedSpace: TLargeInteger read GetUsedSpace;
  65.         property AvailableSpace: TLargeInteger read fAvailableSpace;
  66.         property DriveCount: Integer read GetDriveCount;
  67.         property DriveTypes: TDriveTypes read fDriveTypes write SetDriveTypes default [fsFixed];
  68.     end;
  69.  
  70. { TFileSystem }
  71.  
  72. constructor TFileSystem.Create (AOwner: TComponent);
  73. begin
  74.     Inherited Create (AOwner);
  75.     SetDriveTypes ([fsFixed]);
  76. end;
  77.  
  78. destructor TFileSystem.Destroy;
  79. begin
  80.     Inherited Destroy;
  81. end;
  82.  
  83. function TFileSystem.GetDriveCount: Integer;
  84. begin
  85.     Result := Length (fDrives);
  86. end;
  87.  
  88. function TFileSystem.GetDriveChar (Index: Integer): Char;
  89. begin
  90.     Result := #0;
  91.     if (Index >= 0) and (Index < Length (fDrives)) then Result := fDrives [Index + 1];
  92. end;
  93.  
  94. procedure TFileSystem.InitDrivesList;
  95. var
  96.     p: PChar;
  97.     Buff: array [0..255] of Char;
  98. begin
  99.     fDrives := '';
  100.     GetLogicalDriveStrings (sizeof (Buff), Buff);
  101.     p := Buff;
  102.     while p^ <> #0 do begin
  103.         if TDriveType (GetDriveType (p)) in fDriveTypes then begin
  104.             fDrives := fDrives + UpperCase (p^);
  105.             // If this is the first, make it the current drive by default.
  106.             if Length (fDrives) = 1 then SetDriveLetter (p^);
  107.         end;
  108.  
  109.         Inc (p, 4);
  110.     end;
  111. end;
  112.  
  113. function TFileSystem.GetUsedSpace: TLargeInteger;
  114. begin
  115.     Result := fTotalSize - fFreeSpace;
  116. end;
  117.  
  118. function TFileSystem.GetSerialNumber: String;
  119. begin
  120.     // Precision specifier in the format string ensures that leading zeroes
  121.     // actrually get printed instead of being silently discarded....
  122.     Result := Format ('%.4x-%.4x', [HiWord (fSerialNumber), LoWord (fSerialNumber)]);
  123. end;
  124.  
  125. procedure TFileSystem.SetDriveLetter (Value: Char);
  126. begin
  127.     Value := UpCase (Value);
  128.     if (Value <> fDriveLetter) and (Pos (Value, fDrives) > 0) then begin
  129.         fDriveLetter := Value;
  130.         fDriveType := TDriveType (GetDriveType (PChar (Value + ':\')));
  131.         Refresh;
  132.     end;
  133. end;
  134.  
  135. function TFileSystem.GetIsReady: Boolean;
  136. var
  137.     errMode, FindErr: Integer;
  138.     SearchRec: TSearchRec;
  139. begin
  140.     Result := fDriveType in [fsFixed, fsRemote, fsRAMDisk];
  141.     if not Result then begin
  142.         errMode := SetErrorMode (sem_FailCriticalErrors);
  143.         try
  144.             FindErr := FindFirst (fDriveLetter + ':\', faAnyFile, SearchRec);
  145.             try
  146.                 Result := FindErr = 2;
  147.             finally
  148.                 FindClose (SearchRec);
  149.             end;
  150.         finally
  151.             SetErrorMode (errMode);
  152.         end;
  153.     end;
  154. end;
  155.  
  156. procedure TFileSystem.SetDriveTypes (Value: TDriveTypes);
  157. begin
  158.     if Value <> fDriveTypes then begin
  159.         fDriveTypes := Value;
  160.         InitDrivesList;
  161.     end;
  162. end;
  163.  
  164. procedure TFileSystem.Refresh;
  165. var
  166.     Junk: DWord;
  167.     szVolumeName, szFileSystem: array [0..255] of char;
  168. begin
  169.     // Initialise drive-information properties
  170.     if not GetIsReady then raise EFileSystem.Create ('Drive not ready');
  171.     GetDiskFreeSpaceEx (PChar (fDriveLetter + ':\'), fAvailableSpace, fTotalSize, @fFreeSpace);
  172.     GetVolumeInformation (PChar (fDriveLetter + ':\'), szVolumeName, sizeof (szVolumeName),
  173.                           @fSerialNumber, Junk, Junk, szFileSystem, sizeof (szFileSystem));
  174.     fVolumeName := szVolumeName;
  175.     fFileSystem := szFileSystem;
  176. end;
  177.  
  178. procedure TFileSystem.SetVolumeName (Value: String);
  179. begin
  180.     if GetIsReady and (fVolumeName <> Value) then begin
  181.         if Length (Value) > 11 then Value := Copy (Value, 1, 11);
  182.         SetVolumeLabel (PChar (fDriveLetter + ':\'), PChar (Value));
  183.         Refresh; // Ensure fVolumeName reflects reality.....
  184.     end;
  185. end;
  186.  
  187. //--------- End of TFileSystem component ---------------------------------
  188.  
  189. procedure TForm1.FormCreate (Sender: TObject);
  190. var
  191.     S: String;
  192.     Idx: Integer;
  193.     TotBytes: Double;
  194.     FileSys: TFileSystem;
  195.  
  196.     function StrDriveType (Typ: TDriveType): String;
  197.     begin
  198.         case Typ of
  199.           fsRemovable: Result := 'Removable';
  200.           fsFixed:     Result := 'Fixed    ';
  201.           fsRemote:    Result := 'Remote   ';
  202.           fsCDROM:     Result := 'CD-ROM   ';
  203.           fsRAMDisk:   Result := 'RAM-Disk ';
  204.           else         Result := '-unknown-';
  205.         end;
  206.     end;
  207.  
  208. begin
  209.     FileSys := TFileSystem.Create (Self);
  210.     with FileSys do try
  211.         DriveTypes := [ fsRemovable, fsFixed, fsRemote, fsCDROM ];
  212.         for Idx := 0 to DriveCount - 1 do begin
  213.             try
  214.                 DriveLetter := Drives [Idx];
  215.                 S := DriveLetter + ':' + #9 + VolumeName + #9 + FileSystem + #9 + SerialNumber + #9;
  216.                 TotBytes := TotalSize;
  217.                 S := S + Format ('%n', [TotBytes]);
  218.                 SetLength (S, Length (S) - 3);
  219.                 S := S + #9 + StrDriveType (DriveType);
  220.             except
  221.                 on EFileSystem do S := Drives [Idx] + ':' + #9 + '---<not ready>---';
  222.             end;
  223.             DriveList.Items.Add (S);
  224.         end;
  225.     finally
  226.         FileSys.Free;
  227.     end;
  228. end;
  229.  
  230. end.
  231.  
  232.  
  233.  
  234.