unit_pea.pas (peazip-7.7.0.src) | : | unit_pea.pas (peazip-7.7.1.src) | ||
---|---|---|---|---|
skipping to change at line 164 | skipping to change at line 164 | |||
key schedule of each cipher is based on a dif ferent hash primitive which is run for a different number of iterations | key schedule of each cipher is based on a dif ferent hash primitive which is run for a different number of iterations | |||
Whirlpool x 25000 for AES, SHA512 x 50000 fo r Twofish, SHA3-512 x 75000 for Serpent (Whirlpool is significantly slower than SHA512 that is slower than SHA3-512) | Whirlpool x 25000 for AES, SHA512 x 50000 fo r Twofish, SHA3-512 x 75000 for Serpent (Whirlpool is significantly slower than SHA512 that is slower than SHA3-512) | |||
key schedule of each cipher is provided a sep arate 96 byte pseudorandom salt | key schedule of each cipher is provided a sep arate 96 byte pseudorandom salt | |||
password is modified when provided as input f or key schedule of each cipher | password is modified when provided as input f or key schedule of each cipher | |||
modification are trivial xor with non secret values and counters, with the sole purpose to initialize the key derivation wit h different values and be a further factor (alongside different salt, and differ ent hash / iteration number) to guarantee keys are a statistically independent | modification are trivial xor with non secret values and counters, with the sole purpose to initialize the key derivation wit h different values and be a further factor (alongside different salt, and differ ent hash / iteration number) to guarantee keys are a statistically independent | |||
Password verification tag is the xor of the 3 password verification tags of each encryption function, and is written / verifie d after all 3 key initialization functions are completed before verification | Password verification tag is the xor of the 3 password verification tags of each encryption function, and is written / verifie d after all 3 key initialization functions are completed before verification | |||
Each block between password verification tag a nd stream authentication tag is encrypted with all 3 ciphers | Each block between password verification tag a nd stream authentication tag is encrypted with all 3 ciphers | |||
A 1..128 bytes block of random data is added a fter password verification tag in order to mask exact archive size | A 1..128 bytes block of random data is added a fter password verification tag in order to mask exact archive size | |||
Each cipher generate its own 128 bit sized str eam authentication tag, tags are concatenated and hashed with SHA3-384; the SHA3 -384 value is checked for verification, this requires all the 3 tags to match to expected values and does not allow ciphers to be authenticated separately | Each cipher generate its own 128 bit sized str eam authentication tag, tags are concatenated and hashed with SHA3-384; the SHA3 -384 value is checked for verification, this requires all the 3 tags to match to expected values and does not allow ciphers to be authenticated separately | |||
0.75 20201206 G.Tani Recompiled with updated theming | 0.75 20201206 G.Tani Recompiled with updated theming | |||
0.76 20210121 G.Tani Improved quoting on Unix-like sistems, fixes | ||||
(C) Copyright 2006 Giorgio Tani giorgio.tani.software@gmail.com | (C) Copyright 2006 Giorgio Tani giorgio.tani.software@gmail.com | |||
The program is released under GNU LGPL http://www.gnu.org/licenses/lgpl.txt | The program is released under GNU LGPL http://www.gnu.org/licenses/lgpl.txt | |||
This library is free software; you can redistribute it and/or | This library is free software; you can redistribute it and/or | |||
modify it under the terms of the GNU Lesser General Public | modify it under the terms of the GNU Lesser General Public | |||
License as published by the Free Software Foundation; either | License as published by the Free Software Foundation; either | |||
version 3 of the License, or (at your option) any later version. | version 3 of the License, or (at your option) any later version. | |||
skipping to change at line 211 | skipping to change at line 212 | |||
type | type | |||
{ TForm_pea } | { TForm_pea } | |||
TForm_pea = class(TForm) | TForm_pea = class(TForm) | |||
Bevel10: TBevel; | Bevel10: TBevel; | |||
Bevel11: TBevel; | Bevel11: TBevel; | |||
Bevel9: TBevel; | Bevel9: TBevel; | |||
ButtonDone1: TBitBtn; | ButtonDone1: TBitBtn; | |||
ButtonPeaExit1: TBitBtn; | ||||
ButtonPW1: TBitBtn; | ButtonPW1: TBitBtn; | |||
ButtonPW2: TBitBtn; | ButtonPW2: TBitBtn; | |||
ButtonPeaExit: TBitBtn; | ||||
ButtonRefSize: TButton; | ButtonRefSize: TButton; | |||
ButtonUtilsCancel: TBitBtn; | ButtonUtilsCancel: TBitBtn; | |||
ButtonToolsCancel: TBitBtn; | ButtonToolsCancel: TBitBtn; | |||
ButtonUtilsOK: TBitBtn; | ButtonUtilsOK: TBitBtn; | |||
ButtonRFSinteractive: TBitBtn; | ButtonRFSinteractive: TBitBtn; | |||
ButtonRFSinteractive1: TBitBtn; | ButtonRFSinteractive1: TBitBtn; | |||
ButtonUtilsReset: TSpeedButton; | ButtonUtilsReset: TSpeedButton; | |||
ComboBox1: TComboBox; | ComboBox1: TComboBox; | |||
ComboBox2: TComboBox; | ComboBox2: TComboBox; | |||
ComboBox3: TComboBox; | ComboBox3: TComboBox; | |||
skipping to change at line 298 | skipping to change at line 301 | |||
peautilsmenu: TPopupMenu; | peautilsmenu: TPopupMenu; | |||
ProgressBar1: TProgressBar; | ProgressBar1: TProgressBar; | |||
Shape2: TShape; | Shape2: TShape; | |||
ShapeE1: TShape; | ShapeE1: TShape; | |||
ShapeE2: TShape; | ShapeE2: TShape; | |||
peautilsbtn: TSpeedButton; | peautilsbtn: TSpeedButton; | |||
SpinEdit1: TSpinEdit; | SpinEdit1: TSpinEdit; | |||
Timer1: TTimer; | Timer1: TTimer; | |||
procedure Bevel12ChangeBounds(Sender: TObject); | procedure Bevel12ChangeBounds(Sender: TObject); | |||
procedure ButtonDone1Click(Sender: TObject); | procedure ButtonDone1Click(Sender: TObject); | |||
procedure ButtonPeaExitClick(Sender: TObject); | ||||
procedure ButtonPW1Click(Sender: TObject); | procedure ButtonPW1Click(Sender: TObject); | |||
procedure ButtonPW2Click(Sender: TObject); | procedure ButtonPW2Click(Sender: TObject); | |||
procedure ButtonRFSinteractive1Click(Sender: TObject); | procedure ButtonRFSinteractive1Click(Sender: TObject); | |||
procedure ButtonRFSinteractiveClick(Sender: TObject); | procedure ButtonRFSinteractiveClick(Sender: TObject); | |||
procedure ButtonToolsCancelClick(Sender: TObject); | procedure ButtonToolsCancelClick(Sender: TObject); | |||
procedure ButtonUtilsCancelClick(Sender: TObject); | procedure ButtonUtilsCancelClick(Sender: TObject); | |||
procedure ButtonUtilsResetClick(Sender: TObject); | procedure ButtonUtilsResetClick(Sender: TObject); | |||
procedure ButtonUtilsOKClick(Sender: TObject); | procedure ButtonUtilsOKClick(Sender: TObject); | |||
procedure ComboBox1Change(Sender: TObject); | procedure ComboBox1Change(Sender: TObject); | |||
procedure ComboBoxUtilsChange(Sender: TObject); | procedure ComboBoxUtilsChange(Sender: TObject); | |||
skipping to change at line 338 | skipping to change at line 342 | |||
procedure Timer1Timer(Sender: TObject); | procedure Timer1Timer(Sender: TObject); | |||
private | private | |||
{ private declarations } | { private declarations } | |||
public | public | |||
{ public declarations } | { public declarations } | |||
end; | end; | |||
Type fileofbyte = file of byte; | Type fileofbyte = file of byte; | |||
const | const | |||
P_RELEASE = '0.75'; //declares release version for the whole build | P_RELEASE = '0.76'; //declares release version for the whole build | |||
PEAUTILS_RELEASE = '1.3'; //declares for reference last peautils release | PEAUTILS_RELEASE = '1.3'; //declares for reference last peautils release | |||
PEA_FILEFORMAT_VER = 1; | PEA_FILEFORMAT_VER = 1; | |||
PEA_FILEFORMAT_REV = 3; //version and revision declared to be implemented must match with the ones in pea_utils, otherwise a warning will be raised (form capt ion) | PEA_FILEFORMAT_REV = 3; //version and revision declared to be implemented must match with the ones in pea_utils, otherwise a warning will be raised (form capt ion) | |||
SBUFSIZE = 32768; | SBUFSIZE = 32768; | |||
{32KB of size for reading small buffers, used for ciphers and hashes} | {32KB of size for reading small buffers, used for ciphers and hashes} | |||
WBUFSIZE = 1048576; | WBUFSIZE = 1048576; | |||
{1MB of size for reading whide buffers, used for compression. | {1MB of size for reading whide buffers, used for compression. | |||
Decompression may read arbitrarily sized buffers up to array size used for | Decompression may read arbitrarily sized buffers up to array size used for | |||
wide buffers -64KB (left for possible data expansion)} | wide buffers -64KB (left for possible data expansion)} | |||
{$IFDEF MSWINDOWS} | {$IFDEF MSWINDOWS} | |||
skipping to change at line 2085 | skipping to change at line 2089 | |||
MD5Digest,MD5Digest_obj,MD5Digest_volume: TMD5Digest; | MD5Digest,MD5Digest_obj,MD5Digest_volume: TMD5Digest; | |||
crc64,crc64_obj,crc64_volume:TCRC64; | crc64,crc64_obj,crc64_volume:TCRC64; | |||
ts_start:TTimeStamp; | ts_start:TTimeStamp; | |||
f_in,f_out:file of byte; | f_in,f_out:file of byte; | |||
sbuf1,sbuf2:array [0..65535] of byte; | sbuf1,sbuf2:array [0..65535] of byte; | |||
tagbuf,exp_auth:array [0..63] of byte; | tagbuf,exp_auth:array [0..63] of byte; | |||
compr_level,headersize,authsize,obj_authsize,volume_authsize,archive_datetime encoding,storead:byte; | compr_level,headersize,authsize,obj_authsize,volume_authsize,archive_datetime encoding,storead:byte; | |||
pw_len,fns:word; | pw_len,fns:word; | |||
adler,crc32,adler_obj,crc32_obj,adler_volume,crc32_volume:longint; | adler,crc32,adler_obj,crc32_obj,adler_volume,crc32_volume:longint; | |||
i,j,ci,cj,h,k,numread,numwritten,n_chunks,n_dirs,n_input_files,compsize,uncom psize,addr,fage,fattrib,buf_size:dword; | i,j,ci,cj,h,k,numread,numwritten,n_chunks,n_dirs,n_input_files,compsize,uncom psize,addr,fage,fattrib,buf_size:dword; | |||
total,wrk_space,exp_space,cent_size,fs,nobj,out_size,qw0,qw1,qw2,qw3,qw4,qw5, | total,wrk_space,exp_space,cent_size,fs,out_size,qw0,qw1,qw2,qw3,qw4,qw5,qw6,q | |||
qw6,qw7:qword; | w7:qword; | |||
nobj:int64; | ||||
stream_error,obj_error,volume_error,end_of_archive,pwneeded,chunks_ok,filenam ed,out_created,no_more_files,readingstream,readingheader,readingfns,readingtrigg er,readingfn,readingfs,readingfage,readingfattrib,readingcompsize,fassigned,read ingf,readingcompblock,readingobjauth,readingauth,singlevolume:boolean; | stream_error,obj_error,volume_error,end_of_archive,pwneeded,chunks_ok,filenam ed,out_created,no_more_files,readingstream,readingheader,readingfns,readingtrigg er,readingfn,readingfs,readingfage,readingfattrib,readingcompsize,fassigned,read ingf,readingcompblock,readingobjauth,readingauth,singlevolume:boolean; | |||
subroot,basedir,s,in_file,in_name,in_folder,out_path,out_file,algo,obj_algo,v olume_algo,compr,fn:ansistring; | subroot,basedir,s,in_file,in_name,in_folder,out_path,out_file,algo,obj_algo,v olume_algo,compr,fn:ansistring; | |||
label 1; | label 1; | |||
procedure clean_variables; | procedure clean_variables; | |||
begin | begin | |||
i:=0; | i:=0; | |||
j:=0; | j:=0; | |||
h:=0; | h:=0; | |||
k:=0; | k:=0; | |||
skipping to change at line 5193 | skipping to change at line 5198 | |||
Form_pea.LabelOpen.Visible:=true; | Form_pea.LabelOpen.Visible:=true; | |||
Form_pea.LabelOpen.Enabled:=false; | Form_pea.LabelOpen.Enabled:=false; | |||
Form_pea.LabelLog1.Visible:=true; | Form_pea.LabelLog1.Visible:=true; | |||
end; | end; | |||
//procedure to checksum/hash files | //procedure to checksum/hash files | |||
procedure check; //ALL: all algorithms, otherwise specify the algorithm to use f ollowed by "on" which marks the input parameters | procedure check; //ALL: all algorithms, otherwise specify the algorithm to use f ollowed by "on" which marks the input parameters | |||
var | var | |||
sbuf:array [1..32767] of byte; | sbuf:array [1..32767] of byte; | |||
i,j,n,t,td,te,k,dmax,dmin,x,icount,iver,rc,dup,icol:integer; | i,j,n,t,td,te,k,dmax,dmin,x,icount,iver,rc,dup,icol:integer; | |||
f_size,nfiles,ntfiles,ndirs,ctsize,etsize,tsize,nfound,ntotalexp,time,speed,c | f_size,nfiles,ntfiles,ndirs,ctsize,etsize,tsize,nfound,ntotalexp,time,speed,c | |||
ompest,compsize,smax,smin:qword; | ompest,compsize:qword; | |||
smax,smin:int64; | ||||
exp_files:TFoundList; | exp_files:TFoundList; | |||
exp_fsizes:TFoundListSizes; | exp_fsizes:TFoundListSizes; | |||
exp_ftimes:TFoundListAges; | exp_ftimes:TFoundListAges; | |||
exp_fattr:TFoundListAttrib; | exp_fattr:TFoundListAttrib; | |||
exp_fattr_dec:TFoundList; | exp_fattr_dec:TFoundList; | |||
tsin,tsout:TTimestamp; | tsin,tsout:TTimestamp; | |||
mode,dummystr,oper,moded,sdig:ansistring; | mode,dummystr,oper,moded,sdig:ansistring; | |||
dummyansistr:ansistring; | dummyansistr:ansistring; | |||
pgpsig:TPGPDigest; | pgpsig:TPGPDigest; | |||
Adler:longint; | Adler:longint; | |||
skipping to change at line 6594 | skipping to change at line 6600 | |||
interacting:=false; | interacting:=false; | |||
end; | end; | |||
{ TForm_pea } | { TForm_pea } | |||
procedure TForm_pea.ButtonDone1Click(Sender: TObject); | procedure TForm_pea.ButtonDone1Click(Sender: TObject); | |||
begin | begin | |||
Close; | Close; | |||
end; | end; | |||
procedure TForm_pea.ButtonPeaExitClick(Sender: TObject); | ||||
begin | ||||
halt; | ||||
end; | ||||
procedure TForm_pea.Bevel12ChangeBounds(Sender: TObject); | procedure TForm_pea.Bevel12ChangeBounds(Sender: TObject); | |||
begin | begin | |||
end; | end; | |||
procedure TForm_pea.ButtonPW1Click(Sender: TObject); | procedure TForm_pea.ButtonPW1Click(Sender: TObject); | |||
begin | begin | |||
if (EditPW1.Text='') and (EditConfirm1.Text='') then pw:='default' | if (EditPW1.Text='') and (EditConfirm1.Text='') then pw:='default' | |||
else | else | |||
if (upcase(paramstr(1))='PEA') and (EditPW1.Text<>EditConfirm1.Text) then | if (upcase(paramstr(1))='PEA') and (EditPW1.Text<>EditConfirm1.Text) then | |||
skipping to change at line 6719 | skipping to change at line 6730 | |||
{$ENDIF} | {$ENDIF} | |||
end; | end; | |||
procedure TForm_pea.ButtonUtilsOKClick(Sender: TObject); | procedure TForm_pea.ButtonUtilsOKClick(Sender: TObject); | |||
var | var | |||
cl,bin_name,in_param:ansistring; | cl,bin_name,in_param:ansistring; | |||
i:integer; | i:integer; | |||
P:TProcessUTF8; | P:TProcessUTF8; | |||
begin | begin | |||
Form_report.StringGrid1.PopupMenu:=nil; | Form_report.StringGrid1.PopupMenu:=nil; | |||
bin_name:=delimiter+escapefilename(executable_path,desk_env)+'pea'+EXEEXT+delimi ter; | bin_name:=stringdelim(escapefilename(executable_path,desk_env)+'pea'+EXEEXT); | |||
in_param:=''; | in_param:=''; | |||
cl:=''; | cl:=''; | |||
for i:=0 to ListMemo.Lines.Count do | for i:=0 to ListMemo.Lines.Count do | |||
if length(ListMemo.Lines[i])>1 then | if length(ListMemo.Lines[i])>1 then | |||
in_param:=in_param+delimiter+ListMemo.Lines[i]+delimiter+' '; | in_param:=in_param+stringdelim(ListMemo.Lines[i])+' '; | |||
case ComboBoxUtils.ItemIndex of | case ComboBoxUtils.ItemIndex of | |||
16: begin end; | 16: begin end; | |||
17: begin end; | 17: begin end; | |||
18: begin end; | 18: begin end; | |||
else if in_param='' then exit; | else if in_param='' then exit; | |||
end; | end; | |||
case ComboBoxUtils.ItemIndex of | case ComboBoxUtils.ItemIndex of | |||
0: cl:=bin_name+' CHECK HEX CRC32 ON '+in_param; | 0: cl:=bin_name+' CHECK HEX CRC32 ON '+in_param; | |||
1: cl:=bin_name+' CHECK HEX CRC64 ON '+in_param; | 1: cl:=bin_name+' CHECK HEX CRC64 ON '+in_param; | |||
2: cl:=bin_name+' CHECK HEX MD5 ON '+in_param; | 2: cl:=bin_name+' CHECK HEX MD5 ON '+in_param; | |||
3: cl:=bin_name+' CHECK HEX RIPEMD160 ON '+in_param; | 3: cl:=bin_name+' CHECK HEX RIPEMD160 ON '+in_param; | |||
4: cl:=bin_name+' CHECK HEX SHA1 ON '+in_param; | 4: cl:=bin_name+' CHECK HEX SHA1 ON '+in_param; | |||
5: cl:=bin_name+' CHECK HEX BLAKE2S ON '+in_param; | 5: cl:=bin_name+' CHECK HEX BLAKE2S ON '+in_param; | |||
6: cl:=bin_name+' CHECK HEX SHA256 ON '+in_param; | 6: cl:=bin_name+' CHECK HEX SHA256 ON '+in_param; | |||
7: cl:=bin_name+' CHECK HEX SHA3_256 ON '+in_param; | 7: cl:=bin_name+' CHECK HEX SHA3_256 ON '+in_param; | |||
8: cl:=bin_name+' CHECK HEX CRC32 CRC64 MD5 RIPEMD160 SHA1 BLAKE2S SHA256 SHA 3_256 ON '+in_param; | 8: cl:=bin_name+' CHECK HEX CRC32 CRC64 MD5 RIPEMD160 SHA1 BLAKE2S SHA256 SHA 3_256 ON '+in_param; | |||
9: cl:=bin_name+' CHECK HEX ALL ON '+in_param; | 9: cl:=bin_name+' CHECK HEX ALL ON '+in_param; | |||
10: cl:=bin_name+' CHECK HEX LIST ON '+in_param; | 10: cl:=bin_name+' CHECK HEX LIST ON '+in_param; | |||
11: cl:=bin_name+' RFS AUTONAME ASK NONE BATCH '+delimiter+ListMemo.Lines[0]+ | 11: cl:=bin_name+' RFS AUTONAME ASK NONE BATCH '+stringdelim(ListMemo.Lines[0 | |||
delimiter; //one file | ]); //one file | |||
12: cl:=bin_name+' RFJ '+delimiter+ListMemo.Lines[0]+delimiter+' BATCH AUTONA | 12: cl:=bin_name+' RFJ '+stringdelim(ListMemo.Lines[0])+' BATCH AUTONAME'; // | |||
ME'; //one file (strictly) | one file (strictly) | |||
13: cl:=bin_name+' COMPARE '+in_param; //two files or one file (ask for secon d file, ignores more files) | 13: cl:=bin_name+' COMPARE '+in_param; //two files or one file (ask for secon d file, ignores more files) | |||
14: cl:=bin_name+' HEXPREVIEW '+delimiter+ListMemo.Lines[0]+delimiter; //one file | 14: cl:=bin_name+' HEXPREVIEW '+stringdelim(ListMemo.Lines[0]); //one file | |||
15: begin | 15: begin | |||
if MessageDlg('Do you want to securely delete selected file(s)? The operat ion can''t be undone and files will be not recoverable', mtWarning, [mbYes,mbNo] , 0)=6 then | if MessageDlg('Do you want to securely delete selected file(s)? The operat ion can''t be undone and files will be not recoverable', mtWarning, [mbYes,mbNo] , 0)=6 then | |||
begin | begin | |||
cl:=bin_name+' WIPE MEDIUM '+in_param; | cl:=bin_name+' WIPE MEDIUM '+in_param; | |||
P:=TProcessUTF8.Create(nil); | P:=TProcessUTF8.Create(nil); | |||
P.Options := [poNoConsole,poWaitOnExit]; | P.Options := [poNoConsole,poWaitOnExit]; | |||
cl:=(cl); | cl:=(cl); | |||
P.CommandLine:=cl; | P.CommandLine:=cl; | |||
if validatecl(cl)<>0 then begin MessageDlg('Operation stopped, potentia lly dangerous command detected (i.e. command concatenation not allowed within th e program): '+cl, mtWarning, [mbOK], 0); exit; end; | if validatecl(cl)<>0 then begin MessageDlg('Operation stopped, potentia lly dangerous command detected (i.e. command concatenation not allowed within th e program): '+cl, mtWarning, [mbOK], 0); exit; end; | |||
P.Execute; | P.Execute; | |||
skipping to change at line 7069 | skipping to change at line 7080 | |||
setpbitmap(Badmin,i16res); | setpbitmap(Badmin,i16res); | |||
Form_pea.peautilsbtn.Glyph:=Butils; | Form_pea.peautilsbtn.Glyph:=Butils; | |||
Form_pea.pmrunasadmin.Bitmap:=Badmin; | Form_pea.pmrunasadmin.Bitmap:=Badmin; | |||
Form_pea.Image3.Picture.Bitmap:=Binfo; | Form_pea.Image3.Picture.Bitmap:=Binfo; | |||
Form_pea.Image4.Picture.Bitmap:=Binfo; | Form_pea.Image4.Picture.Bitmap:=Binfo; | |||
Form_pea.Image5.Picture.Bitmap:=Binfo; | Form_pea.Image5.Picture.Bitmap:=Binfo; | |||
Form_pea.Image7.Picture.Bitmap:=Binfo; | Form_pea.Image7.Picture.Bitmap:=Binfo; | |||
Form_pea.ImageUtils.Picture.Bitmap:=Binfo; | Form_pea.ImageUtils.Picture.Bitmap:=Binfo; | |||
Form_pea.buttonpw1.Glyph:=Bok; | Form_pea.buttonpw1.Glyph:=Bok; | |||
Form_pea.buttonpw2.Glyph:=Bcancel; | Form_pea.buttonpw2.Glyph:=Bcancel; | |||
Form_pea.ButtonPeaExit.Glyph:=Bcancel; | ||||
Form_pea.ButtonPeaExit1.Glyph:=Bcancel; | ||||
Form_pea.buttonrfsinteractive.Glyph:=Bok; | Form_pea.buttonrfsinteractive.Glyph:=Bok; | |||
Form_pea.buttonrfsinteractive1.Glyph:=Bcancel; | Form_pea.buttonrfsinteractive1.Glyph:=Bcancel; | |||
Form_pea.buttonutilsok.Glyph:=Bok; | Form_pea.buttonutilsok.Glyph:=Bok; | |||
Form_pea.buttonutilscancel.Glyph:=Bcancel; | Form_pea.buttonutilscancel.Glyph:=Bcancel; | |||
Form_pea.buttontoolscancel.Glyph:=Bcancel; | Form_pea.buttontoolscancel.Glyph:=Bcancel; | |||
except | except | |||
//MessageDlg('some icons not found', mtWarning, [mbOK], 0); //it's deactivat ed in final compilation to allow the program to work outside of PeaZip package | //MessageDlg('some icons not found', mtWarning, [mbOK], 0); //it's deactivat ed in final compilation to allow the program to work outside of PeaZip package | |||
end; | end; | |||
end; | end; | |||
End of changes. 13 change blocks. | ||||
12 lines changed or deleted | 25 lines changed or added |