Subversion Repositories checksum-tools

Rev

Rev 10 | 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.   if Copy(FileName, 2, 1) = ':' then FileName := '\\?\' + FileName; // To allow long filenames
  97.   ADirectory := ExtractFilePath(FileName);
  98.  
  99.   if not FileExists(FileName) then
  100.   begin
  101.     ShowMessageFmt('File not found: %s', [FileName]);
  102.     Close;
  103.   end;
  104.  
  105.   Memo1.Clear;
  106.   Memo2.Clear;
  107.   Memo3.Clear;
  108.   Memo4.Clear;
  109.  
  110.   if SameText(ExtractFileExt(FileName), '.sfv') then
  111.     csman := TCheckSumFileSFV.Create(FileName)
  112.   else if SameText(ExtractFileExt(FileName), '.md5') then
  113.     csman := TCheckSumFileMD5.Create(FileName)
  114.   else
  115.     Exception.Create('Unknown file extension. Only supporting MD5 and SFV.');
  116.  
  117.   slSFV := TStringList.Create;
  118.   existingFiles := TStringList.Create;
  119.   try
  120.     // Read SFV/MD5 file
  121.     csman.ToStringList(slSFV);
  122.  
  123.     // List existing files
  124.     IsFound := FindFirst(ADirectory + '*', faAnyFile xor faDirectory, SR) = 0;
  125.     while IsFound do
  126.     begin
  127.       if (SR.Name <> '.') and (SR.Name <> '..') then
  128.       begin
  129.         existingFiles.Add(SR.Name);
  130.       end;
  131.       IsFound := FindNext(SR) = 0;
  132.     end;
  133.     FindClose(SR);
  134.  
  135.     // Checksum mismatch or missing files
  136.     for i := 0 to slSFV.Count-1 do
  137.     begin
  138.       TestFilename := IncludeTrailingPathDelimiter(ADirectory) + slSFV.Strings[i];
  139.       SollChecksum := TCheckSum(slSFV.Objects[i]).checksum;
  140.       if not FileExists(TestFilename) then
  141.       begin
  142.         Memo3.Lines.Add(csman.MergeLine(slSFV.Strings[i], SollChecksum));
  143.       end
  144.       else
  145.       begin
  146.         IstChecksum  := csman.SingleFileChecksum(TestFilename);
  147.         if SameText(SollChecksum, IstChecksum) then
  148.         begin
  149.           Memo1.Lines.Add(csman.MergeLine(slSFV.Strings[i], SollChecksum));
  150.         end
  151.         else
  152.         begin
  153.           Memo2.Lines.Add('; [CURRENT FILE CHECKSUM] ' + csman.MergeLine(slSFV.Strings[i], IstChecksum));
  154.           Memo2.Lines.Add(csman.MergeLine(slSFV.Strings[i], SollChecksum));
  155.         end;
  156.  
  157.         {$IFDEF MSWINDOWS}
  158.         existingFiles.CaseSensitive := false;
  159.         {$ELSE}
  160.         existingFiles.CaseSensitive := true;
  161.         {$ENDIF}
  162.         j := existingFiles.IndexOf(slSFV.Strings[i]);
  163.         if j >= 0 then existingFiles.Delete(j);
  164.       end;
  165.     end;
  166.  
  167.     // Check non-indexed files
  168.     for i := 0 to existingFiles.Count-1 do
  169.     begin
  170.       TestFileName := existingFiles[i];
  171.       if not SameText(ExtractFileExt(TestFileName), '.sfv') and
  172.          not SameText(ExtractFileExt(TestFileName), '.md5') and
  173.          not SameText(TestFileName, 'Thumbs.db') then
  174.       begin
  175.         IstChecksum  := csman.SingleFileChecksum(IncludeTrailingPathDelimiter(ADirectory) + TestFilename);
  176.         Memo4.Lines.Add(csman.MergeLine(TestFileName, IstChecksum));
  177.       end;
  178.     end;
  179.  
  180.     if (Memo2.Text = '') and (Memo3.Text = '') and (Memo4.Text = '') then
  181.       Color := clMoneyGreen
  182.     else if (Memo2.Text <> '') then
  183.       Color := clRed
  184.     else
  185.       Color := clYellow;
  186.  
  187.     Memo1.SelStart := 0;
  188.     Memo1.SelLength := 0;
  189.     Memo2.SelStart := 0;
  190.     Memo2.SelLength := 0;
  191.     Memo3.SelStart := 0;
  192.     Memo3.SelLength := 0;
  193.     Memo4.SelStart := 0;
  194.     Memo4.SelLength := 0;
  195.  
  196.     if Memo2.Text <> '' then Memo2.SetFocus
  197.     else if Memo3.Text <> '' then Memo3.SetFocus
  198.     else if Memo4.Text <> '' then Memo4.SetFocus
  199.     else Memo1.SetFocus;
  200.   finally
  201.     FreeAndNil(slSFV);
  202.     FreeAndNil(existingFiles);
  203.     FreeAndNil(csman);
  204.   end;
  205. end;
  206.  
  207. function TForm3.ParamChecksumFile: string;
  208. begin
  209.   if FChecksumFile <> '' then
  210.   begin
  211.     result := FChecksumFile;
  212.   end
  213.   else
  214.   begin
  215.     result := ParamStr(1);
  216.     if result = '' then
  217.     begin
  218.       if not OpenDialog1.Execute then
  219.       begin
  220.         Close;
  221.         Abort;
  222.       end;
  223.       result := OpenDialog1.FileName;
  224.     end;
  225.     FChecksumFile := result;
  226.   end;
  227. end;
  228.  
  229. procedure TForm3.SaveSFV;
  230. var
  231.   hFile: THandle;
  232.   i: Integer;
  233.   slOut: TStringList;
  234. begin
  235.   MyAssignFile(hFile, ParamChecksumFile);
  236.   try
  237.     MyRewrite(hFile); // clear File
  238.  
  239.     slOut := TStringList.Create;
  240.     try
  241.       // Fill slOut with the Memo contents
  242.       for i := 0 to memo1.Lines.Count-1 do
  243.       begin
  244.         slOut.Add(Memo1.Lines[i]);
  245.       end;
  246.       for i := 0 to memo2.Lines.Count-1 do
  247.       begin
  248.         slOut.Add(Memo2.Lines[i]);
  249.       end;
  250.       for i := 0 to memo3.Lines.Count-1 do
  251.       begin
  252.         slOut.Add(Memo3.Lines[i]);
  253.       end;
  254.       for i := 0 to memo4.Lines.Count-1 do
  255.       begin
  256.         slOut.Add(Memo4.Lines[i]);
  257.       end;
  258.  
  259.       // Sort
  260.       slOut.Sort;
  261.  
  262.       // Write to SFV/MD5 file
  263.       for i := 0 to slOut.Count-1 do
  264.       begin
  265.         if Trim(slOut[i]) <> '' then
  266.           MyWriteLn(hFile, AnsiString(utf8encode(slOut[i])));
  267.       end;
  268.     finally
  269.       FreeAndNil(slOut);
  270.     end;
  271.   finally
  272.     MyCloseFile(hFile);
  273.   end;
  274. end;
  275.  
  276. procedure TForm3.Timer1Timer(Sender: TObject);
  277. begin
  278.   Timer1.Enabled := false;
  279.   LoadSFV;
  280. end;
  281.  
  282. end.
  283.