Changeset 10 for trunk/UDriveScan.pas


Ignore:
Timestamp:
Apr 2, 2016, 12:02:59 AM (8 years ago)
Author:
chronos
Message:
  • Added support for continue previous stopped scan.
  • Modified: Allow to scan only part of drive by specifiing start and end sector.
  • Added: Table showing list of operations in project.
  • Added: Allow to create new project and close project.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/UDriveScan.pas

    r8 r10  
    2525  TDriveScan = class
    2626  private
     27    FDriveName: string;
    2728    FOnChange: TNotifyEvent;
    2829    FOnTerminate: TNotifyEvent;
     30    FSectorCurrent: Integer;
    2931    ScanThread: TScanThread;
    3032    procedure DoChange;
    3133    procedure DoTerminate;
     34    function GetSectorCount: Integer;
    3235    procedure Run;
     36    procedure SetDriveName(AValue: string);
     37    procedure SetSectorCount(AValue: Integer);
    3338  public
    3439    Lock: TCriticalSection;
    3540    BlockMap: TBlockMap;
    3641    SectorSize: Integer;
    37     SectorCurrent: Integer;
    3842    TimeStart: TDateTime;
    3943    TimeEnd: TDateTime;
    4044    Terminated: Boolean;
    4145    DamagedBlockCount: Integer;
    42     Drive: string;
    4346    Mode: TRunMode;
    4447    WritePattern: Byte;
     48    SectorStart: Integer;
     49    SectorEnd: Integer;
    4550    function GetElapsedTime: TDateTime;
     51    procedure CheckDrive;
     52    procedure Reset;
    4653    procedure Start;
    4754    procedure Stop;
     
    5057    procedure SaveToNode(Node: TDOMNode);
    5158    procedure LoadFromNode(Node: TDOMNode);
     59    property SectorCurrent: Integer read FSectorCurrent;
     60    property DriveName: string read FDriveName write SetDriveName;
    5261    property OnTerminate: TNotifyEvent read FOnTerminate write FOnTerminate;
    5362    property OnChange: TNotifyEvent read FOnChange write FOnChange;
     63    property SectorCount: Integer read GetSectorCount write SetSectorCount;
    5464  end;
    5565
     
    114124procedure TDriveScan.DoTerminate;
    115125begin
     126
    116127  if Assigned(FOnTerminate) then FOnTerminate(Self);
     128end;
     129
     130function TDriveScan.GetSectorCount: Integer;
     131begin
     132  Result := BlockMap.SectorCount;
    117133end;
    118134
     
    121137  if TimeEnd <> 0 then Result := TimeEnd - TimeStart
    122138    else Result := Now - TimeStart;
     139end;
     140
     141procedure TDriveScan.CheckDrive;
     142var
     143  F: TFileStream;
     144begin
     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;
     153end;
     154
     155procedure TDriveScan.Reset;
     156begin
     157  TimeStart := Now;
     158  DamagedBlockCount := 0;
     159  BlockMap.Clear;
     160  FSectorCurrent := SectorStart;
    123161end;
    124162
     
    138176  RealSize: Integer;
    139177  Buffer: array of Byte;
    140   I: Integer;
    141178begin
    142179  try
    143180  Lock.Acquire;
    144   TimeStart := Now;
    145181  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
    151185  SetLength(Buffer, SectorSize);
    152186  if Mode = rmWrite then
    153187    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
    156189    try
    157190      Lock.Release;
     
    163196        //Sleep(1);
    164197      end else begin
    165         F.Position := I * SectorSize;
     198        F.Position := FSectorCurrent * SectorSize;
    166199        if Mode = rmRead then RealSize := F.Read(Buffer[0], SectorSize)
    167200          else if Mode = rmWrite then RealSize := F.Write(Buffer[0], SectorSize)
     
    172205    end;
    173206    if RealSize <> SectorSize then begin
    174       BlockMap.Sectors[I] := bsDamaged;
     207      BlockMap.Sectors[FSectorCurrent] := bsDamaged;
    175208      Inc(DamagedBlockCount);
    176     end else BlockMap.Sectors[I] := bsOk;
     209    end else BlockMap.Sectors[FSectorCurrent] := bsOk;
     210    Inc(FSectorCurrent);
    177211    if Terminated then Break;
    178212  end;
    179   F.Free;
    180 
     213  finally
     214    F.Free;
     215  end;
    181216  finally
    182217    Lock.Release;
     
    185220  DoChange;
    186221  Terminated := True;
    187   DoTerminate;
     222  ScanThread.Synchronize(DoTerminate);
     223end;
     224
     225procedure TDriveScan.SetDriveName(AValue: string);
     226begin
     227  if FDriveName = AValue then Exit;
     228  FDriveName := AValue;
     229  CheckDrive;
     230end;
     231
     232procedure TDriveScan.SetSectorCount(AValue: Integer);
     233begin
     234  if BlockMap.SectorCount = AValue then Exit;
     235  BlockMap.SectorCount := AValue;
    188236end;
    189237
     
    204252  SectorSize := 4096;
    205253  Terminated := True;
     254  Reset;
    206255end;
    207256
     
    221270    WriteInteger(Node, 'DamagedBlockCount', DamagedBlockCount);
    222271    WriteInteger(Node, 'WritePattern', WritePattern);
    223     WriteString(Node, 'DriveName', Drive);
     272    WriteString(Node, 'DriveName', DriveName);
    224273    WriteDateTime(Node, 'TimeStart', TimeStart);
    225274    WriteDateTime(Node, 'TimeEnd', TimeEnd);
     275    WriteInteger(Node, 'SectorStart', SectorStart);
     276    WriteInteger(Node, 'SectorEnd', SectorEnd);
     277    WriteInteger(Node, 'SectorCurrent', FSectorCurrent);
    226278
    227279    NewNode := OwnerDocument.CreateElement('SectorMap');
     
    238290    DamagedBlockCount := ReadInteger(Node, 'DamagedBlockCount', 0);
    239291    WritePattern := ReadInteger(Node, 'WritePattern', 0);
    240     Drive := ReadString(Node, 'DriveName', '');
     292    DriveName := ReadString(Node, 'DriveName', '');
    241293    TimeStart := ReadDateTime(Node, 'TimeStart', 0);
    242294    TimeEnd := ReadDateTime(Node, 'TimeEnd', 0);
     295    FSectorCurrent := ReadInteger(Node, 'SectorCurrent', 0);
     296    SectorStart := ReadInteger(Node, 'SectorStart', 0);
     297    SectorEnd := ReadInteger(Node, 'SectorEnd', SectorCount - 1);
    243298
    244299    NewNode := FindNode('SectorMap');
Note: See TracChangeset for help on using the changeset viewer.