source: trunk/UPhysDrive.pas

Last change on this file was 41, checked in by chronos, 5 years ago
  • Modified: Build under Lazarus 2.0.
  • Modified: Used .lrj files instead of .lrt files.
  • Modified: Removed TemplateGenerics package.
File size: 5.1 KB
Line 
1unit UPhysDrive;
2
3{$mode delphi}
4
5interface
6
7uses
8 Classes, SysUtils, Contnrs, UFindFile, UCommon, Math
9 {$IFDEF Windows},ActiveX,ComObj,Variants
10 {$ENDIF};
11
12type
13 TDriveKind = (dkPhysical, dkFile);
14
15 { TDriveInfo }
16
17 TDriveInfo = class
18 private
19 FSectorSize: Integer;
20 FSectorCount: Int64;
21 FSize: Int64;
22 function GetSectorCount: Int64;
23 procedure SetSectorSize(AValue: Integer);
24 procedure SetSize(AValue: Int64);
25 public
26 Kind: TDriveKind;
27 Model: string;
28 Path: string;
29 constructor Create;
30 procedure Assign(Source: TDriveInfo);
31 property SectorSize: Integer read FSectorSize write SetSectorSize;
32 property SectorCount: Int64 read GetSectorCount;
33 property Size: Int64 read FSize write SetSize;
34 end;
35
36 { TDriveList }
37
38 TDriveList = class(TObjectList)
39 function FindByModel(Model: string): TDriveInfo;
40 procedure LoadToStrings(Strings: TStrings);
41 procedure Detect;
42 private
43 {$IFDEF Windows}
44 procedure GetWin32DiskDriveInfo;
45 {$ENDIF}
46 end;
47
48implementation
49
50uses
51 UPrefixMultiplier;
52
53resourcestring
54 SMinSectorSize = 'Minimum sector size is 1';
55
56{ TDriveInfo }
57
58procedure TDriveInfo.SetSectorSize(AValue: Integer);
59begin
60 if FSectorSize = AValue then Exit;
61 if Avalue < 1 then
62 raise Exception.Create(SMinSectorSize);
63 FSectorSize := AValue;
64 FSectorCount := Ceil(FSize / FSectorSize);
65end;
66
67function TDriveInfo.GetSectorCount: Int64;
68begin
69 Result := Ceil(FSize / FSectorSize);
70end;
71
72procedure TDriveInfo.SetSize(AValue: Int64);
73begin
74 if FSize = AValue then Exit;
75 FSize := AValue;
76end;
77
78constructor TDriveInfo.Create;
79begin
80 FSectorSize := 1;
81end;
82
83procedure TDriveInfo.Assign(Source: TDriveInfo);
84begin
85 Path := Source.Path;
86 Model := Source.Model;
87 Size := Source.Size;
88 FSectorCount := Source.FSectorCount;
89 SectorSize := Source.SectorSize;
90end;
91
92{ TDriveList }
93
94function TDriveList.FindByModel(Model: string): TDriveInfo;
95var
96 I: Integer;
97begin
98 I := 0;
99 while (I < Count) and (TDriveInfo(Items[I]).Model <> Model) do Inc(I);
100 if I < Count then Result := TDriveInfo(Items[I])
101 else Result := nil;
102end;
103
104procedure TDriveList.LoadToStrings(Strings: TStrings);
105var
106 I: Integer;
107 PrefixMultiplier: TPrefixMultiplier;
108begin
109 PrefixMultiplier := TPrefixMultiplier.Create(nil);
110 try
111 while Strings.Count > Count do
112 Strings.Delete(Strings.Count - 1);
113 while Strings.Count < Count do
114 Strings.Add('');
115 for I := 0 to Count - 1 do begin
116 Strings[I] := TDriveInfo(Items[I]).Model + ' (' +
117 PrefixMultiplier.Add(TDriveInfo(Items[I]).Size, BasePrefixMultipliers, 'B') + ')';
118 Strings.Objects[I] := Items[I];
119 end;
120 finally
121 PrefixMultiplier.Free;
122 end;
123end;
124
125procedure TDriveList.Detect;
126var
127 NewDriveInfo: TDriveInfo;
128 List: TStringList;
129 I: Integer;
130 FindFile: TFindFile;
131begin
132 Clear;
133 {$IFDEF Linux}
134 FindFile := TFindFile.Create(nil);
135 FindFile.Path := '/sys/block';
136 FindFile.FileMask := '*';
137 FindFile.FileAttr := [ffaDirectory];
138 FindFile.InSubFolders := False;
139 List := FindFile.SearchForFiles;
140 for I := 0 to List.Count - 1 do
141 if (ExtractFileName(List[I]) <> '.') and (ExtractFileName(List[I]) <> '..') then begin
142 if FileExists(List[I] + '/device') then begin
143 NewDriveInfo := TDriveInfo.Create;
144 NewDriveInfo.Kind := dkPhysical;
145 NewDriveInfo.Model := Trim(LoadFileToStr(List[I] + '/device/model'));
146 NewDriveInfo.SectorSize := StrToInt(Trim(LoadFileToStr(List[I] + '/queue/physical_block_size')));
147 NewDriveInfo.Size := StrToInt64(Trim(LoadFileToStr(List[I] + '/size'))) * 512;
148 NewDriveInfo.Path := '/dev/' + ExtractFileName(List[I]);
149 Add(NewDriveInfo);
150 end;
151 end;
152 {$ENDIF}
153 {$IFDEF Windows}
154 GetWin32DiskDriveInfo;
155 {$ENDIF}
156 // Drive located using filename
157 NewDriveInfo := TDriveInfo.Create;
158 NewDriveInfo.Kind := dkFile;
159 NewDriveInfo.Model := 'File';
160 NewDriveInfo.SectorSize := 4096;
161 NewDriveInfo.Size := 0;
162 NewDriveInfo.Path := '';
163 Add(NewDriveInfo);
164end;
165
166{$IFDEF Windows}
167procedure TDriveList.GetWin32DiskDriveInfo;
168const
169 WbemUser = '';
170 WbemPassword = '';
171 WbemComputer = 'localhost';
172 wbemFlagForwardOnly = $00000020;
173var
174 FSWbemLocator: OLEVariant;
175 FWMIService: OLEVariant;
176 FWbemObjectSet: OLEVariant;
177 FWbemObject: OLEVariant;
178 oEnum: IEnumvariant;
179 OutVar: LongWord;
180 NewDriveInfo: TDriveInfo;
181begin;
182 FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
183 FWMIService := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser,
184 WbemPassword);
185 FWbemObjectSet := FWMIService.ExecQuery('SELECT * FROM Win32_DiskDrive',
186 'WQL', wbemFlagForwardOnly);
187 oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
188 while oEnum.Next(1, FWbemObject, OutVar) = 0 do begin
189 NewDriveInfo := TDriveInfo.Create;
190 NewDriveInfo.Kind := dkPhysical;
191 NewDriveInfo.Model := FWbemObject.Properties_.Item('Caption').Value;
192 //NewDriveInfo.Model := FWbemObject.Properties_.Item('Model').Value;
193 NewDriveInfo.Size := FWbemObject.Properties_.Item('Size').Value;
194 NewDriveInfo.SectorSize := 4096;
195 NewDriveInfo.Path := FWbemObject.Properties_.Item('DeviceID').Value;
196 Add(NewDriveInfo);
197
198 FWbemObject := Unassigned;
199 end;
200end;
201{$ENDIF}
202
203
204end.
205
Note: See TracBrowser for help on using the repository browser.