Changeset 3
- Timestamp:
- Mar 26, 2016, 11:40:31 PM (9 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/CoolDisk.lpi
r1 r3 72 72 </Item2> 73 73 </RequiredPackages> 74 <Units Count=" 6">74 <Units Count="8"> 75 75 <Unit0> 76 76 <Filename Value="CoolDisk.lpr"/> … … 105 105 <IsPartOfProject Value="True"/> 106 106 </Unit5> 107 <Unit6> 108 <Filename Value="UBlockMap.pas"/> 109 <IsPartOfProject Value="True"/> 110 </Unit6> 111 <Unit7> 112 <Filename Value="UDriveScan.pas"/> 113 <IsPartOfProject Value="True"/> 114 </Unit7> 107 115 </Units> 108 116 </ProjectOptions> … … 139 147 </Options> 140 148 </Linking> 149 <Other> 150 <CompilerMessages> 151 <IgnoredMessages idx5024="True"/> 152 </CompilerMessages> 153 </Other> 141 154 </CompilerOptions> 142 155 <Debugging> -
trunk/CoolDisk.lpr
r1 r3 9 9 Interfaces, // this includes the LCL widgetset 10 10 Forms, tachartlazaruspkg, UFormMain, UFormBenchmark, UFormProject, UProject, 11 UConfig 11 UConfig, UBlockMap, UDriveScan 12 12 { you can add units after this }; 13 13 -
trunk/UFormMain.lfm
r2 r3 1 1 object FormMain: TFormMain 2 Left = 3552 Left = 215 3 3 Height = 941 4 Top = 2114 Top = 79 5 5 Width = 1703 6 6 Caption = 'CoolDisk' … … 12 12 OnDestroy = FormDestroy 13 13 OnShow = FormShow 14 LCLVersion = '1. 6.0.4'14 LCLVersion = '1.7' 15 15 object ListView1: TListView 16 16 Left = 16 … … 44 44 object Label1: TLabel 45 45 Left = 15 46 Height = 2 446 Height = 22 47 47 Top = 675 48 Width = 10148 Width = 91 49 49 Caption = 'Sector size:' 50 50 ParentColor = False … … 52 52 object LabelBlockSize: TLabel 53 53 Left = 256 54 Height = 2 454 Height = 22 55 55 Top = 675 56 56 Width = 10 … … 60 60 object LabelBlockCount: TLabel 61 61 Left = 256 62 Height = 2 462 Height = 22 63 63 Top = 704 64 64 Width = 10 … … 68 68 object Label2: TLabel 69 69 Left = 16 70 Height = 2 470 Height = 22 71 71 Top = 704 72 Width = 1 1972 Width = 105 73 73 Caption = 'Sector count:' 74 74 ParentColor = False … … 76 76 object LabelBlockCurrent: TLabel 77 77 Left = 256 78 Height = 2 478 Height = 22 79 79 Top = 736 80 80 Width = 10 … … 84 84 object Label3: TLabel 85 85 Left = 16 86 Height = 2 486 Height = 22 87 87 Top = 736 88 Width = 1 3688 Width = 122 89 89 Caption = 'Current sector:' 90 90 ParentColor = False … … 92 92 object Label4: TLabel 93 93 Left = 17 94 Height = 2 494 Height = 22 95 95 Top = 768 96 Width = 1 6296 Width = 147 97 97 Caption = 'Damaged sectors:' 98 98 ParentColor = False … … 100 100 object LabelBlockDamaged: TLabel 101 101 Left = 256 102 Height = 2 4102 Height = 22 103 103 Top = 764 104 104 Width = 10 … … 108 108 object Label5: TLabel 109 109 Left = 16 110 Height = 2 4110 Height = 22 111 111 Top = 796 112 Width = 1 22112 Width = 112 113 113 Caption = 'Elapsed time:' 114 114 ParentColor = False … … 116 116 object LabelElapsedTime: TLabel 117 117 Left = 256 118 Height = 2 4118 Height = 22 119 119 Top = 792 120 120 Width = 10 … … 124 124 object Label6: TLabel 125 125 Left = 17 126 Height = 2 4126 Height = 22 127 127 Top = 824 128 Width = 1 42128 Width = 129 129 129 Caption = 'Estimated time:' 130 130 ParentColor = False … … 132 132 object LabelEstimatedTime: TLabel 133 133 Left = 257 134 Height = 2 4134 Height = 22 135 135 Top = 820 136 136 Width = 10 … … 140 140 object Label7: TLabel 141 141 Left = 17 142 Height = 2 4142 Height = 22 143 143 Top = 644 144 Width = 1 60144 Width = 144 145 145 Caption = 'Sectors per Block:' 146 146 ParentColor = False … … 148 148 object LabelSectorPerBlock: TLabel 149 149 Left = 256 150 Height = 2 4150 Height = 22 151 151 Top = 640 152 152 Width = 10 … … 156 156 object LabelIOSpeed: TLabel 157 157 Left = 256 158 Height = 2 4158 Height = 22 159 159 Top = 848 160 160 Width = 10 … … 164 164 object Label8: TLabel 165 165 Left = 16 166 Height = 2 4166 Height = 22 167 167 Top = 852 168 Width = 94168 Width = 86 169 169 Caption = 'I/O speed:' 170 170 ParentColor = False … … 196 196 object EditDrive: TEdit 197 197 Left = 16 198 Height = 3 4198 Height = 32 199 199 Top = 8 200 200 Width = 448 … … 203 203 object ComboBoxRunMode: TComboBox 204 204 Left = 17 205 Height = 3 8205 Height = 32 206 206 Top = 88 207 207 Width = 247 … … 218 218 object Label9: TLabel 219 219 Left = 286 220 Height = 2 4220 Height = 22 221 221 Top = 95 222 Width = 1 21222 Width = 108 223 223 Caption = 'Data pattern:' 224 224 ParentColor = False … … 226 226 object EditPattern: TEdit 227 227 Left = 440 228 Height = 3 4228 Height = 32 229 229 Top = 88 230 230 Width = 80 231 231 TabOrder = 7 232 232 Text = '0xff' 233 end 234 object Label10: TLabel 235 Left = 16 236 Height = 22 237 Top = 612 238 Width = 36 239 Caption = 'Size:' 240 ParentColor = False 241 end 242 object LabelSize: TLabel 243 Left = 256 244 Height = 22 245 Top = 608 246 Width = 10 247 Caption = ' ' 248 ParentColor = False 233 249 end 234 250 object MainMenu1: TMainMenu -
trunk/UFormMain.pas
r2 r3 7 7 uses 8 8 Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, 9 Menus, ComCtrls, ExtCtrls, ActnList, Math,dateutils, syncobjs, UProject,10 U Config;9 Menus, ComCtrls, ExtCtrls, ActnList, dateutils, syncobjs, UProject, 10 UDriveScan; 11 11 12 12 type 13 14 TSectorState = (bsNone, bsOk, bsDamaged);15 16 { TBlockMap }17 18 TBlockMap = class19 private20 FBlockSize: TPoint;21 FDrawSize: TPoint;22 FSectorPerBlock: Integer;23 FSectors: array of TSectorState;24 FBlocks: array of TSectorState;25 function GetBlockCount: Integer;26 function GetSector(Index: Integer): TSectorState;27 function GetSectorCount: Integer;28 procedure SetBlockCount(AValue: Integer);29 procedure SetBlockSize(AValue: TPoint);30 procedure SetDrawSize(AValue: TPoint);31 procedure SetSector(Index: Integer; AValue: TSectorState);32 procedure SetSectorCount(AValue: Integer);33 procedure SetSectorPerBlock(AValue: Integer);34 procedure UpdateBlockSize;35 procedure UpdateBlocks;36 public37 ItemsCount: TPoint;38 function CombineSectors(From, Count: Integer): TSectorState;39 procedure Draw(Canvas: TCanvas);40 procedure Clear;41 constructor Create;42 property BlockSize: TPoint read FBlockSize write SetBlockSize;43 property DrawSize: TPoint read FDrawSize write SetDrawSize;44 property SectorPerBlock: Integer read FSectorPerBlock write SetSectorPerBlock;45 property SectorCount: Integer read GetSectorCount write SetSectorCount;46 property BlockCount: Integer read GetBlockCount;47 property Sectors[Index: Integer]: TSectorState read GetSector write SetSector;48 end;49 50 TRunMode = (rmRead, rmWrite);51 52 { TDriveScan }53 54 TDriveScan = class55 private56 FOnChange: TNotifyEvent;57 FOnTerminate: TNotifyEvent;58 procedure DoChange;59 procedure DoTerminate;60 public61 Lock: TCriticalSection;62 BlockMap: TBlockMap;63 SectorSize: Integer;64 SectorCurrent: Integer;65 TimeStart: TDateTime;66 TimeEnd: TDateTime;67 Terminated: Boolean;68 DamagedBlockCount: Integer;69 Drive: string;70 Mode: TRunMode;71 WritePattern: Byte;72 function GetElapsedTime: TDateTime;73 procedure Run;74 constructor Create;75 destructor Destroy; override;76 property OnTerminate: TNotifyEvent read FOnTerminate write FOnTerminate;77 property OnChange: TNotifyEvent read FOnChange write FOnChange;78 end;79 80 { TScanThread }81 82 TScanThread = class(TThread)83 Form: TForm;84 procedure Execute; override;85 end;86 87 13 { TFormMain } 88 14 … … 102 28 Image1: TImage; 103 29 Label1: TLabel; 30 Label10: TLabel; 104 31 Label2: TLabel; 105 32 Label3: TLabel; … … 117 44 LabelEstimatedTime: TLabel; 118 45 LabelIOSpeed: TLabel; 46 LabelSize: TLabel; 119 47 LabelSectorPerBlock: TLabel; 120 48 ListView1: TListView; … … 134 62 private 135 63 LastBlockPos: Integer; 136 DriveScan: TDriveScan;137 64 ScanThread: TScanThread; 138 65 RedrawPending: Boolean; … … 143 70 procedure UpdateInterface; 144 71 public 72 DriveScan: TDriveScan; 145 73 Project: TProject; 146 74 procedure Detect; … … 157 85 uses 158 86 UFormProject; 159 160 { TScanThread }161 162 procedure TScanThread.Execute;163 begin164 TFormMain(Form).DriveScan.Run;165 end;166 167 { TBlockMap }168 169 function TBlockMap.GetSectorCount: Integer;170 begin171 Result := Length(FSectors);172 end;173 174 procedure TBlockMap.SetBlockCount(AValue: Integer);175 begin176 SetLength(FBlocks, AValue);177 end;178 179 procedure TBlockMap.SetBlockSize(AValue: TPoint);180 begin181 if (FBlockSize.X = AValue.X) and (FBlockSize.Y = AValue.Y) then Exit;182 if (AValue.X = 0) or (AValue.Y = 0) then183 raise Exception.Create('BlockSize can''t be set to 0');184 FBlockSize := AValue;185 end;186 187 procedure TBlockMap.SetDrawSize(AValue: TPoint);188 begin189 if (FDrawSize.X = AValue.X) and (FDrawSize.Y = AValue.Y) then Exit;190 FDrawSize := AValue;191 UpdateBlockSize;192 end;193 194 function TBlockMap.GetSector(Index: Integer): TSectorState;195 begin196 Result := FSectors[Index];197 end;198 199 function TBlockMap.GetBlockCount: Integer;200 begin201 Result := Length(FBlocks);202 end;203 204 procedure TBlockMap.SetSector(Index: Integer; AValue: TSectorState);205 var206 BlockIndex: Integer;207 begin208 FSectors[Index] := AValue;209 210 // Update block211 BlockIndex := Index div FSectorPerBlock;212 if (AValue = bsDamaged) then FBlocks[BlockIndex] := bsDamaged213 else if (AValue = bsOk) and (FBlocks[BlockIndex] = bsNone) then214 FBlocks[BlockIndex] := bsOk;215 end;216 217 procedure TBlockMap.SetSectorCount(AValue: Integer);218 begin219 if Length(FSectors) = AValue then Exit;220 SetLength(FSectors, AValue);221 UpdateBlockSize;222 end;223 224 procedure TBlockMap.SetSectorPerBlock(AValue: Integer);225 begin226 if FSectorPerBlock = AValue then Exit;227 FSectorPerBlock := AValue;228 UpdateBlockSize;229 end;230 231 procedure TBlockMap.UpdateBlockSize;232 begin233 ItemsCount := Point(Trunc(FDrawSize.X / BlockSize.X), Trunc(FDrawSize.Y / BlockSize.Y));234 FSectorPerBlock := Ceil(SectorCount / (ItemsCount.X * ItemsCount.Y));235 SetBlockCount(Ceil(SectorCount / FSectorPerBlock));236 UpdateBlocks;237 end;238 239 procedure TBlockMap.UpdateBlocks;240 var241 I: Integer;242 begin243 for I := 0 to BlockCount - 1 do244 FBlocks[I] := CombineSectors(I * FSectorPerBlock, FSectorPerBlock);245 end;246 247 function TBlockMap.CombineSectors(From, Count: Integer): TSectorState;248 var249 I: Integer;250 UpTo: Integer;251 begin252 Result := bsNone;253 UpTo := From + Count - 1;254 if UpTo >= SectorCount then Upto := SectorCount - 1;255 for I := From to UpTo do begin256 257 if (Result = bsNone) and (Sectors[I] = bsOk) then Result := bsOk258 else if (Result = bsOk) and (Sectors[I] = bsDamaged) then Result := bsDamaged;259 end;260 end;261 262 procedure TBlockMap.Draw(Canvas: TCanvas);263 var264 I: Integer;265 Rect: TRect;266 BlockState: TSectorState;267 begin268 Canvas.Pen.Style := psSolid;269 Canvas.Pen.Color := clBlack;270 // Clean background271 Canvas.Brush.Style := bsSolid;272 Canvas.Brush.Color := clBlack;273 Canvas.FillRect(0, 0, Canvas.Width, Canvas.Height);274 275 DrawSize := Point(Canvas.Width, Canvas.Height);276 if SectorPerBlock >= 1 then begin277 for I := 0 to BlockCount - 1 do begin278 Rect := Bounds((I mod ItemsCount.X) * BlockSize.X,279 (I div ItemsCount.X) * BlockSize.Y, BlockSize.X - 1, BlockSize.Y - 1);280 BlockState := FBlocks[I];281 if BlockState = bsOk then Canvas.Brush.Color := clGreen282 else if BlockState = bsDamaged then Canvas.Brush.Color := clRed283 else Canvas.Brush.Color := clSilver;284 Canvas.FillRect(Rect);285 //Canvas.TextOut(Rect.Left, Rect.Top, IntToStr(I));286 end;287 end;288 end;289 290 procedure TBlockMap.Clear;291 var292 I: Integer;293 begin294 for I := 0 to SectorCount - 1 do295 FSectors[I] := bsNone;296 end;297 298 constructor TBlockMap.Create;299 begin300 FBlockSize := Point(12, 12);301 SectorPerBlock := 1;302 end;303 304 { TDriveScan }305 306 procedure TDriveScan.DoChange;307 begin308 if Assigned(FOnChange) then FOnChange(Self);309 end;310 311 procedure TDriveScan.DoTerminate;312 begin313 if Assigned(FOnTerminate) then FOnTerminate(Self);314 end;315 316 function TDriveScan.GetElapsedTime: TDateTime;317 begin318 if TimeEnd <> 0 then Result := TimeEnd - TimeStart319 else Result := Now - TimeStart;320 end;321 322 procedure TDriveScan.Run;323 var324 F: TFileStream;325 RealSize: Integer;326 Buffer: array of Byte;327 I: Integer;328 begin329 try330 Lock.Acquire;331 TimeStart := Now;332 Terminated := False;333 DamagedBlockCount := 0;334 if Mode = rmRead then F := TFileStream.Create(Drive, fmOpenRead)335 else if Mode = rmWrite then F := TFileStream.Create(Drive, fmOpenReadWrite);336 BlockMap.SectorCount := F.Size div SectorSize;337 BlockMap.Clear;338 SetLength(Buffer, SectorSize);339 if Mode = rmWrite then340 FillChar(Buffer[0], Length(Buffer), WritePattern);341 for I := 0 to BlockMap.SectorCount - 1 do begin342 SectorCurrent := I;343 try344 Lock.Release;345 DoChange;346 347 if ConfigTest then begin348 if Random < 0.000001 then RealSize := 0349 else RealSize := SectorSize;350 //Sleep(1);351 end else begin352 F.Position := I * SectorSize;353 if Mode = rmRead then RealSize := F.Read(Buffer[0], SectorSize)354 else if Mode = rmWrite then RealSize := F.Write(Buffer[0], SectorSize)355 else raise Exception.Create('Unknwon run mode');356 end;357 finally358 Lock.Acquire;359 end;360 if RealSize <> SectorSize then begin361 BlockMap.Sectors[I] := bsDamaged;362 Inc(DamagedBlockCount);363 end else BlockMap.Sectors[I] := bsOk;364 if Terminated then Break;365 end;366 F.Free;367 368 finally369 Lock.Release;370 end;371 TimeEnd := Now;372 DoChange;373 Terminated := True;374 DoTerminate;375 end;376 377 constructor TDriveScan.Create;378 begin379 Lock := TCriticalSection.Create;380 BlockMap := TBlockMap.Create;381 SectorSize := 4096;382 Terminated := True;383 end;384 385 destructor TDriveScan.Destroy;386 begin387 FreeAndNil(BlockMap);388 FreeAndNil(Lock);389 inherited Destroy;390 end;391 87 392 88 { TFormMain } … … 411 107 ScanThread.Form := Self; 412 108 Project := TProject.Create; 413 EditDrive.Text := '/dev/sd b';109 EditDrive.Text := '/dev/sda'; 414 110 end; 415 111 … … 482 178 Picture.Bitmap.EndUpdate; 483 179 end; 180 LabelSize.Caption := IntToStr(DriveScan.BlockMap.SectorCount * DriveScan.SectorSize) + ' bytes'; 484 181 LabelSectorPerBlock.Caption := IntToStr(DriveScan.BlockMap.SectorPerBlock); 485 182 LabelBlockSize.Caption := IntToStr(DriveScan.SectorSize) + ' bytes';
Note:
See TracChangeset
for help on using the changeset viewer.