;--------------------------------------------------------------------------------------------------------------------
#ifndef IS_ENHANCED
#error Enhanced edition of Inno Setup (restools) is required to compile this script
#endif
;--------------------------------------------------------------------------------------------------------------------
[Setup]
AppName=ISMD5_Example
AppVerName=ISMD5_Example
DefaultDirName={pf}\ISMD5_Example
OutputDir=.
ShowLanguageDialog=auto
OutputBaseFilename=ISMD5
VersionInfoCopyright=Shegorat, nik1967
VersionInfoVersion=1.0.0.1
[Languages]
Name: rus; MessagesFile: compiler:Languages\Russian.isl
Name: eng; MessagesFile: compiler:Default.isl
[CustomMessages]
rus.Wait=Подождите, идет проверка хеш-сумм установочных файлов...
rus.Check=Проверка MD5 — «%1» — %2
rus.Check1=Проверка MD5
rus.Close=Вы действительно хотите пропустить проверку MD5?%nЕсли хэш-суммы файлов не совпадут,%nто установка может пройти некорректно.%nПропустить проверку?
rus.Close1=Отмена проверки MD5
rus.Error=Вы можете на свой страх и риск продолжить установку.%nПродолжить установку?
rus.Error1=Хеш-сумма файла — «%1» — не совпадает!
rus.Yes=Да
rus.No=Нет
rus.MB=мб
rus.GB=гб
rus.TB=тб
rus.Comparing=Сравнение хеш-суммы файла: «%1» (%2)
rus.Skip=Пропустить
rus.Foundfiles=Проверяется файл: %1 из %2
rus.GSize=Проверено: %1 из %2
eng.Wait=Wait, checking the hash-sum of installation files...
eng.Check=Checking the MD5 — «%1» — %2
eng.Check1=Checking the MD5
eng.Close=You really want to skip MD5 check?%nIf a hash amount of files won't match, installation%ncan incorrectly pass.%nTo skip check?
eng.Close1=Canceling of check MD5
eng.Error=You can continue installation on your own risk.%nContinue installation?
eng.Error1=Hash sum of file — «%1» — is incorrect!
eng.Yes=Yes
eng.No=No
eng.MB=mb
eng.GB=gb
eng.TB=tb
eng.Comparing=Comparing file hash-sum: «%1» (%2)
eng.Skip=Skip
eng.Foundfiles=Check files: %1 of %2
eng.GSize=Checked: %1 of %2
[Files]
Source: Include\ISMD5.dll; Flags: dontcopy;
[code]
const
ID_QUESTION = 65579; // вопрос
ID_HAND = 65581; // ошибка
type
TMD5Callback = function (Progress: Longword): Boolean;
var
MD5Form,MyExit,MyError: TSetupForm;
MD5PB: TNewProgressBar;
Res,Total,CurN,i: Integer;
CloseForm,Md5Error,CanClose: boolean;
OkButton, CancelButton: TButton;
Ico: TNewIconImage;
CheckMD5Label,CheckMD5Label2,CheckMD5Label3,CheckMD5Label4: TLabel;
CurFilename: String;
CurSize: DWORD;
TotalProgress: Longword;
TSize: Extended;
Path,Md5Value: array [1..100] of String;
//-----------------------------------------------------------------------------------------
// РАБОТА С Md5 //* прверка md5 хэш-суммы файлов */
procedure Md5;
begin
//-----------------------------------------------------------------------------------------
Path[1]:= '{src}\data.cst'; //* Путь и название 1 файла */
Md5Value[1]:= '44af4bd126520ab01d5ff10ff98c79a2'; //* Хэш-сумма 1 файла */
//-----------------------------------------------------------------------------------------
Path[2]:= '{src}\data1.cst'; //* Путь и название 2 файла */
Md5Value[2]:= '9c00f97b15759a1b1129e1ee0b3918a0'; //* Хэш-сумма 2 файла */
//-----------------------------------------------------------------------------------------
Path[3]:= '{src}\data2.cst'; //* Путь и название 3 файла */
Md5Value[3]:= '84ff580c1e89a80cc0090006d0289819'; //* Хэш-сумма 3 файла */
//-----------------------------------------------------------------------------------------
Path[4]:= '{src}\data3.cst'; //* Путь и название 4 файла */
Md5Value[4]:= 'db28493dfa366c24096f64e391fca4af'; //* Хэш-сумма 4 файла */
//-----------------------------------------------------------------------------------------
Path[5]:= '{src}\data4.cst'; //* Путь и название 5 файла */
Md5Value[5]:= '38734d7d8eabb219d6ffdd230df836a0'; //* Хэш-сумма 5 файла */
//-----------------------------------------------------------------------------------------
Path[6]:= '{src}\'; //* Путь и название 6 файла */
Md5Value[6]:= '45b4a905dc382cea77301c8fe5df00ea'; //* Хэш-сумма 6 файла */
//-----------------------------------------------------------------------------------------
Path[7]:= '{src}\'; //* Путь и название 7 файла */
Md5Value[7]:= '194b5c29333ff8cea740a82ef523574b'; //* Хэш-сумма 7 файла */
//-----------------------------------------------------------------------------------------
Path[8]:= '{src}\'; //* Путь и название 8 файла */
Md5Value[8]:= '5f7d4fd3e7dc28ed416f3f142acecdfa'; //* Хэш-сумма 8 файла */
//-----------------------------------------------------------------------------------------
Path[9]:= '{src}\'; //* Путь и название 9 файла */
Md5Value[9]:= '452ffd71a37efd0a7d475e56b58986be'; //* Хэш-сумма 9 файла */
//-----------------------------------------------------------------------------------------
Path[10]:= '{src}\'; //* Путь и название 10 файла */
Md5Value[10]:= '544098c5ebca81430f7e152b51fb5dc1'; //* Хэш-сумма 10 файла */
//-----------------------------------------------------------------------------------------
Path[11]:= '{src}\'; //* Путь и название 11 файла */
Md5Value[11]:= '292d10f72266b639d8b369c11c0d9734'; //* Хэш-сумма 11 файла */
//-----------------------------------------------------------------------------------------
Path[12]:= '{src}\'; //* Путь и название 12 файла */
Md5Value[12]:= 'cadd81bf0a7e0616281c9287b0f57398'; //* Хэш-сумма 12 файла */
//-----------------------------------------------------------------------------------------
Path[13]:= '{src}\'; //* Путь и название 13 файла */
Md5Value[13]:= 'dcf47d289880d40c27523071d3163dba'; //* Хэш-сумма 13 файла */
//-----------------------------------------------------------------------------------------
Path[14]:= '{src}\'; //* Путь и название 14 файла */
Md5Value[14]:= 'c9ce3deb8816c2b307b7f987930adc7c'; //* Хэш-сумма 14 файла */
//-----------------------------------------------------------------------------------------
Path[15]:= '{src}\'; //* Путь и название 15 файла */
Md5Value[15]:= 'c9ce3deb8816c2b307b7f987930adc7c'; //* Хэш-сумма 15 файла */
//-----------------------------------------------------------------------------------------
// ..................................................................................
//-----------------------------------------------------------------------------------------
//Path[100]:= '{src}\'; //* Путь и название 100 файла */
//Md5Value[100]:= 'c9ce3deb8816c2b307b7f987930adc7c'; //* Хэш-сумма 100 файла */
//-----------------------------------------------------------------------------------------
end;
//-----------------------------------------------------------------------------------------
function MbOrTb(Float: Extended): String;
begin
if Float < 1024 then Result:= FormatFloat('0', Float)+ExpandConstant(' {cm:MB}') else
if Float/1024 < 1024 then Result:= format('%.2n', [Float/1024])+ExpandConstant(' {cm:GB}') else
Result:= format('%.2n', [Float/(1024*1024)])+ExpandConstant(' {cm:TB}');
StringChange(Result, ',', '.');
end;
function CheckMD5(Filename: PAnsiChar; MD5: PAnsiChar; Callback: TMD5Callback): Boolean; external 'CheckMD5@files:ISMD5.dll stdcall';
function MD5Progress(Progress: Longword): Boolean;
begin
MD5PB.Position:= TotalProgress+(Progress*CurSize div Trunc(TSize))+1;
CheckMD5Label3.Caption:= FmtMessage('%1.%2 %', [IntToStr(MD5PB.Position div 10), chr(48 + MD5PB.Position mod 10)]);
CheckMD5Label4.Caption:= FmtMessage(ExpandConstant('{cm:GSize}'), [MbOrTb(Trunc(TSize) * MD5PB.Position div 1000), MbOrTb(TSize)]);
MD5Form.Caption:= FmtMessage(ExpandConstant('{cm:Check}'), [CurFilename, CheckMD5Label3.Caption]);
Application.ProcessMessages;
if CloseForm then
Result:= false
else
Result:= True;
end;
function Size64(Hi, Lo: Integer): Extended;
begin
Result:= Lo;
if Lo<0 then Result:= Result + $7FFFFFFF + $7FFFFFFF + 2;
for Hi:= Hi-1 Downto 0 do
Result:= Result + $7FFFFFFF + $7FFFFFFF + 2;
end;
function GetFileSize(const FileName: string): Extended;
var
FSR: TFindRec;
begin
Result:= 0;
if FindFirst(FileName, FSR) then
try
if FSR.Attributes and FILE_ATTRIBUTE_DIRECTORY = 0 then
Result:= Size64(FSR.SizeHigh, FSR.SizeLow) div (1024*1024);
finally
FindClose(FSR);
end;
end;
function Exists(const FileName: string): Extended;
var
Size: Extended;
begin
if FileExists(FileName) then begin
Size:= GetFileSize(FileName);
TSize:= TSize+Size;
Total:= Total+1;
end;
end;
function CheckMD(Filename, MD5: String): Boolean;
begin
TotalProgress:= MD5PB.Position;
Result:= True;
if FileExists(Filename) then begin
CurFilename:= ExtractFilename(FileName);
CurN:= CurN+1;
CheckMD5Label2.Caption:= FmtMessage(ExpandConstant('{cm:Foundfiles}'), [IntToStr(CurN), IntToStr(Total)]);
if GetFileSize(FileName)*(1024*1024) <> 0 then begin
CurSize:= Trunc(GetFileSize(FileName));
CheckMD5Label.Caption:= FmtMessage(ExpandConstant('{cm:Comparing}'), [CurFilename, MbOrTb(CurSize)]);
Result:= CheckMD5(Filename, PAnsiChar(MD5), @MD5Progress);
end else begin
MD5Form.Free;
Result:= false;
end;
end;
end;
procedure MD5FormClose(Sender: TObject; var CanClose: Boolean);
begin
MD5Form.Hide;
CanClose:= false;
MyExit:= CreateCustomForm();
with MyExit do begin
ClientWidth:= ScaleX(360);
ClientHeight:= ScaleY(150);
Caption:= ExpandConstant('{cm:Close1}');
Ico:= TNewIconImage.Create(MyExit);
with Ico do begin
Parent:= MyExit;
Left:= ScaleX(20);
Top:= ScaleY(40);
Icon.Handle:= ID_QUESTION;
end;
with TBevel.Create(MyExit) do begin
SetBounds(ScaleX(0),ScaleY(105),MyExit.Width,ScaleY(2));
Parent:= MyExit;
end;
with TNewStaticText.Create(MyExit) do begin
Left:= ScaleX(65);
Top:= ScaleY(25);
Width:= ScaleX(278);
Height:= ScaleY(60);
AutoSize:= False;
WordWrap:= True;
Caption:= ExpandConstant('{cm:Close}');
Parent:= MyExit;
end;
CancelButton:= TButton.Create(MyExit);
with CancelButton do begin
Width:= ScaleX(75);
Height:= ScaleY(23);
Left:= MyExit.Width - Width - ScaleX(15);
Top:= MyExit.Height - Height * 2 - ScaleY(13);
Caption:= ExpandConstant('{cm:No}');
ModalResult:= mrCancel;
Parent:= MyExit;
end;
OkButton:= TButton.Create(MyExit);
with OkButton do begin
Width:= CancelButton.Width;
Height:= CancelButton.Height;
Left:= CancelButton.Left - Width - ScaleX(5);
Top:= CancelButton.Top;
Caption:= ExpandConstant('{cm:Yes}');
ModalResult:= mrOk;
Parent:= MyExit;
end;
ActiveControl:= CancelButton;
Center;
end;
if MyExit.ShowModal() = mrCancel then begin
CloseForm:= false;
MD5Form.Show;
end else begin
CloseForm:= true;
if FileExists(ExpandConstant('{src}\setup.exe')) then
Exec(ExpandConstant('{src}\setup.exe'), '', '', SW_SHOWNORMAL, ewNoWait, Res);
end;
end;
procedure CBClick(Sender: TObject);
begin
MD5FormClose(Sender,CanClose);
end;
function InitializeSetup(): Boolean;
begin
Md5();
for i:= 1 to 100 do
Exists(ExpandConstant(Path[i]));
MD5Form:= CreateCustomForm();
with MD5Form do begin
ClientWidth:= ScaleX(360);
ClientHeight:= ScaleY(150);
OnCloseQuery:= @MD5FormClose;
Center;
end;
with TLabel.Create(MD5Form) do begin
SetBounds(ScaleX(5),ScaleY(5),ScaleX(350),ScaleY(15));
Caption:= ExpandConstant('{cm:Wait}');
Transparent:= True;
Parent:= MD5Form;
end;
CheckMD5Label:= TLabel.Create(MD5Form);
with CheckMD5Label do begin
SetBounds(ScaleX(5),ScaleY(25),ScaleX(350),ScaleY(15));
Transparent:= True;
Parent:= MD5Form;
end;
CheckMD5Label2:= TLabel.Create(MD5Form);
with CheckMD5Label2 do begin
SetBounds(ScaleX(5),ScaleY(65),ScaleX(300),ScaleY(15));
Transparent:= True;
Parent:= MD5Form;
end;
CheckMD5Label3:= TLabel.Create(MD5Form);
with CheckMD5Label3 do begin
SetBounds(ScaleX(240),ScaleY(70),ScaleX(50),ScaleY(15));
Transparent:= True;
Font.Size:= 14;
Parent:= MD5Form;
end;
CheckMD5Label4:= TLabel.Create(MD5Form);
with CheckMD5Label4 do begin
SetBounds(ScaleX(5),ScaleY(85),ScaleX(300),ScaleY(15));
Transparent:= True;
Parent:= MD5Form;
end;
MD5PB:= TNewProgressBar.Create(MD5Form);
with MD5PB do begin
Min:= 0;
Max:= 1000;
SetBounds(ScaleX(5),ScaleY(45),ScaleX(350),ScaleY(15));
Parent:= MD5Form;
end;
with TBevel.Create(MD5Form) do begin
SetBounds(ScaleX(0),ScaleY(105),MD5Form.Width,ScaleY(2));
Parent:= MD5Form;
end;
CancelButton:= TButton.Create(MD5Form);
with CancelButton do begin
Width:= ScaleX(75);
Height:= ScaleY(23);
Left:= MD5Form.Width - Width - ScaleX(15);
Top:= MD5Form.Height - Height * 2 - ScaleY(13);
Caption:= ExpandConstant('{cm:Skip}');
OnClick:= @CBClick;
Parent:= MD5Form;
end;
MD5Form.Show;
Application.Title:= ExpandConstant('{cm:Check1}');
for i:= 1 to Total+1 do begin
Md5Error:= true;
if not CheckMD(ExpandConstant(Path[i]),Md5Value[i]) then break;
Md5Error:= false;
end;
if not CloseForm and not Md5Error then
if FileExists(ExpandConstant('{src}\setup.exe')) then
Exec(ExpandConstant('{src}\setup.exe'), '', '', SW_SHOWNORMAL, ewNoWait, Res);
if not CloseForm and Md5Error then begin
MD5Form.Hide;
MyError:= CreateCustomForm();
with MyError do begin
ClientWidth:= ScaleX(360);
ClientHeight:= ScaleY(150);
Caption:= FmtMessage(ExpandConstant('{cm:Error1}'), [CurFilename]);
Ico:= TNewIconImage.Create(MyError);
with Ico do begin
Parent:= MyError;
Left:= ScaleX(20);
Top:= ScaleY(40);
Icon.Handle:= ID_HAND;
end;
with TBevel.Create(MyError) do begin
SetBounds(ScaleX(0),ScaleY(105),MyError.Width,ScaleY(2));
Parent:= MyError;
end;
with TNewStaticText.Create(MyError) do begin
Left:= ScaleX(65);
Top:= ScaleY(35);
Width:= ScaleX(278);
Height:= ScaleY(60);
AutoSize:= False;
WordWrap:= True;
Caption:= ExpandConstant('{cm:Error}');
Parent:= MyError;
end;
CancelButton:= TButton.Create(MyError);
with CancelButton do begin
Width:= ScaleX(75);
Height:= ScaleY(23);
Left:= MyError.Width - Width - ScaleX(15);
Top:= MyError.Height - Height * 2 - ScaleY(13);
Caption:= ExpandConstant('{cm:No}');
ModalResult:= mrCancel;
Parent:= MyError;
end;
OkButton:= TButton.Create(MyError);
with OkButton do begin
Width:= CancelButton.Width;
Height:= CancelButton.Height;
Left:= CancelButton.Left - Width - ScaleX(5);
Top:= CancelButton.Top;
Caption:= ExpandConstant('{cm:Yes}');
ModalResult:= mrOk;
Parent:= MyError;
end;
ActiveControl:= CancelButton;
Center;
end;
if MyError.ShowModal() = mrOk then
if FileExists(ExpandConstant('{src}\setup.exe')) then
Exec(ExpandConstant('{src}\setup.exe'), '', '', SW_SHOWNORMAL, ewNoWait, Res);
end;
end;