Changeset 10 for trunk/UDriveScan.pas
- Timestamp:
- Apr 2, 2016, 12:02:59 AM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/UDriveScan.pas
r8 r10 25 25 TDriveScan = class 26 26 private 27 FDriveName: string; 27 28 FOnChange: TNotifyEvent; 28 29 FOnTerminate: TNotifyEvent; 30 FSectorCurrent: Integer; 29 31 ScanThread: TScanThread; 30 32 procedure DoChange; 31 33 procedure DoTerminate; 34 function GetSectorCount: Integer; 32 35 procedure Run; 36 procedure SetDriveName(AValue: string); 37 procedure SetSectorCount(AValue: Integer); 33 38 public 34 39 Lock: TCriticalSection; 35 40 BlockMap: TBlockMap; 36 41 SectorSize: Integer; 37 SectorCurrent: Integer;38 42 TimeStart: TDateTime; 39 43 TimeEnd: TDateTime; 40 44 Terminated: Boolean; 41 45 DamagedBlockCount: Integer; 42 Drive: string;43 46 Mode: TRunMode; 44 47 WritePattern: Byte; 48 SectorStart: Integer; 49 SectorEnd: Integer; 45 50 function GetElapsedTime: TDateTime; 51 procedure CheckDrive; 52 procedure Reset; 46 53 procedure Start; 47 54 procedure Stop; … … 50 57 procedure SaveToNode(Node: TDOMNode); 51 58 procedure LoadFromNode(Node: TDOMNode); 59 property SectorCurrent: Integer read FSectorCurrent; 60 property DriveName: string read FDriveName write SetDriveName; 52 61 property OnTerminate: TNotifyEvent read FOnTerminate write FOnTerminate; 53 62 property OnChange: TNotifyEvent read FOnChange write FOnChange; 63 property SectorCount: Integer read GetSectorCount write SetSectorCount; 54 64 end; 55 65 … … 114 124 procedure TDriveScan.DoTerminate; 115 125 begin 126 116 127 if Assigned(FOnTerminate) then FOnTerminate(Self); 128 end; 129 130 function TDriveScan.GetSectorCount: Integer; 131 begin 132 Result := BlockMap.SectorCount; 117 133 end; 118 134 … … 121 137 if TimeEnd <> 0 then Result := TimeEnd - TimeStart 122 138 else Result := Now - TimeStart; 139 end; 140 141 procedure TDriveScan.CheckDrive; 142 var 143 F: TFileStream; 144 begin 145 if FileExists(DriveName) then begin 146 F := TFileStream.Create(DriveName, fmOpenRead); 147 try 148 BlockMap.SectorCount := F.Size div SectorSize; 149 finally 150 F.Free; 151 end; 152 end else BlockMap.SectorCount := 0; 153 end; 154 155 procedure TDriveScan.Reset; 156 begin 157 TimeStart := Now; 158 DamagedBlockCount := 0; 159 BlockMap.Clear; 160 FSectorCurrent := SectorStart; 123 161 end; 124 162 … … 138 176 RealSize: Integer; 139 177 Buffer: array of Byte; 140 I: Integer;141 178 begin 142 179 try 143 180 Lock.Acquire; 144 TimeStart := Now;145 181 Terminated := False; 146 DamagedBlockCount := 0; 147 if Mode = rmRead then F := TFileStream.Create(Drive, fmOpenRead) 148 else if Mode = rmWrite then F := TFileStream.Create(Drive, fmOpenReadWrite); 149 BlockMap.SectorCount := F.Size div SectorSize; 150 BlockMap.Clear; 182 if Mode = rmRead then F := TFileStream.Create(DriveName, fmOpenRead) 183 else if Mode = rmWrite then F := TFileStream.Create(DriveName, fmOpenReadWrite); 184 try 151 185 SetLength(Buffer, SectorSize); 152 186 if Mode = rmWrite then 153 187 FillChar(Buffer[0], Length(Buffer), WritePattern); 154 for I := 0 to BlockMap.SectorCount - 1 do begin 155 SectorCurrent := I; 188 while FSectorCurrent < SectorEnd do begin 156 189 try 157 190 Lock.Release; … … 163 196 //Sleep(1); 164 197 end else begin 165 F.Position := I* SectorSize;198 F.Position := FSectorCurrent * SectorSize; 166 199 if Mode = rmRead then RealSize := F.Read(Buffer[0], SectorSize) 167 200 else if Mode = rmWrite then RealSize := F.Write(Buffer[0], SectorSize) … … 172 205 end; 173 206 if RealSize <> SectorSize then begin 174 BlockMap.Sectors[ I] := bsDamaged;207 BlockMap.Sectors[FSectorCurrent] := bsDamaged; 175 208 Inc(DamagedBlockCount); 176 end else BlockMap.Sectors[I] := bsOk; 209 end else BlockMap.Sectors[FSectorCurrent] := bsOk; 210 Inc(FSectorCurrent); 177 211 if Terminated then Break; 178 212 end; 179 F.Free; 180 213 finally 214 F.Free; 215 end; 181 216 finally 182 217 Lock.Release; … … 185 220 DoChange; 186 221 Terminated := True; 187 DoTerminate; 222 ScanThread.Synchronize(DoTerminate); 223 end; 224 225 procedure TDriveScan.SetDriveName(AValue: string); 226 begin 227 if FDriveName = AValue then Exit; 228 FDriveName := AValue; 229 CheckDrive; 230 end; 231 232 procedure TDriveScan.SetSectorCount(AValue: Integer); 233 begin 234 if BlockMap.SectorCount = AValue then Exit; 235 BlockMap.SectorCount := AValue; 188 236 end; 189 237 … … 204 252 SectorSize := 4096; 205 253 Terminated := True; 254 Reset; 206 255 end; 207 256 … … 221 270 WriteInteger(Node, 'DamagedBlockCount', DamagedBlockCount); 222 271 WriteInteger(Node, 'WritePattern', WritePattern); 223 WriteString(Node, 'DriveName', Drive );272 WriteString(Node, 'DriveName', DriveName); 224 273 WriteDateTime(Node, 'TimeStart', TimeStart); 225 274 WriteDateTime(Node, 'TimeEnd', TimeEnd); 275 WriteInteger(Node, 'SectorStart', SectorStart); 276 WriteInteger(Node, 'SectorEnd', SectorEnd); 277 WriteInteger(Node, 'SectorCurrent', FSectorCurrent); 226 278 227 279 NewNode := OwnerDocument.CreateElement('SectorMap'); … … 238 290 DamagedBlockCount := ReadInteger(Node, 'DamagedBlockCount', 0); 239 291 WritePattern := ReadInteger(Node, 'WritePattern', 0); 240 Drive := ReadString(Node, 'DriveName', '');292 DriveName := ReadString(Node, 'DriveName', ''); 241 293 TimeStart := ReadDateTime(Node, 'TimeStart', 0); 242 294 TimeEnd := ReadDateTime(Node, 'TimeEnd', 0); 295 FSectorCurrent := ReadInteger(Node, 'SectorCurrent', 0); 296 SectorStart := ReadInteger(Node, 'SectorStart', 0); 297 SectorEnd := ReadInteger(Node, 'SectorEnd', SectorCount - 1); 243 298 244 299 NewNode := FindNode('SectorMap');
Note:
See TracChangeset
for help on using the changeset viewer.