Subversion Repositories checksum-tools

Rev

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

Rev Author Line No. Line
6 daniel-mar 1
unit Unit3;
2
 
3
interface
4
 
5
uses
6
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
8 daniel-mar 7
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;
6 daniel-mar 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;
8 daniel-mar 21
    Timer1: TTimer;
6 daniel-mar 22
    procedure Button1Click(Sender: TObject);
23
    procedure FormShow(Sender: TObject);
8 daniel-mar 24
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
25
    procedure Timer1Timer(Sender: TObject);
6 daniel-mar 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
 
8 daniel-mar 50
procedure TForm3.FormKeyDown(Sender: TObject; var Key: Word;
51
  Shift: TShiftState);
7 daniel-mar 52
begin
8 daniel-mar 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;
7 daniel-mar 69
end;
70
 
6 daniel-mar 71
procedure TForm3.FormShow(Sender: TObject);
72
begin
73
  Caption := ParamChecksumFile;
8 daniel-mar 74
  Timer1.Enabled := true;
6 daniel-mar 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
8 daniel-mar 92
  Color := clGray;
93
  Refresh;
94
 
6 daniel-mar 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
7 daniel-mar 123
    IsFound := FindFirst(ADirectory + '*', faAnyFile xor faDirectory, SR) = 0;
6 daniel-mar 124
    while IsFound do
125
    begin
126
      if (SR.Name <> '.') and (SR.Name <> '..') then
127
      begin
8 daniel-mar 128
        existingFiles.Add(SR.Name);
6 daniel-mar 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
8 daniel-mar 145
        IstChecksum  := csman.SingleFileChecksum(TestFilename);
6 daniel-mar 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
 
8 daniel-mar 156
        {$IFDEF MSWINDOWS}
157
        existingFiles.CaseSensitive := false;
158
        {$ELSE}
159
        existingFiles.CaseSensitive := true;
160
        {$ENDIF}
161
        j := existingFiles.IndexOf(slSFV.Strings[i]);
6 daniel-mar 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
10 daniel-mar 174
        IstChecksum  := csman.SingleFileChecksum(IncludeTrailingPathDelimiter(ADirectory) + TestFilename);
6 daniel-mar 175
        Memo4.Lines.Add(csman.MergeLine(TestFileName, IstChecksum));
176
      end;
177
    end;
7 daniel-mar 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;
8 daniel-mar 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;
6 daniel-mar 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;
8 daniel-mar 232
  slOut: TStringList;
6 daniel-mar 233
begin
234
  MyAssignFile(hFile, ParamChecksumFile);
8 daniel-mar 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);
6 daniel-mar 272
  end;
273
end;
274
 
8 daniel-mar 275
procedure TForm3.Timer1Timer(Sender: TObject);
276
begin
277
  Timer1.Enabled := false;
278
  LoadSFV;
279
end;
280
 
6 daniel-mar 281
end.