Subversion Repositories checksum-tools

Rev

Rev 8 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. unit Unit3;
  2.  
  3. interface
  4.  
  5. uses
  6.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  7.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;
  8.  
  9. type
  10.   TForm3 = class(TForm)
  11.     Memo1: TMemo;
  12.     Label1: TLabel;
  13.     Memo2: TMemo;
  14.     Label2: TLabel;
  15.     Memo3: TMemo;
  16.     Label3: TLabel;
  17.     Memo4: TMemo;
  18.     Label4: TLabel;
  19.     Button1: TButton;
  20.     OpenDialog1: TOpenDialog;
  21.     Timer1: TTimer;
  22.     procedure Button1Click(Sender: TObject);
  23.     procedure FormShow(Sender: TObject);
  24.     procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  25.     procedure Timer1Timer(Sender: TObject);
  26.   private
  27.     FChecksumFile: string;
  28.   public
  29.     function ParamChecksumFile: string;
  30.     procedure LoadSFV;
  31.     procedure SaveSFV;
  32.   end;
  33.  
  34. var
  35.   Form3: TForm3;
  36.  
  37. implementation
  38.  
  39. {$R *.dfm}
  40.  
  41. uses
  42.   Common, SFV, MD5, LongFilenameOperations;
  43.  
  44. procedure TForm3.Button1Click(Sender: TObject);
  45. begin
  46.   SaveSFV;
  47.   LoadSFV;
  48. end;
  49.  
  50. procedure TForm3.FormKeyDown(Sender: TObject; var Key: Word;
  51.   Shift: TShiftState);
  52. begin
  53.   if (Shift = []) and (Key = VK_F6) then
  54.   begin
  55.     Key := 0;
  56.     SaveSFV;
  57.     LoadSFV;
  58.   end
  59.   else if (Shift = []) and (Key = VK_ESCAPE) then
  60.   begin
  61.     Key := 0;
  62.     Close;
  63.   end
  64.   else if (Shift = []) and (Key = VK_F5) then
  65.   begin
  66.     Key := 0;
  67.     LoadSFV;
  68.   end;
  69. end;
  70.  
  71. procedure TForm3.FormShow(Sender: TObject);
  72. begin
  73.   Caption := ParamChecksumFile;
  74.   Timer1.Enabled := true;
  75. end;
  76.  
  77. procedure TForm3.LoadSFV;
  78. var
  79.   FileName: string;
  80.   ADirectory: string;
  81.   slSFV: TStringList;
  82.   SR: TSearchRec;
  83.   IsFound: Boolean;
  84.   i: Integer;
  85.   TestFilename: string;
  86.   SollChecksum: string;
  87.   IstChecksum: string;
  88.   existingFiles: TStringList;
  89.   j: Integer;
  90.   csman: TCheckSumFile;
  91. begin
  92.   Color := clGray;
  93.   Refresh;
  94.  
  95.   FileName := ParamChecksumFile;
  96.   ADirectory := ExtractFilePath(FileName);
  97.  
  98.   if not FileExists(FileName) then
  99.   begin
  100.     ShowMessageFmt('File not found: %s', [FileName]);
  101.     Close;
  102.   end;
  103.  
  104.   Memo1.Clear;
  105.   Memo2.Clear;
  106.   Memo3.Clear;
  107.   Memo4.Clear;
  108.  
  109.   if SameText(ExtractFileExt(FileName), '.sfv') then
  110.     csman := TCheckSumFileSFV.Create(FileName)
  111.   else if SameText(ExtractFileExt(FileName), '.md5') then
  112.     csman := TCheckSumFileMD5.Create(FileName)
  113.   else
  114.     Exception.Create('Unknown file extension. Only supporting MD5 and SFV.');
  115.  
  116.   slSFV := TStringList.Create;
  117.   existingFiles := TStringList.Create;
  118.   try
  119.     // Read SFV/MD5 file
  120.     csman.ToStringList(slSFV);
  121.  
  122.     // List existing files
  123.     IsFound := FindFirst(ADirectory + '*', faAnyFile xor faDirectory, SR) = 0;
  124.     while IsFound do
  125.     begin
  126.       if (SR.Name <> '.') and (SR.Name <> '..') then
  127.       begin
  128.         existingFiles.Add(SR.Name);
  129.       end;
  130.       IsFound := FindNext(SR) = 0;
  131.     end;
  132.     FindClose(SR);
  133.  
  134.     // Checksum mismatch or missing files
  135.     for i := 0 to slSFV.Count-1 do
  136.     begin
  137.       TestFilename := IncludeTrailingPathDelimiter(ADirectory) + slSFV.Strings[i];
  138.       SollChecksum := TCheckSum(slSFV.Objects[i]).checksum;
  139.       if not FileExists(TestFilename) then
  140.       begin
  141.         Memo3.Lines.Add(csman.MergeLine(slSFV.Strings[i], SollChecksum));
  142.       end
  143.       else
  144.       begin
  145.         IstChecksum  := csman.SingleFileChecksum(TestFilename);
  146.         if SameText(SollChecksum, IstChecksum) then
  147.         begin
  148.           Memo1.Lines.Add(csman.MergeLine(slSFV.Strings[i], SollChecksum));
  149.         end
  150.         else
  151.         begin
  152.           Memo2.Lines.Add('; [CURRENT FILE CHECKSUM] ' + csman.MergeLine(slSFV.Strings[i], IstChecksum));
  153.           Memo2.Lines.Add(csman.MergeLine(slSFV.Strings[i], SollChecksum));
  154.         end;
  155.  
  156.         {$IFDEF MSWINDOWS}
  157.         existingFiles.CaseSensitive := false;
  158.         {$ELSE}
  159.         existingFiles.CaseSensitive := true;
  160.         {$ENDIF}
  161.         j := existingFiles.IndexOf(slSFV.Strings[i]);
  162.         if j >= 0 then existingFiles.Delete(j);
  163.       end;
  164.     end;
  165.  
  166.     // Check non-indexed files
  167.     for i := 0 to existingFiles.Count-1 do
  168.     begin
  169.       TestFileName := existingFiles[i];
  170.       if not SameText(ExtractFileExt(TestFileName), '.sfv') and
  171.          not SameText(ExtractFileExt(TestFileName), '.md5') and
  172.          not SameText(TestFileName, 'Thumbs.db') then
  173.       begin
  174.         IstChecksum  := csman.SingleFileChecksum(IncludeTrailingPathDelimiter(ADirectory) + TestFilename);
  175.         Memo4.Lines.Add(csman.MergeLine(TestFileName, IstChecksum));
  176.       end;
  177.     end;
  178.  
  179.     if (Memo2.Text = '') and (Memo3.Text = '') and (Memo4.Text = '') then
  180.       Color := clMoneyGreen
  181.     else if (Memo2.Text <> '') then
  182.       Color := clRed
  183.     else
  184.       Color := clYellow;
  185.  
  186.     Memo1.SelStart := 0;
  187.     Memo1.SelLength := 0;
  188.     Memo2.SelStart := 0;
  189.     Memo2.SelLength := 0;
  190.     Memo3.SelStart := 0;
  191.     Memo3.SelLength := 0;
  192.     Memo4.SelStart := 0;
  193.     Memo4.SelLength := 0;
  194.  
  195.     if Memo2.Text <> '' then Memo2.SetFocus
  196.     else if Memo3.Text <> '' then Memo3.SetFocus
  197.     else if Memo4.Text <> '' then Memo4.SetFocus
  198.     else Memo1.SetFocus;
  199.   finally
  200.     FreeAndNil(slSFV);
  201.     FreeAndNil(existingFiles);
  202.     FreeAndNil(csman);
  203.   end;
  204. end;
  205.  
  206. function TForm3.ParamChecksumFile: string;
  207. begin
  208.   if FChecksumFile <> '' then
  209.   begin
  210.     result := FChecksumFile;
  211.   end
  212.   else
  213.   begin
  214.     result := ParamStr(1);
  215.     if result = '' then
  216.     begin
  217.       if not OpenDialog1.Execute then
  218.       begin
  219.         Close;
  220.         Abort;
  221.       end;
  222.       result := OpenDialog1.FileName;
  223.     end;
  224.     FChecksumFile := result;
  225.   end;
  226. end;
  227.  
  228. procedure TForm3.SaveSFV;
  229. var
  230.   hFile: THandle;
  231.   i: Integer;
  232.   slOut: TStringList;
  233. begin
  234.   MyAssignFile(hFile, ParamChecksumFile);
  235.   try
  236.     MyRewrite(hFile); // clear File
  237.  
  238.     slOut := TStringList.Create;
  239.     try
  240.       // Fill slOut with the Memo contents
  241.       for i := 0 to memo1.Lines.Count-1 do
  242.       begin
  243.         slOut.Add(Memo1.Lines[i]);
  244.       end;
  245.       for i := 0 to memo2.Lines.Count-1 do
  246.       begin
  247.         slOut.Add(Memo2.Lines[i]);
  248.       end;
  249.       for i := 0 to memo3.Lines.Count-1 do
  250.       begin
  251.         slOut.Add(Memo3.Lines[i]);
  252.       end;
  253.       for i := 0 to memo4.Lines.Count-1 do
  254.       begin
  255.         slOut.Add(Memo4.Lines[i]);
  256.       end;
  257.  
  258.       // Sort
  259.       slOut.Sort;
  260.  
  261.       // Write to SFV/MD5 file
  262.       for i := 0 to slOut.Count-1 do
  263.       begin
  264.         if Trim(slOut[i]) <> '' then
  265.           MyWriteLn(hFile, AnsiString(utf8encode(slOut[i])));
  266.       end;
  267.     finally
  268.       FreeAndNil(slOut);
  269.     end;
  270.   finally
  271.     MyCloseFile(hFile);
  272.   end;
  273. end;
  274.  
  275. procedure TForm3.Timer1Timer(Sender: TObject);
  276. begin
  277.   Timer1.Enabled := false;
  278.   LoadSFV;
  279. end;
  280.  
  281. end.
  282.