This commit is contained in:
Alexander 2023-02-02 12:02:14 +03:00
parent 703d2d5a52
commit 8e2f0fdd9c
94 changed files with 25754 additions and 1 deletions

View File

@ -1,3 +1,69 @@
# JarUnPacker
#### Версия: 2023.01.31
#### Автор: Александр Бабаев
Проект Lazarus для распаковки / упаковки JAR файлов
## Описание
Проект Lazarus для распаковки / упаковки JAR файлов. Может распаковать jar файл, составив список, и упаковать jar файл по списку.
## Лицензия
### Определения
**JarUnPacker** (далее «_программа_» или «_продукт_») - программа и её исходный код, на которое распространяется данное соглашение.
**Конечный пользователь** (далее «_вы_» или «_пользователь_») - лицо и/или организация, которое(-ая) использует программу.
**Автор** - человек, написавший программу.
### ОГРАНИЧЕНИЯ
В некоторых государствах (районах, областях, штатах) не позволяется ограничение или исключение ответственности за непредвиденный ущерб. Если ваша страна (район, область, штат) не подразумевает ограничение или исключение ответственности за непредвиденный ущерб, то данное соглашение не может применяться к вам. В этом случае откажитесь от использования продукта.
В некоторых государствах (районах, областях, штатах) не позволяется исключение подразумеваемых гарантий. Если ваша страна (район, область, штат) не подразумевает исключение подразумеваемых гарантий, то данное соглашение не может применяться к вам. В этом случае откажитесь от использования продукта.
### ПРЕДМЕТ СОГЛАШЕНИЯ
Данное соглашение заключается между автором и пользователем и определяет отношения между ними, возникающие при загрузке и использовании программы.
### ЛИЦЕНЗИЯ
Файл распространяется по принципу «**AS-IS**» («**КАК ЕСТЬ**»). Администрация не несет **НИКАКОЙ ОТВЕТСТВЕННОСТИ** в случае нанесения данной программой физического, материального или любого другого вреда вам и вашему компьютеру. Вы на свой страх и риск загружаете программу. Администрация не несёт никакой ответственности за ошибки, неисправности (и т.п.), нанесенные программой вашему компьютеру.
Вы можете использовать данную программу на свое усмотрение, а также копировать и распространять со ссылкой на автора и сайт "https://babaev-an.ru/". Вам запрещается копировать, распространять продукт без ссылки на автора и указанный ранее сайт. Вам запрещается копирование и использование программы, если устанавливаемая вами копия файла не имеет ссылки на автора и указанный ранее сайт.
ЕСЛИ ВЫ ЗАГРУЖАЕТЕ, КОПИРУЕТЕ ФАЙЛ ИЛИ ИСПОЛЬЗУЕТЕ ЕГО КАКИМ-ЛИБО ДРУГИМ СПОСОБОМ, ЭТИМ ВЫ ПОДТВЕРЖДАЕТЕ СВОЕ СОГЛАСИЕ СОБЛЮДАТЬ УСЛОВИЯ ДАННОГО ЛИЦЕНЗИОННОГО СОГЛАШЕНИЯ С КОНЕЧНЫМ ПОЛЬЗОВАТЕЛЕМ. ЕСЛИ ВЫ НЕ СОГЛАСНЫ, НЕ УСТАНАВЛИВАЙТЕ, НЕ КОПИРУЙТЕ И НЕ ИСПОЛЬЗУЙТЕ ФАЙЛ.
### АВТОРСКОЕ ПРАВО
Авторское право на все копии файла принадлежат его автору и защищено законодательством РФ и ряда других стран.
### ОГРАНИЧЕННАЯ ГАРАНТИЯ И ПРАВОВАЯ ОГОВОРКА
Вам не дается никаких гарантий. Все ваши возможные требования, притязания и претензии (в том числе и по качеству) будут **НЕПРИЗНАННЫ**.
### ОГРАНИЧЕНИЕ ОТВЕТСТВЕННОСТИ
Вам не дается никаких обязательств. Все ваши возможные требования будут **НЕПРИЗНАННЫ**.
### Область использования
Программу можно использовать в коммерческой и не коммерческой деятельности.
## Использование
Для распаковки jar архива передайте селудующие параметры:
* `extract="Имя_JAR_файла"` - инициализация распаковки и задание файла для распаковки.
* `target="Имя_папки"` - папка извлечения.
* `listFile="Имя_файла_списка"` - имя файла для списка распакованных файлов.
Рассмотрим пример: вам надо распаковать файл `C:\demo\demo.jar` в папку `C:\extract_to\` и сохранить список распакованных файлов в файл `C:\demo\list.txt`
```
jarunpacker.exe /extract="C:\demo\demo.jar" /target="C:\extract_to\" /listFile="C:\demo\list.txt"
```
Для упаковки jar архива передайте селудующие параметры:
* `compress="Имя_JAR_файла"` - инициализация упаковки и задание файла jar.
* `from="Имя_папки"` - папка с файлами.
* `filesList="Имя_файла_списка"` - имя файла для списка файлов для упаковки.
Рассмотрим пример: вам надо упаковать в файл `C:\demo\demo.jar` из папки `C:\extract_to\` по списку файлов из файла `C:\demo\list.txt`
```
jarunpacker.exe /compress="C:\demo\demo.jar" /from="C:\extract_to\" /filesList="C:\demo\list.txt"
```

View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<Package Version="4">
<PathDelim Value="\"/>
<Name Value="ANBSTCP"/>
<Type Value="RunAndDesignTime"/>
<Author Value="Александр Бабаев"/>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<OtherUnitFiles Value="data"/>
<UnitOutputDirectory Value="data\lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<CodeGeneration>
<Optimizations>
<OptimizationLevel Value="3"/>
</Optimizations>
</CodeGeneration>
</CompilerOptions>
<Description Value="ANB ST Components Pack"/>
<License Value="ЛИЦЕНЗИОНОЕ СОГЛАШЕНИЕ С КОНЕЧНЫМ ПОЛЬЗОВАТЕЛЕМ (EULA) НА ANB ST COMPONENTS PACK.
(Версия 1.0)
ОПРЕДЕЛЕНИЯ
ANB ST COMPONENTS PACK (или просто ASTCP) (далее &quot;ПРОДУКТ&quot;) - программа и/или компонент программы и/или другое (игра, изображение, фильм и т.п.), на которое распространяется данное соглашение.
КОНЕЧНЫЙ ПОЛЬЗОВАТЕЛЬ (далее &quot;ВЫ&quot; или &quot;ПОЛЬЗОВАТЕЛЬ&quot;) - лицо и/или организация, которое(-ая) использует продукт, предоставляемый под этой лицензией.
АЛЕКСАНДР БАБАЕВ (далее &quot;ПРОИЗВОДИТЕЛЬ&quot;) - лицо и/или организация, которое(-ая) произвело продукт.
ОГРАНИЧЕНИЯ
В некоторых государствах (районах, областях, штатах) не позволяется ограничение или исключение ответственности за непредвиденный ущерб. Если ваша страна (район, область, штат) не подразумевает ограничение или исключение ответственности за непредвиденный ущерб, то данное соглашение не может применяться к вам. В этом случае откажитесь от использования продукта.
В некоторых государствах (районах, областях, штатах) не позволяется исключение подразумеваемых гарантий. Если ваша страна (район, область, штат) не подразумевает исключение подразумеваемых гарантий, то данное соглашение не может применяться к вам. В этом случае откажитесь от использования продукта.
ПРЕДМЕТ СОГЛАШЕНИЯ
Данное соглашение заключается между Производителем продукта и Пользователем продукта. Данное соглашение определяет отношения между Производителем и Пользователем, возникающие при использовании продукта.
ЛИЦЕНЗИЯ
Продукт распространяется по принципу &quot;AS-IS&quot; (&quot;КАК ЕСТЬ&quot;). Автор не несёт НИКАКОЙ ОТВЕТСТВЕННОСТИ в случае нанесения данной программой физического, материального или любого другого вреда вам и вашему компьютеру. Вы на свой страх и риск устанавливаете продукт. Производитель и/или Распространитель не несёт(-ут) никакой ответственности за ошибки, неисправности (и т.п.), нанесённые продуктом вашему компьютеру. Вы можете использовать данную программу на своё усмотрение, а также копировать и распространять со ссылкой на автора, сайт &quot;http://anbsoftteam.com/&quot;.
Вам запрещается копировать, распространять продукт без ссылки на автора и указанные ранее сайты. Вам запрещается копирование и использование продукта, если устанавливаемая вами копия продукта не имеет ссылки на автора и указанные ранее сайты. Вам запрещается ипользовать компоненты продукта в других программах без письменного соглашения Производителя, удалять или исправлять в продукте любые знаки о праве собственности и/или авторском праве на продукт.
ЕСЛИ ВЫ ЗАГРУЖАЕТЕ, КОПИРУЕТЕ ПРОДУКТ ИЛИ ИСПОЛЬЗУЕТЕ ЕГО КАКИМ-ЛИБО ДРУГИМ СПОСОБОМ, ЭТИМ ВЫ ПОДТВЕРЖДАЕТЕ СВОЕ СОГЛАСИЕ СОБЛЮДАТЬ УСЛОВИЯ ДАННОГО
ЛИЦЕНЗИОННОГО СОГЛАШЕНИЯ С КОНЕЧНЫМ ПОЛЬЗОВАТЕЛЕМ. ЕСЛИ ВЫ НЕ СОГЛАСНЫ, НЕ УСТАНАВЛИВАЙТЕ, НЕ КОПИРУЙТЕ И НЕ ИСПОЛЬЗУЙТЕ ПРОДУКТ.
АВТОРСКОЕ ПРАВО
Авторское право на все копии продукта принадлежат Производителю и частично Распространителю и защищено законодательством РФ и ряда других стран.
ОГРАНИЧЕННАЯ ГАРАНТИЯ И ПРАВОВАЯ ОГОВОРКА
Вам не даётся никаких гарантий. Все ваши возможные требования, притязания и претензии (в том числе и по качеству) будут НЕПРИЗНАННЫ.
ОГРАНИЧЕНИЕ ОТВЕТСТВЕННОСТИ
Вам не даётся никаких обязательств. Все ваши возможные требования будут НЕПРИЗНАНЫ.
СПАСИБО, ЧТО ИСПОЛЬЗУЕТЕ &quot;ANB ST COMPONENTS PACK&quot;!"/>
<Version Major="1" Minor="8" Release="25" Build="70"/>
<Files Count="10">
<Item1>
<Filename Value="data\ANBFormatString.pas"/>
<UnitName Value="ANBFormatString"/>
</Item1>
<Item2>
<Filename Value="data\ParamsMngr.pas"/>
<UnitName Value="ParamsMngr"/>
</Item2>
<Item3>
<Filename Value="data\SimplyINI.pas"/>
<UnitName Value="SimplyINI"/>
</Item3>
<Item4>
<Filename Value="data\VCLEx.pas"/>
<UnitName Value="VCLEx"/>
</Item4>
<Item5>
<Filename Value="data\ANBInputBox.pas"/>
<UnitName Value="ANBInputBox"/>
</Item5>
<Item6>
<Filename Value="data\VersionControl.pas"/>
<UnitName Value="VersionControl"/>
</Item6>
<Item7>
<Filename Value="data\SimplyJSON.pas"/>
<UnitName Value="SimplyJSON"/>
</Item7>
<Item8>
<Filename Value="data\FileUtilsEx.pas"/>
<UnitName Value="FileUtilsEx"/>
</Item8>
<Item9>
<Filename Value="data\GraphicsEx.pas"/>
<UnitName Value="GraphicsEx"/>
</Item9>
<Item10>
<Filename Value="data\MsgBoxes.pas"/>
<UnitName Value="sfp_msgboxes"/>
</Item10>
</Files>
<RequiredPkgs Count="3">
<Item1>
<PackageName Value="dd_versioninfo"/>
</Item1>
<Item2>
<PackageName Value="LCL"/>
</Item2>
<Item3>
<PackageName Value="FCL"/>
</Item3>
</RequiredPkgs>
<UsageOptions>
<UnitPath Value="$(PkgOutDir)"/>
</UsageOptions>
<PublishOptions>
<Version Value="2"/>
</PublishOptions>
<CustomOptions Items="ExternHelp" Version="2">
<_ExternHelp Items="Count"/>
</CustomOptions>
</Package>
</CONFIG>

View File

@ -0,0 +1,22 @@
{ This file was automatically created by Lazarus. Do not edit!
This source is only used to compile and install the package.
}
unit ANBSTCP;
{$warn 5023 off : no warning about unused units}
interface
uses
ANBFormatString, ParamsMngr, SimplyINI, VCLEx, ANBInputBox, VersionControl,
SimplyJSON, FileUtilsEx, GraphicsEx, MsgBoxes, LazarusPackageIntf;
implementation
procedure Register;
begin
end;
initialization
RegisterPackage('ANBSTCP', @Register);
end.

View File

@ -0,0 +1,72 @@
unit ANBFormatString;
{$MODE Delphi}
{$codepage UTF8}
interface
uses StrUtils, SysUtils, VCLEx;
{stdcalls}
function FormatStr(const AFrmtdStr: String; const AArgs, AArgsValues: array of String): String; STDCALL;
function FormatStrW(const AFrmtdStr: WideString; const AArgs, AArgsValues: array of WideString): WideString; STDCALL;
implementation
function SearchAndReplaceStr(const AStr, ASearchStr, AReplaceStr: String): String;
var CurrDelim, NextDelim: IntEx;
ElemName, s: String;
begin
s:= '';
CurrDelim:= 1;
repeat
NextDelim:= PosEx(ASearchStr, AStr, CurrDelim);
if NextDelim = 0 then
NextDelim:= Length(AStr) + 1;
ElemName:= Copy(AStr, CurrDelim, NextDelim - CurrDelim);
if not (NextDelim > Length(AStr)) then
s:= s + ElemName + AReplaceStr
else
s:= s + ElemName;
CurrDelim:= NextDelim + Length(ASearchStr);
until CurrDelim > Length(AStr);
Result:= s;
end;
{Only for Windows}
function SearchAndReplaceStrW(const AStr, ASearchStr, AReplaceStr: WideString): WideString;
var CurrDelim, NextDelim: IntEx;
ElemName, s: WideString;
begin
s:= '';
CurrDelim:= 1;
repeat
NextDelim:= PosEx(ASearchStr, AStr, CurrDelim);
if NextDelim = 0 then
NextDelim:= Length(AStr) + 1;
ElemName:= Copy(AStr, CurrDelim, NextDelim - CurrDelim);
if not (NextDelim > Length(AStr)) then
s:= s + ElemName + AReplaceStr
else
s:= s + ElemName;
CurrDelim:= NextDelim + Length(ASearchStr);
until CurrDelim > Length(AStr);
Result:= s;
end;
function FormatStr(const AFrmtdStr: string; const AArgs, AArgsValues: array of String): String;
var i: IntEx;
s: String;
begin
s:= AFrmtdStr;
if High(AArgs) <> High(AArgsValues) then
raise Exception.Create('Array of arguments not equal array of its values!');
for i:= 0 to High(AArgs) do
s:= SearchAndReplaceStr(s, AArgs[i], AArgsValues[i]);
Result:= s;
end;
{Only for Windows}
function FormatStrW(const AFrmtdStr: WideString; const AArgs, AArgsValues: array of WideString): WideString;
var i: IntEx;
s: WideString;
begin
s:= AFrmtdStr;
if High(AArgs) <> High(AArgsValues) then
raise Exception.Create('Array of arguments not equal array of its values!');
for i:= 0 to High(AArgs) do
s:= SearchAndReplaceStrW(s, AArgs[i], AArgsValues[i]);
Result:= s;
end;
end.

View File

@ -0,0 +1,401 @@
unit ANBInputBox;
{$MODE Delphi}
{$codepage UTF8}
interface
uses LCLIntf, LCLType, SysUtils, Graphics, Controls, Forms, StdCtrls, Classes, Types, MaskEdit, Spin, VCLEx;
function ShowInputBox (const ACaption, APrompt, ADefault: String; var isAccept: Boolean): String; OVERLOAD; STDCALL;
function ShowInputBox (const ACaption, APrompt, ADefault: String; const ABtnCaptions: array of String; var isAccept: Boolean): String; OVERLOAD; STDCALL;
function ShowInputBox (const ACaption, APrompt, ADefault: String; const ABtnCaptions: array of String; const AMaxLength: IntEx; var isAccept: Boolean): String; OVERLOAD; STDCALL;
function ShowPasswordInputBox (const ACaption, APrompt, ADefault, APassword: String; var isAccept, isPasswordConfirmed: Boolean; const APasswordChar: Char = '*'): String; OVERLOAD; STDCALL;
function ShowPasswordInputBox (const ACaption, APrompt, ADefault, APassword: String; var isAccept, isPasswordConfirmed: Boolean; const ABtnCaptions: array of String; const APasswordChar: Char = '*'): String; OVERLOAD; STDCALL;
function ShowComboBox (const ACaption, APrompt: String; var Items: TStringList; const ADefaultIndex: IntEx; var isAccept: Boolean): IntEx; OVERLOAD; STDCALL;
function ShowComboBox (const ACaption, APrompt: String; var Items: TStringList; const ADefaultIndex: IntEx; const ABtnsCaption: array of String; var isAccept: Boolean): IntEx; OVERLOAD; STDCALL;
function ShowMaskedBox (const ACaption, APrompt, AMask, ADefault: String; const isIgnoreMask: Boolean; var isAccept: Boolean): String; OVERLOAD; STDCALL;
function ShowMaskedBox (const ACaption, APrompt, AMask, ADefault: String; const isIgnoreMask: Boolean; const ABtnCaptions: array of String; const AMaxLength: IntEx; var isAccept: Boolean): String; OVERLOAD; STDCALL;
function ShowSpinedBox (const ACaption, APrompt: String; const ADefault: IntEx; var isAccept: Boolean): IntEx; STDCALL; OVERLOAD;
function ShowSpinedBox (const ACaption, APrompt: String; const ADefault, AMinValue, AMaxValue: IntEx; const ABtnCaptions: array of String; var isAccept: Boolean): IntEx; STDCALL; OVERLOAD;
const OkBtnDefCaption: String = '&Ok';
CancelBtnDefCaption: String = 'C&ancel';
implementation
function MyGetAveCharSize(Canvas: TCanvas): TPoint;
var I: IntEx;
Buffer: array[0..51] of Char;
begin
with Result do
begin
x:= 0;
y:= 0;
end;
for I:= 0 to 25 do
Buffer[I]:= Chr(I + Ord('A'));
for I:= 0 to 25 do
Buffer[I + 26]:= Chr(I + Ord('a'));
GetTextExtentPoint(Canvas.Handle, Buffer, 52, TSize(Result));
Result.X:= Result.X div 52;
end;
function MyInputQuery(const ACaption, APrompt: String; var Value: String; var APasswordConfirmed: Boolean; const APassword: Boolean; const ANeedPassword: String; const APasswordChar: Char; const AMaxLength: IntEx; const ABtnsCaption: array of String): Boolean;
var Form: TForm;
Prompt: TLabel;
Edit: TEdit;
DialogUnits: TPoint;
ButtonTop, ButtonWidth, ButtonHeight: IntEx;
begin
Result:= false;
Form:= TForm.Create(Application);
with Form do
try
Canvas.Font:= Font;
DialogUnits:= MyGetAveCharSize(Canvas);
BorderStyle:= bsDialog;
Caption:= ACaption;
ClientWidth:= MulDiv(180, DialogUnits.X, 4);
Position:= poScreenCenter;
Color:= clBtnFace;
Prompt:= TLabel.Create(Form);
with Prompt do
begin
Parent:= Form;
Caption:= APrompt;
Left:= MulDiv(8, DialogUnits.X, 4);
Top:= MulDiv(8, DialogUnits.Y, 8);
Constraints.MaxWidth:= MulDiv(164, DialogUnits.X, 4);
WordWrap:= True;
end;
Edit:= TEdit.Create(Form);
with Edit do
begin
Parent:= Form;
Left:= Prompt.Left;
Top:= Prompt.Top + Prompt.Height + 5;
Width:= MulDiv(164, DialogUnits.X, 4);
MaxLength:= AMaxLength;
if APassword then
PasswordChar:= APasswordChar;
Text:= Value;
SelectAll;
end;
ButtonTop:= Edit.Top + Edit.Height + 15;
ButtonWidth:= MulDiv(50, DialogUnits.X, 4);
ButtonHeight:= MulDiv(14, DialogUnits.Y, 8);
with TButton.Create(Form) do
begin
Parent:= Form;
Caption:= ABtnsCaption[0];
ModalResult:= mrOk;
Cursor:= crHandPoint;
Default:= True;
SetBounds(MulDiv(38, DialogUnits.X, 4), ButtonTop, ButtonWidth, ButtonHeight);
end;
with TButton.Create(Form) do
begin
Parent:= Form;
Caption:= ABtnsCaption[1];
ModalResult:= mrCancel;
Cursor:= crHandPoint;
Cancel:= True;
SetBounds(MulDiv(92, DialogUnits.X, 4), Edit.Top + Edit.Height + 15, ButtonWidth, ButtonHeight);
Form.ClientHeight:= Top + Height + 13;
end;
if ShowModal = mrOk then
begin
Value:= Edit.Text;
if APassword then
if Value = ANeedPassword then
APasswordConfirmed:= true
else
APasswordConfirmed:= false;
Result:= True;
end;
finally
Form.Free;
end;
end;
function MyInputComboQuery(const ACaption, APrompt: String; const Values: TStringList; const DefIndex: IntEx; var SelectedIndex: IntEx; const ABtnsCaption: array of String): Boolean;
var Form: TForm;
Prompt: TLabel;
Combo: TComboBox;
DialogUnits: TPoint;
ButtonTop, ButtonWidth, ButtonHeight: IntEx;
begin
Result:= false;
Form:= TForm.Create(Application);
with Form do
try
Canvas.Font:= Font;
DialogUnits:= MyGetAveCharSize(Canvas);
BorderStyle:= bsDialog;
Caption:= ACaption;
ClientWidth:= MulDiv(180, DialogUnits.X, 4);
Position:= poScreenCenter;
Color:= clBtnFace;
Prompt:= TLabel.Create(Form);
with Prompt do
begin
Parent:= Form;
Caption:= APrompt;
Left:= MulDiv(8, DialogUnits.X, 4);
Top:= MulDiv(8, DialogUnits.Y, 8);
Constraints.MaxWidth:= MulDiv(164, DialogUnits.X, 4);
WordWrap:= True;
end;
Combo:= TComboBox.Create(Form);
with Combo do
begin
Parent:= Form;
Left:= Prompt.Left;
Top:= Prompt.Top + Prompt.Height + 5;
Width:= MulDiv(164, DialogUnits.X, 4);
Style:= csDropDownList;
Items.Assign(Values);
if DefIndex <= Items.Count - 1 then
ItemIndex:= DefIndex
else
ItemIndex:= -1;
end;
ButtonTop:= Combo.Top + Combo.Height + 15;
ButtonWidth:= MulDiv(50, DialogUnits.X, 4);
ButtonHeight:= MulDiv(14, DialogUnits.Y, 8);
with TButton.Create(Form) do
begin
Parent:= Form;
Caption:= ABtnsCaption[0];
ModalResult:= mrOk;
Cursor:= crHandPoint;
Default:= True;
SetBounds(MulDiv(38, DialogUnits.X, 4), ButtonTop, ButtonWidth, ButtonHeight);
end;
with TButton.Create(Form) do
begin
Parent:= Form;
Caption:= ABtnsCaption[1];
ModalResult:= mrCancel;
Cursor:= crHandPoint;
Cancel:= True;
SetBounds(MulDiv(92, DialogUnits.X, 4), Combo.Top + Combo.Height + 15, ButtonWidth, ButtonHeight);
Form.ClientHeight:= Top + Height + 13;
end;
if ShowModal = mrOk then
begin
SelectedIndex:= Combo.ItemIndex;
Result:= True;
end;
finally
Form.Free;
end;
end;
function MyInputMaskQuery(const ACaption, APrompt, AMask: String; var Value: String; const isIgnoreMask: Boolean; const AMaxLength: IntEx; const ABtnsCaption: array of String): Boolean;
var Form: TForm;
Prompt: TLabel;
Edit: TMaskEdit;
DialogUnits: TPoint;
ButtonTop, ButtonWidth, ButtonHeight: IntEx;
begin
Result:= false;
Form:= TForm.Create(Application);
with Form do
try
Canvas.Font:= Font;
DialogUnits:= MyGetAveCharSize(Canvas);
BorderStyle:= bsDialog;
Caption:= ACaption;
ClientWidth:= MulDiv(180, DialogUnits.X, 4);
Position:= poScreenCenter;
Color:= clBtnFace;
Prompt:= TLabel.Create(Form);
with Prompt do
begin
Parent:= Form;
Caption:= APrompt;
Left:= MulDiv(8, DialogUnits.X, 4);
Top:= MulDiv(8, DialogUnits.Y, 8);
Constraints.MaxWidth:= MulDiv(164, DialogUnits.X, 4);
WordWrap:= True;
end;
Edit:= TMaskEdit.Create(Form);
with Edit do
begin
Parent:= Form;
Left:= Prompt.Left;
Top:= Prompt.Top + Prompt.Height + 5;
Width:= MulDiv(164, DialogUnits.X, 4);
MaxLength:= AMaxLength;
EditMask:= AMask;
if isIgnoreMask then
Text:= Value
else
EditText:= Value;
ValidateEdit;
end;
ButtonTop:= Edit.Top + Edit.Height + 15;
ButtonWidth:= MulDiv(50, DialogUnits.X, 4);
ButtonHeight:= MulDiv(14, DialogUnits.Y, 8);
with TButton.Create(Form) do
begin
Parent:= Form;
Caption:= ABtnsCaption[0];
ModalResult:= mrOk;
Cursor:= crHandPoint;
Default:= True;
SetBounds(MulDiv(38, DialogUnits.X, 4), ButtonTop, ButtonWidth, ButtonHeight);
end;
with TButton.Create(Form) do
begin
Parent:= Form;
Caption:= ABtnsCaption[1];
ModalResult:= mrCancel;
Cursor:= crHandPoint;
Cancel:= True;
SetBounds(MulDiv(92, DialogUnits.X, 4), Edit.Top + Edit.Height + 15, ButtonWidth, ButtonHeight);
Form.ClientHeight:= Top + Height + 13;
end;
if ShowModal = mrOk then
begin
if isIgnoreMask then
Value:= Edit.Text
else
Value:= Edit.EditText;
Result:= True;
end;
finally
Form.Free;
end;
end;
function MyInputSpinQuery(const ACaption, APrompt: String; var _Value: IntEx; const AMinValue, AMaxValue: IntEx; const ABtnsCaption: array of String): Boolean;
var Form: TForm;
Prompt: TLabel;
Edit: TSpinEdit;
DialogUnits: TPoint;
ButtonTop, ButtonWidth, ButtonHeight: IntEx;
begin
Result:= False;
Form:= TForm.Create(Application);
with Form do
try
Canvas.Font:= Font;
DialogUnits:= MyGetAveCharSize(Canvas);
BorderStyle:= bsDialog;
Caption:= ACaption;
ClientWidth:= MulDiv(180, DialogUnits.X, 4);
Position:= poScreenCenter;
Color:= clBtnFace;
Prompt:= TLabel.Create(Form);
with Prompt do
begin
Parent:= Form;
Caption:= APrompt;
Left:= MulDiv(8, DialogUnits.X, 4);
Top:= MulDiv(8, DialogUnits.Y, 8);
Constraints.MaxWidth:= MulDiv(164, DialogUnits.X, 4);
WordWrap:= True;
end;
Edit:= TSpinEdit.Create(Form);
with Edit do
begin
Parent:= Form;
Left:= Prompt.Left;
Top:= Prompt.Top + Prompt.Height + 5;
Width:= MulDiv(164, DialogUnits.X, 4);
MinValue:= Integer(AMinValue);
MaxValue:= Integer(AMaxValue);
if _Value < AMinValue then
Value:= AMinValue
else
if _Value > AMaxValue then
Value:= AMaxValue
else
Value:= _Value;
SelectAll;
end;
ButtonTop:= Edit.Top + Edit.Height + 15;
ButtonWidth:= MulDiv(50, DialogUnits.X, 4);
ButtonHeight:= MulDiv(14, DialogUnits.Y, 8);
with TButton.Create(Form) do
begin
Parent:= Form;
Caption:= ABtnsCaption[0];
ModalResult:= mrOk;
Cursor:= crHandPoint;
Default:= True;
SetBounds(MulDiv(38, DialogUnits.X, 4), ButtonTop, ButtonWidth, ButtonHeight);
end;
with TButton.Create(Form) do
begin
Parent:= Form;
Caption:= ABtnsCaption[1];
ModalResult:= mrCancel;
Cursor:= crHandPoint;
Cancel:= True;
SetBounds(MulDiv(92, DialogUnits.X, 4), Edit.Top + Edit.Height + 15, ButtonWidth, ButtonHeight);
Form.ClientHeight:= Top + Height + 13;
end;
if ShowModal = mrOk then
begin
_Value:= Edit.Value;
Result:= True;
end;
finally
Form.Free;
end;
end;
function ShowInputBox (const ACaption, APrompt, ADefault: String; var isAccept: Boolean): String;
var Pasw: boolean;
begin
Result:= ADefault;
Pasw:= False;
isAccept:= MyInputQuery(ACaption, APrompt, Result, Pasw, False, '', '*', 0, [OkBtnDefCaption, CancelBtnDefCaption]);
end;
function ShowInputBox (const ACaption, APrompt, ADefault: String; const ABtnCaptions: array of String; var isAccept: Boolean): String;
var Pasw: boolean;
begin
Result:= ADefault;
Pasw:= False;
isAccept:= MyInputQuery(ACaption, APrompt, Result, Pasw, False, '', '*', 0, ABtnCaptions);
end;
function ShowInputBox (const ACaption, APrompt, ADefault: String; const ABtnCaptions: array of String; const AMaxLength: IntEx; var isAccept: Boolean): String;
var Pasw: boolean;
begin
Result:= ADefault;
Pasw:= False;
isAccept:= MyInputQuery(ACaption, APrompt, Result, Pasw, false, '', '*', AMaxLength, ABtnCaptions);
end;
function ShowPasswordInputBox (const ACaption, APrompt, ADefault, APassword: String; var isAccept, isPasswordConfirmed: Boolean; const APasswordChar: Char = '*'): String;
begin
Result:= ADefault;
isAccept:= MyInputQuery(ACaption, APrompt, Result, isPasswordConfirmed, True, APassword, APasswordChar, 0, [OkBtnDefCaption, CancelBtnDefCaption]);
end;
function ShowPasswordInputBox (const ACaption, APrompt, ADefault, APassword: String; var isAccept, isPasswordConfirmed: Boolean; const ABtnCaptions: array of String; const APasswordChar: Char = '*'): String;
begin
Result:= ADefault;
isAccept:= MyInputQuery(ACaption, APrompt, Result, isPasswordConfirmed, True, APassword, APasswordChar, 0, ABtnCaptions);
end;
function ShowComboBox (const ACaption, APrompt: string; var Items: TStringList; const ADefaultIndex: IntEx; var isAccept: boolean): IntEx;
begin
Result:= ADefaultIndex;
isAccept:= MyInputComboQuery(ACaption, APrompt, Items, Result, Result, [OkBtnDefCaption, CancelBtnDefCaption]);
end;
function ShowComboBox (const ACaption, APrompt: String; var Items: TStringList; const ADefaultIndex: IntEx; const ABtnsCaption: array of String; var isAccept: Boolean): IntEx;
begin
Result:= ADefaultIndex;
isAccept:= MyInputComboQuery(ACaption, APrompt, Items, Result, Result, ABtnsCaption);
end;
function ShowMaskedBox (const ACaption, APrompt, AMask, ADefault: String; const isIgnoreMask: Boolean; var isAccept: Boolean): String;
begin
Result:= ADefault;
isAccept:= MyInputMaskQuery(ACaption, APrompt, AMask, Result, isIgnoreMask, 0, [OkBtnDefCaption, CancelBtnDefCaption]);
end;
function ShowMaskedBox (const ACaption, APrompt, AMask, ADefault: String; const isIgnoreMask: Boolean; const ABtnCaptions: array of String; const AMaxLength: IntEx; var isAccept: Boolean): String;
begin
Result:= ADefault;
isAccept:= MyInputMaskQuery(ACaption, APrompt, AMask, Result, isIgnoreMask, AMaxLength, ABtnCaptions);
end;
function ShowSpinedBox (const ACaption, APrompt: String; const ADefault: IntEx; var isAccept: Boolean): IntEx;
begin
Result:= ADefault;
isAccept:= MyInputSpinQuery(ACaption, APrompt, Result, 0, 100, [OkBtnDefCaption, CancelBtnDefCaption]);
end;
function ShowSpinedBox (const ACaption, APrompt: String; const ADefault, AMinValue, AMaxValue: IntEx; const ABtnCaptions: array of String; var isAccept: Boolean): IntEx;
begin
Result:= ADefault;
isAccept:= MyInputSpinQuery(ACaption, APrompt, Result, AMinValue, AMaxValue, ABtnCaptions);
end;
end.

View File

@ -0,0 +1,12 @@
unit ANBRegComp;
{$mode delphi}
{$codepage UTF8}
interface
uses Classes, SysUtils, SkinButton;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('ANB Components', [TSkinBtn]);
end;
end.

View File

@ -0,0 +1,169 @@
//version 0.31 beta
unit FileUtilsEx;
{$MODE Delphi}
{$codepage UTF8}
interface
uses windows, sysutils, ShellApi, Classes;
type TExePlatform = (expUnknown, exp32Bit, exp64Bit, expOther);
//stdcalls
function FileVersion (AFileName: String): String;
function FileSize2Str (const AFileSize: Int64; AStringNames: Array of String; const ADecimalPlaces: Byte): String; Stdcall; Overload;
function FileSize2Str (const AFileSize: Int64; AStringNames: Array of String): String; Stdcall; Overload;
function FileSize2Str (const AFileSize: Int64; const ADecimalPlaces: Byte): String; Overload;
function FileSize2Str (const AFileSize: Int64): String; Overload;
function FileAccessDateToDateTime (FileTime: TFILETIME): TDateTime; Stdcall;
function RenameDir (const DirName, NewName: String): Boolean; STDCALL;
function GetEXEPlatform (const AFileName: String): TExePlatform; STDCALL;
implementation
const AFileSizeNames: Array[0..4] of String = ('Byte', 'KB', 'MB', 'GB', 'TB');
//Getting version of the file
function FileVersion (AFileName: String): String;
var szName: array[0..255] of Char;
P: Pointer;
Value: Pointer;
Len: UINT;
GetTranslationString: String;
FFileName: PChar;
FValid:boolean;
FSize: DWORD;
FHandle: DWORD;
FBuffer: PChar;
begin
try
FFileName:= StrPCopy(StrAlloc(Length(AFileName) + 1), AFileName);
FValid:= False;
FSize:= GetFileVersionInfoSize(FFileName, FHandle);
if FSize > 0 then
try
GetMem(FBuffer, FSize);
FValid:= GetFileVersionInfo(FFileName, FHandle, FSize, FBuffer);
except
FValid:= False;
raise;
end;
Result:= '';
if FValid then
VerQueryValue(FBuffer, '\VarFileInfo\Translation', P, Len)
else
P:= nil;
if P <> nil then
GetTranslationString:= IntToHex(MakeLong(HiWord(Longint(P^)), LoWord(Longint(P^))), 8);
if FValid then
begin
StrPCopy(szName, '\StringFileInfo\' + GetTranslationString + '\FileVersion');
if VerQueryValue(FBuffer, szName, Value, Len) then
Result:= StrPas(PChar(Value));
end;
finally
try
if FBuffer <> nil then
FreeMem(FBuffer, FSize);
except
end;
try
StrDispose(FFileName);
except
end;
end;
end;
//FileSize2Str
function FileSize2Str (const AFileSize: Int64; AStringNames: Array of String; const ADecimalPlaces: Byte): String; Overload;
function FrmtSize (const ASize, ADelim: Int64; const ADP: Byte): String;
var VDelim: Int64;
Indx: Byte;
begin
VDelim:= 1;
for Indx:= 0 to ADP do
VDelim:= VDelim*10;
Result:= FloatToStr(round((ASize*VDelim)/ADelim)/VDelim);
end;
const AFrmtsStr: String = '%s %s';
begin
//Bytes
if AFileSize < 1024 then
Result:= Format(AFrmtsStr, [IntToStr(AFileSize), AStringNames[0]]);
//KiloBytes
if (AFileSize >= 1024) and (AFileSize < 1048576) then
Result:= Format(AFrmtsStr, [FrmtSize(AFileSize, 1024, ADecimalPlaces), AStringNames[1]]);
//MegaBytes
if (AFileSize >= 1048576) and (AFileSize < 1073741824) then
Result:= Format(AFrmtsStr, [FrmtSize(AFileSize, 1048576, ADecimalPlaces), AStringNames[2]]);
//GigaBytes
if (AFileSize >= 1073741824) and (AFileSize < 1099511627776) then
Result:= Format(AFrmtsStr, [FrmtSize(AFileSize, 1073741824, ADecimalPlaces), AStringNames[3]]);
//TeraBytes
if (AFileSize >= 1099511627776) then
Result:= Format(AFrmtsStr, [FrmtSize(AFileSize, 1073741824, ADecimalPlaces), AStringNames[4]]);
end;
function FileSize2Str (const AFileSize: Int64; AStringNames: Array of String): String; Overload;
begin
Result:= FileSize2Str(AFileSize, AStringNames, 2);
end;
function FileSize2Str (const AFileSize: Int64; const ADecimalPlaces: Byte): String; Overload;
begin
Result:= FileSize2Str(AFileSize, AFileSizeNames, ADecimalPlaces);
end;
function FileSize2Str (const AFileSize: Int64): String; Overload;
begin
Result:= FileSize2Str(AFileSize, AFileSizeNames, 2);
end;
//FileAccessDateToDateTime
//Author: Дураг (http://www.sql.ru/forum/memberinfo.aspx?mid=32731) from http://www.sql.ru/forum/259218/kak-poluchit-datu-i-vremya-sozdaniya-fayla
function FileAccessDateToDateTime (FileTime: TFILETIME): TDateTime;
var LocalTime: TFILETIME;
DOSFileTime: DWORD;
begin
FileTimeToLocalFileTime(FileTime, LocalTime);
FileTimeToDosDateTime(LocalTime, LongRec(DOSFileTime).Hi, LongRec(DOSFileTime).Lo);
Result:= FileDateToDateTime(DOSFileTime);
end;
//RenameDir
function RenameDir (const DirName, NewName: String): Boolean;
var shellinfo: TSHFILEOPSTRUCT;
DirFrom, DirTo: String;
begin
DirFrom:= DirName;
DirTo:= NewName;
with shellinfo do
begin
Wnd:= 0;
wFunc:= FO_RENAME;
pFrom:= PChar(DirFrom);
pTo:= PChar(DirTo);
fFlags:= FOF_FILESONLY or FOF_ALLOWUNDO or FOF_SILENT or FOF_NOCONFIRMATION;
end;
SHFileOperation(shellinfo);
Result:= DirectoryExists(NewName);
end;
//GetEXEPlatform
//Author Dmitry Arefiev (http://www.sql.ru/forum/808857/kak-opredelit-razryadnost-prilozheniya)
function GetEXEPlatform (const AFileName: String): TExePlatform;
var oFS: TFileStream;
iPeOffset: Integer;
iPeHead: LongWord;
iMachineType: Word;
begin
Result:= expUnknown;
try
oFS:= TFileStream.Create(AFileName, fmOpenRead or fmShareDenyNone);
try
oFS.Seek($3C, soFromBeginning);
oFS.Read(iPeOffset, SizeOf(iPeOffset));
oFS.Seek(iPeOffset, soFromBeginning);
oFS.Read(iPeHead, SizeOf(iPeHead));
if iPeHead <> $00004550 then
Exit;
oFS.Read(iMachineType, SizeOf(iMachineType));
case iMachineType of
$8664, $0200: Result:= exp64Bit;
$014C: Result:= exp32Bit;
else
Result:= expOther;
end;
finally
oFS.Free;
end;
except
end;
end;
end.

View File

@ -0,0 +1,28 @@
unit GraphicsEx;
//version 0.1
{$MODE Delphi}
{$codepage UTF8}
interface
uses Classes, SysUtils, Graphics;
type TRGBByte = 0..255;
TRGBColor = record
R, G, B: TRGBByte;
end;
//stdcalls
function RGB2Color (const ARGB: TRGBColor): TColor;
function Color2RGB (const AColor: TColor): TRGBColor;
implementation
function RGB2Color (const ARGB: TRGBColor): TColor;
begin
Result:= RGBToColor(ARGB.R, ARGB.G, ARGB.B);
end;
function Color2RGB (const AColor: TColor): TRGBColor;
//from http://www.delphisources.ru/pages/faq/base/rgb_tcolor.html
var Color: LongInt;
begin
Color:= ColorToRGB(AColor);
Result.R:= Color;
Result.G:= Color shr 8;
Result.B:= Color shr 16;
end;
end.

View File

@ -0,0 +1,25 @@
unit MsgBoxes;
{$mode delphi}
{$codepage UTF8}
interface
uses Classes, SysUtils, Forms;
{dialog types for Linux capatability}
const DLG_ASTERISK = $40;
DLG_EXCLAMATION = $30;
DLG_WARNING = $30;
DLG_ERROR = $10;
DLG_QUESTION = $20;
{stdcalls}
function ShowMessageBox (const AText, ATitle: String; const AMessageType: LongInt = 0): Integer; STDCALL;
function ShowMessageBoxA (const AText: String; const AMessageType: LongInt = 0): Integer; STDCALL;
implementation
//Sample Windows MessageDialogs
function ShowMessageBox (const AText, ATitle: String; const AMessageType: LongInt = 0): Integer;
begin
Result:= Application.MessageBox(PChar(AText), PChar(ATitle), AMessageType);
end;
function ShowMessageBoxA (const AText: String; const AMessageType: LongInt = 0): Integer;
begin
Result:= Application.MessageBox(PChar(AText), PChar(Application.Title), AMessageType);
end;
end.

View File

@ -0,0 +1,96 @@
unit ParamsMngr;
{$MODE Delphi}
{$codepage UTF8}
interface
uses StrUtils, VCLEx;
{stdcalls}
function HasParam (const AParams: String; const AParam: Char): Boolean; OVERLOAD; STDCALL;
function HasParam (const AParams: String; const AParam: String): Boolean; OVERLOAD; STDCALL;
function HasParam (const AParam: String): Boolean; OVERLOAD; STDCALL;
function GetParamValue (const AParams: String; const AParam: Char): String; OVERLOAD; STDCALL;
function GetParamValue (const AParams: String; const AParam: String): String; OVERLOAD; STDCALL;
function GetParamValue (const AParam: string): string; overload; stdcall;
function StartParams: String; STDCALL;
implementation
function HasParam (const AParams: String; const AParam: Char): Boolean;
begin
Result:= False;
if AParams <> '' then
if Pos('/' + AParam, AParams) > 0 then
Result:= True;
end;
function HasParam (const AParams: String; const AParam: String): Boolean;
var PS: IntEx;
NextChr: Char;
begin
Result:= False;
if AParams <> '' then
begin
PS:= Pos('/' + AParam, AParams);
if PS > 0 then
begin
NextChr:= AParams[PS + Length(AParam) + 1];
if (NextChr = '=') or (NextChr = '#') then
Result:= True;
end;
end;
end;
function HasParam (const AParam: String): Boolean;
begin
Result:= HasParam(StartParams, AParam);
end;
function GetParamValue (const AParams: String; const AParam: Char): String;
var i, j, k: IntEx;
begin
Result:= '';
i:= 0;
j:= 0;
k:= 0;
if AParams <> '' then
begin
i:= Pos('/' + AParam, AParams);
if (i > 0) and (AParams[i+2] = '=') then
j:= i+3;
if j > 0 then
begin
k:= PosEx('#', AParams, j);
if k = 0 then
k:= Length(AParams) + 1;
Result:= Copy(AParams, j, k-j);
end;
end;
end;
function GetParamValue (const AParams: String; const AParam: String): String;
var i, j, k: IntEx;
begin
Result:= '';
i:= 0;
j:= 0;
k:= 0;
if AParams <> '' then
begin
i:= Pos('/' + AParam, AParams);
if (i > 0) and (AParams[i + Length(AParam) + 1] = '=') then
j:= i + Length(AParam) + 2;
if j > 0 then
begin
k:= PosEx('#', AParams, j);
if k = 0 then
k:= Length(AParams) + 1;
Result:= Copy(AParams, j, k-j);
end;
end;
end;
function GetParamValue (const AParam: String): String;
begin
Result:= GetParamValue(StartParams, AParam);
end;
function StartParams: String;
var i: IntEx;
begin
Result:= '';
if Paramcount > 0 then
for i:= 1 to Paramcount do
Result:= Result + ParamStr(i) + '#';
end;
end.

View File

@ -0,0 +1,132 @@
unit SimplyINI;
{$MODE Delphi}
{$codepage UTF8}
interface
uses SysUtils, Classes, IniFiles;
//stdcalls
function INIReadString (const ASection, AKey, ADefault, AFileName: string): string; stdcall;
function INIReadInteger (const ASection, AKey: string; const ADefault: Int64; const AFileName: string): Int64; stdcall;
function INIReadBoolean (const ASection, AKey: string; const ADefault: boolean; const AFileName: string): boolean; stdcall;
procedure INIWriteString (const ASection, AKey, AValue, AFileName: string); stdcall;
procedure INIWriteInteger (const ASection, AKey: string; const AValue: Int64; const AFileName: string); stdcall;
procedure INIWriteBoolean (const ASection, AKey: string; const AValue: boolean; const AFileName: string); stdcall;
procedure INIDeleteKey (const ASection, AKey, AFileName: string); stdcall;
procedure INIDeleteSection (const ASection, AFileName: string); stdcall;
function INISectionExists (const ASection, AFileName: string): boolean; stdcall;
procedure INIReadSections (const AFileName: string; VStrings: TStrings); stdcall;
procedure INIReadSection (const ASection, AFileName: string; VStrings: TStrings); stdcall;
implementation
//Read functions
function INIReadString (const ASection, AKey, ADefault, AFileName: string): string;
var INI: TIniFile;
begin
INI:= TIniFile.Create(AFileName);
try
Result:= INI.ReadString(ASection, AKey, ADefault);
finally
INI.Free;
end;
end;
function INIReadInteger (const ASection, AKey: string; const ADefault: Int64; const AFileName: string): Int64;
var INI: TIniFile;
begin
INI:= TIniFile.Create(AFileName);
try
Result:= INI.ReadInteger(ASection, AKey, ADefault);
finally
INI.Free;
end;
end;
function INIReadBoolean (const ASection, AKey: string; const ADefault: boolean; const AFileName: string): boolean;
var INI: TIniFile;
begin
INI:= TIniFile.Create(AFileName);
try
Result:= INI.ReadBool(ASection, AKey, ADefault);
finally
INI.Free;
end;
end;
//Write procedures
procedure INIWriteString (const ASection, AKey, AValue, AFileName: string);
var INI: TIniFile;
begin
INI:= TIniFile.Create(AFileName);
try
INI.WriteString(ASection, AKey, AValue);
finally
INI.Free;
end;
end;
procedure INIWriteInteger (const ASection, AKey: string; const AValue: Int64; const AFileName: string);
var INI: TIniFile;
begin
INI:= TIniFile.Create(AFileName);
try
INI.WriteInt64(ASection, AKey, AValue);
finally
INI.Free;
end;
end;
procedure INIWriteBoolean (const ASection, AKey: string; const AValue: boolean; const AFileName: string);
var INI: TIniFile;
begin
INI:= TIniFile.Create(AFileName);
try
INI.WriteBool(ASection, AKey, AValue);
finally
INI.Free;
end;
end;
//Delete function
procedure INIDeleteKey (const ASection, AKey, AFileName: string);
var INI: TIniFile;
begin
INI:= TIniFile.Create(AFileName);
try
INI.DeleteKey(ASection, AKey);
finally
INI.Free;
end;
end;
procedure INIDeleteSection (const ASection, AFileName: string);
var INI: TIniFile;
begin
INI:= TIniFile.Create(AFileName);
try
INI.EraseSection(ASection);
finally
INI.Free;
end;
end;
function INISectionExists (const ASection, AFileName: string): boolean;
var INI: TIniFile;
begin
INI:= TIniFile.Create(AFileName);
try
Result:= INI.SectionExists(ASection);
finally
INI.Free;
end;
end;
procedure INIReadSections (const AFileName: string; VStrings: TStrings);
var INI: TIniFile;
begin
INI:= TIniFile.Create(AFileName);
try
INI.ReadSections(VStrings);
finally
INI.Free;
end;
end;
procedure INIReadSection (const ASection, AFileName: string; VStrings: TStrings);
var INI: TIniFile;
begin
INI:= TIniFile.Create(AFileName);
try
INI.ReadSection(ASection, VStrings);
finally
INI.Free;
end;
end;
end.

View File

@ -0,0 +1,325 @@
unit SimplyJSON;
{$MODE Delphi}
{$codepage UTF8}
{*************************************************************************************************************************************
SimplyJSON
Модуль для парсинга JSON файлов (используется TJSONConfig).
Авторские права (c) 2016 - 2019, Александр Бабаев.
История изменений:
1.3 (01.05.2019) Переработан алгоритм открытия / парсинга JSON файлов при чтении, изменена функция JSReadFont
1.2 (09.05.2017) Добавлены функции чтения/записи шрифтов.
*************************************************************************************************************************************}
interface
uses Classes, SysUtils, Graphics, GraphicsEx, LazUTF8Classes, LazFileUtils, fpjson, jsonparser, jsonConf,
ANBFormatString;
//stdcalls
function JSReadString (const AKey, ADefault: UnicodeString; const AFileName: String): UnicodeString; STDCALL; OVERLOAD;
function JSReadString (const AKey, ADefault, AFileName: String): String; STDCALL; OVERLOAD;
function JSReadInteger (const AKey: UnicodeString; const ADefault: Int64; const AFileName: String): Int64; STDCALL; OVERLOAD;
function JSReadInteger (const AKey: String; const ADefault: Int64; const AFileName: String): Int64; STDCALL; OVERLOAD;
function JSReadBoolean (const AKey: UnicodeString; const ADefault: Boolean; const AFileName: String): Boolean; STDCALL; OVERLOAD;
function JSReadBoolean (const AKey: String; const ADefault: Boolean; const AFileName: String): Boolean; STDCALL; OVERLOAD;
function JSReadRGBColor (const AKey: UnicodeString; const ADefault: TRGBColor; const AFileName: String): TRGBColor; STDCALL; OVERLOAD;
function JSReadRGBColor (const AKey: String; const ADefault: TRGBColor; const AFileName: String): TRGBColor; STDCALL; OVERLOAD;
procedure JSReadFont (const AKey: UnicodeString; var Font: TFont; const AFileName: String); STDCALL; OVERLOAD;
procedure JSReadFont (const AKey: String; var Font: TFont; const AFileName: String); STDCALL; OVERLOAD;
procedure JSWriteString (const AKey, AValue: UnicodeString; const AFileName: String); STDCALL; OVERLOAD;
procedure JSWriteString (const AKey, AValue, AFileName: String); STDCALL; OVERLOAD;
procedure JSWriteInteger (const AKey: UnicodeString; const AValue: Int64; const AFileName: String); STDCALL; OVERLOAD;
procedure JSWriteInteger (const AKey: String; const AValue: Int64; const AFileName: String); STDCALL; OVERLOAD;
procedure JSWriteBoolean (const AKey: UnicodeString; const AValue: Boolean; const AFileName: String); STDCALL; OVERLOAD;
procedure JSWriteBoolean (const AKey: String; const AValue: Boolean; const AFileName: String); STDCALL; OVERLOAD;
procedure JSWriteRGBColor (const AKey: UnicodeString; const AValue: TRGBColor; const AFileName: String); STDCALL; OVERLOAD;
procedure JSWriteRGBColor (const AKey: String; const AValue: TRGBColor; const AFileName: String); STDCALL; OVERLOAD;
procedure JSWriteFont (const AKey: UnicodeString; const AValue: TFont; const AFileName: String); STDCALL; OVERLOAD;
procedure JSWriteFont (const AKey: String; const AValue: TFont; const AFileName: String); STDCALL; OVERLOAD;
procedure JSDeleteKey (const AKey: UnicodeString; const AFileName: String); STDCALL; OVERLOAD;
procedure JSDeleteKey (const AKey, AFileName: String); STDCALL; OVERLOAD;
procedure JSReadSubKeys (const AKey: UnicodeString; SubkeyList: TStrings; const AFileName: String); STDCALL; OVERLOAD;
procedure JSReadSubKeys (const AKey: String; SubkeyList: TStrings; const AFileName: String); STDCALL; OVERLOAD;
implementation
//Support functions
procedure GetJSData (const AFileName: String; var JSData: TJSONData);
var FS: TFileStreamUTF8;
SL: TStringListUTF8;
begin
if not FileExistsUTF8(AFileName) then
begin
FS:= TFileStreamUTF8.Create(AFileName, fmOpenWrite);
SL:= TStringListUTF8.Create;
SL.Text:= '{}';
SL.SaveToStream(FS);
SL.Free;
FS.Free;
end;
FS:= TFileStreamUTF8.Create(AFileName, fmOpenRead or fmShareDenyNone);
JSData:= GetJSON(FS, True);
FS.Free;
end;
function FrmtKey (const AKey: UnicodeString): UnicodeString;
var KeyM: UnicodeString;
begin
Result:= AKey;
//Для совместимости с SimplyJSON 1.0 - 1.2 и операциями записи
KeyM:= AKey;
if KeyM[1] = '/' then
Delete(KeyM, 1, 1);
Result:= UnicodeString(FormatStr(KeyM, ['/'], ['.']));
end;
//Read functions
function JSReadString (const AKey, ADefault: UnicodeString; const AFileName: String): UnicodeString; OVERLOAD;
var JD: TJSONData;
begin
GetJSData(AFileName, JD);
try
Result:= JD.FindPath(FrmtKey(AKey)).AsUnicodeString;
except
Result:= ADefault;
end;
JD.Free;
end;
function JSReadString (const AKey, ADefault, AFileName: String): String; OVERLOAD;
var Key, Def, Res: UnicodeString;
begin
Key:= UnicodeString(AKey);
Def:= UnicodeString(ADefault);
Res:= JSReadString(Key, Def, AFileName);
Result:= String(Res);
end;
function JSReadInteger (const AKey: UnicodeString; const ADefault: Int64; const AFileName: String): Int64; OVERLOAD;
var JD: TJSONData;
begin
GetJSData(AFileName, JD);
try
Result:= JD.FindPath(FrmtKey(AKey)).AsInt64;
except
Result:= ADefault;
end;
JD.Free;
end;
function JSReadInteger (const AKey: String; const ADefault: Int64; const AFileName: String): Int64; OVERLOAD;
var Key: UnicodeString;
begin
Key:= UnicodeString(AKey);
Result:= JSReadInteger(Key, ADefault, AFileName);
end;
function JSReadBoolean (const AKey: UnicodeString; const ADefault: Boolean; const AFileName: String): Boolean; OVERLOAD;
var JD: TJSONData;
begin
GetJSData(AFileName, JD);
try
Result:= JD.FindPath(FrmtKey(AKey)).AsBoolean;
except
Result:= ADefault;
end;
JD.Free;
end;
function JSReadBoolean (const AKey: String; const ADefault: Boolean; const AFileName: String): Boolean; OVERLOAD;
var Key: UnicodeString;
begin
Key:= UnicodeString(AKey);
Result:= JSReadBoolean(Key, ADefault, AFileName);
end;
function JSReadRGBColor (const AKey: UnicodeString; const ADefault: TRGBColor; const AFileName: String): TRGBColor; OVERLOAD;
var JD: TJSONData;
KeyM: UnicodeString;
begin
GetJSData(AFileName, JD);
KeyM:= FrmtKey(AKey);
try
Result.R:= JD.FindPath(KeyM + '.r').AsInteger;
Result.G:= JD.FindPath(KeyM + '.g').AsInteger;
Result.B:= JD.FindPath(KeyM + '.b').AsInteger;
except
Result:= ADefault;
end;
JD.Free;
end;
function JSReadRGBColor (const AKey: String; const ADefault: TRGBColor; const AFileName: String): TRGBColor; OVERLOAD;
var Key: UnicodeString;
begin
Key:= UnicodeString(AKey);
Result:= JSReadRGBColor(Key, ADefault, AFileName);
end;
procedure JSReadFont (const AKey: UnicodeString; var Font: TFont; const AFileName: String);
var JD: TJSONData;
FStyle: TFontStyles;
KeyM: UnicodeString;
begin
GetJSData(AFileName, JD);
KeyM:= FrmtKey(AKey);
try
Font.CharSet:= TFontCharSet(JD.FindPath(KeyM + '.charset').AsInteger);
Font.Color:= StringToColor(JD.FindPath(KeyM + '.color').AsString);
Font.Height:= JD.FindPath(KeyM + '.height').AsInteger;
Font.Name:= JD.FindPath(KeyM + '.name').AsString;
Font.Orientation:= JD.FindPath(KeyM + '.orientation').AsInteger;
Font.Pitch:= TFontPitch(JD.FindPath(KeyM + '.pitch').AsInteger);
Font.Quality:= TFontQuality(JD.FindPath(KeyM + '.quality').AsInteger);
Font.Size:= JD.FindPath(KeyM + '.size').AsInteger;
FStyle:= [];
if (JD.FindPath(KeyM + '.style.bold').AsBoolean) then
FStyle:= FStyle + [fsBold];
if (JD.FindPath(KeyM + '.style.italic').AsBoolean) then
FStyle:= FStyle + [fsItalic];
if (JD.FindPath(KeyM + '.style.underline').AsBoolean) then
FStyle:= FStyle + [fsUnderline];
if (JD.FindPath(KeyM + '.style.strikeout').AsBoolean) then
FStyle:= FStyle + [fsStrikeOut];
Font.Style:= FStyle;
except
end;
JD.Free;
end;
procedure JSReadFont (const AKey: String; var Font: TFont; const AFileName: String);
var Key: UnicodeString;
begin
Key:= UnicodeString(AKey);
JSReadFont(Key, Font, AFileName);
end;
//Write procedures
procedure JSWriteString (const AKey, AValue: UnicodeString; const AFileName: String); OVERLOAD;
var JSConf: TJSONConfig;
begin
JSConf:= TJSONConfig.Create(Nil);
with JSConf do
begin
Filename:= AFileName;
Formatted:= True;
SetValue(AKey, AValue);
Flush;
Free;
end;
end;
procedure JSWriteString (const AKey, AValue, AFileName: String); OVERLOAD;
var Key, Val: UnicodeString;
begin
Key:= UnicodeString(AKey);
Val:= UnicodeString(AValue);
JSWriteString(Key, Val, AFileName);
end;
procedure JSWriteInteger (const AKey: UnicodeString; const AValue: Int64; const AFileName: String); OVERLOAD;
var JSConf: TJSONConfig;
begin
JSConf:= TJSONConfig.Create(Nil);
with JSConf do
begin
Filename:= AFileName;
Formatted:= True;
SetValue(AKey, AValue);
Free;
end;
end;
procedure JSWriteInteger (const AKey: String; const AValue: Int64; const AFileName: String); OVERLOAD;
var Key: UnicodeString;
begin
Key:= UnicodeString(AKey);
JSWriteInteger(Key, AValue, AFileName);
end;
procedure JSWriteBoolean (const AKey: UnicodeString; const AValue: Boolean; const AFileName: String); OVERLOAD;
var JSConf: TJSONConfig;
begin
JSConf:= TJSONConfig.Create(Nil);
with JSConf do
begin
Filename:= AFileName;
Formatted:= True;
SetValue(AKey, AValue);
Free;
end;
end;
procedure JSWriteBoolean (const AKey: String; const AValue: Boolean; const AFileName: String); OVERLOAD;
var Key: UnicodeString;
begin
Key:= UnicodeString(AKey);
JSWriteBoolean(Key, AValue, AFileName);
end;
procedure JSWriteRGBColor (const AKey: UnicodeString; const AValue: TRGBColor; const AFileName: String); OVERLOAD;
var JSConf: TJSONConfig;
begin
JSConf:= TJSONConfig.Create(Nil);
with JSConf do
begin
Filename:= AFileName;
Formatted:= True;
SetValue(AKey + '/r', AValue.R);
SetValue(AKey + '/g', AValue.G);
SetValue(AKey + '/b', AValue.B);
Free;
end;
end;
procedure JSWriteRGBColor (const AKey: String; const AValue: TRGBColor; const AFileName: String); OVERLOAD;
var Key: UnicodeString;
begin
Key:= UnicodeString(AKey);
JSWriteRGBColor(Key, AValue, AFileName);
end;
procedure JSWriteFont (const AKey: UnicodeString; const AValue: TFont; const AFileName: String); OVERLOAD;
var JSConf: TJSONConfig;
begin
JSConf:= TJSONConfig.Create(Nil);
with JSConf do
begin
Filename:= AFileName;
Formatted:= True;
SetValue(AKey + '/charset', Integer(AValue.CharSet));
SetValue(AKey + '/color', ColorToString(AValue.Color));
SetValue(AKey + '/height', AValue.Height);
SetValue(AKey + '/name', AValue.Name);
SetValue(AKey + '/orientation', AValue.Orientation);
SetValue(AKey + '/pitch', Integer(AValue.Pitch));
SetValue(AKey + '/quality', Integer(AValue.Quality));
SetValue(AKey + '/size', AValue.Size);
SetValue(AKey + '/style/bold', (fsBold in AValue.Style));
SetValue(AKey + '/style/italic', (fsItalic in AValue.Style));
SetValue(AKey + '/style/underline', (fsUnderline in AValue.Style));
SetValue(AKey + '/style/strikeout', (fsStrikeOut in AValue.Style));
Free;
end;
end;
procedure JSWriteFont (const AKey: String; const AValue: TFont; const AFileName: String); OVERLOAD;
var Key: UnicodeString;
begin
Key:= UnicodeString(AKey);
JSWriteFont(Key, AValue, AFileName);
end;
//Delete function
procedure JSDeleteKey (const AKey: UnicodeString; const AFileName: String); OVERLOAD;
var JSConf: TJSONConfig;
begin
JSConf:= TJSONConfig.Create(Nil);
with JSConf do
begin
Filename:= AFileName;
Formatted:= True;
DeletePath(AKey);
Free;
end;
end;
procedure JSDeleteKey (const AKey, AFileName: String); OVERLOAD;
var Key: UnicodeString;
begin
Key:= UnicodeString(AKey);
JSDeleteKey(Key, AFileName);
end;
//Read subkeys
procedure JSReadSubKeys (const AKey: UnicodeString; SubkeyList: TStrings; const AFileName: String); OVERLOAD;
var JSConf: TJSONConfig;
begin
JSConf:= TJSONConfig.Create(Nil);
with JSConf do
begin
Filename:= AFileName;
Formatted:= True;
SubkeyList.Clear;
EnumSubKeys(AKey, SubkeyList);
Free;
end;
end;
procedure JSReadSubKeys (const AKey: String; SubkeyList: TStrings; const AFileName: String); OVERLOAD;
var Key: UnicodeString;
begin
Key:= UnicodeString(AKey);
JSReadSubKeys(Key, SubkeyList, AFileName);
end;
end.

View File

@ -0,0 +1,61 @@
unit SkinButton;
{$mode delphi}
{$codepage UTF8}
interface
uses Classes, SysUtils, Buttons, Graphics, Controls;
type TSkinBtn = class(TSpeedButton)
private
FNormalColor, FHighlightColor, FClickColor: TColor;
FTransparent: Boolean;
FOnMouseDown: TMouseEvent;
FOnMouseEnter, FOnMouseLeave: TNotifyEvent;
protected
procedure POnMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
procedure POnMouseEnter(Sender: TObject);
procedure POnMouseLeave(Sender: TObject);
public
constructor Create(AOwner: TComponent);
destructor Destroy;
published
property Transparent: Boolean read FTransparent;
property NormalColor: TColor read FNormalColor write FNormalColor;
property OnHighlightColor: TColor read FHighlightColor write FHighlightColor;
property OnClickColor: TColor read FClickColor write FClickColor;
property OnMouseDown: TMouseEvent read FOnMouseDown;
property OnMouseEnter: TNotifyEvent read FOnMouseEnter;
property OnMouseLeave: TNotifyEvent read FOnMouseLeave;
end;
implementation
constructor TSkinBtn.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FNormalColor:= clWhite;
FHighlightColor:= FNormalColor;
FClickColor:= FNormalColor;
FTransparent:= False;
inherited Transparent:= FTransparent;
inherited OnMouseEnter:= POnMouseEnter;
inherited OnMouseDown:= POnMouseDown;
inherited OnMouseLeave:= POnMouseLeave;
end;
destructor TSkinBtn.Destroy;
begin
inherited Destroy;
end;
procedure TSkinBtn.POnMouseEnter(Sender: TObject);
begin
(Sender as TSkinBtn).Color:= FHighlightColor;
inherited OnMouseEnter(Sender);
end;
procedure TSkinBtn.POnMouseLeave(Sender: TObject);
begin
(Sender as TSkinBtn).Color:= FNormalColor;
inherited OnMouseLeave(Sender);
end;
procedure TSkinBtn.POnMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then
(Sender as TSkinBtn).Color:= FClickColor;
inherited OnMouseDown(Sender, Button, Shift, X, Y);
end;
end.

View File

@ -0,0 +1,249 @@
unit VCLEx;
{$MODE Delphi}
{$codepage UTF8}
interface
uses ShellApi, windows, sysutils, strutils, LazFileUtils, LazUTF8;
type IntEx = {$IFDEF Win64}Int64{$ELSE}Integer{$ENDIF};
TWaitEvent = procedure;
TOSPlatform = (ospUnknown, ospWin32, ospWin64);
TPrivilegeState = (psError, psLimitedUser, psAdmin);
Percent = 0..100;
TRandomRange = (rrUpperCasesLetters, rrLowerCasesLetters, rrNumbers, rrStandartSymbols);
TRandomRanges = set of TRandomRange;
//stdcalls
function IntToBool (const AInt: IntEx): Boolean; STDCALL;
function BoolToInt (const ABool: Boolean): IntEx; STDCALL;
function CopyDirectory (const AFromDir, AToDir: String; const AFlags: Word = FOF_FILESONLY): Boolean; STDCALL;
function MoveDirectory (const AFromDir, AToDir: String; const AFlags: Word = FOF_FILESONLY): Boolean; STDCALL;
function DelDirectory (const ADir: String; const AFlags: Word = FOF_SILENT or FOF_NOCONFIRMATION): Boolean; STDCALL;
procedure WaitEx (const AMs: Int64; OnWait: TWaitEvent); STDCALL;
procedure Wait (const AMs: Int64); STDCALL;
function GetBuildPlatform: TOSPlatform; STDCALL;
function GetWindowsUserPrivilege: TPrivilegeState; STDCALL;
function ExtractUpDir(const ADir: String; var VSuccess: Boolean): String; STDCALL;
function GetAnyFileType (const AFileName: UTF8String): UTF8String; STDCALL;
function FileSizeToStr (const AFS: Int64; const AScaleCaptions: array of String): String; OVERLOAD; STDCALL;
function FileSizeToStr (const AFS: Int64): String; OVERLOAD; STDCALL;
function GetRandomString (const sLength: Integer; const ARange: TRandomRanges = [rrUpperCasesLetters, rrLowerCasesLetters]; const AIncludedSymbols: String = ''; const AExcludedSymbols: String = ''): String; STDCALL;
implementation
function IntToBool (const AInt: IntEx): Boolean;
begin
if AInt >= 0 then
Result:= True
else
Result:= False;
end;
function BoolToInt (const ABool: Boolean): IntEx;
begin
if ABool then
Result:= 1
else
Result:= -1;
end;
//from http://www.delphiworld.narod.ru/base/copy_del_move_dir.html
function CopyDirectory (const AFromDir, AToDir: String; const AFlags: Word = FOF_FILESONLY): Boolean;
var fos: TSHFileOpStruct;
begin
with fos do
begin
wFunc:= FO_COPY;
fFlags:= AFlags;
pFrom:= PChar(AFromDir + #0);
pTo:= PChar(AToDir);
end;
Result:= (0 = SHFileOperation(fos));
end;
function MoveDirectory (const AFromDir, AToDir: String; const AFlags: Word = FOF_FILESONLY): Boolean;
var fos: TSHFileOpStruct;
begin
with fos do
begin
wFunc:= FO_MOVE;
fFlags:= AFlags;
pFrom:= PChar(AFromDir + #0);
pTo:= PChar(AToDir);
end;
Result:= (0 = SHFileOperation(fos));
end;
function DelDirectory (const ADir: String; const AFlags: Word = FOF_SILENT or FOF_NOCONFIRMATION): Boolean;
var
fos: TSHFileOpStruct;
begin
with fos do
begin
wFunc:= FO_DELETE;
fFlags:= AFlags;
pFrom:= PChar(ADir + #0);
end;
Result:= (0 = SHFileOperation(fos));
end;
//---
procedure WaitEx (const AMs: Int64; OnWait: TWaitEvent);
var STime: Int64;
begin
STime:= GetTickCount64;
repeat
OnWait;
until (GetTickCount64 - STime) = AMs;
end;
procedure Wait (const AMs: Int64);
procedure MyWait;
begin
end;
begin
WaitEx(AMs, @MyWait);
end;
//GetBuildPlatform
function GetBuildPlatform: TOSPlatform;
begin
Result:= ospUnknown;
if LowerCase({$I %FPCTARGETOS%}) = 'win32' then
Result:= ospWin32;
if LowerCase({$I %FPCTARGETOS%}) = 'win64' then
Result:= ospWin64;
end;
//GetWindowsUserPrivilege
function GetWindowsUserPrivilege: TPrivilegeState;
const SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5));
SECURITY_BUILTIN_DOMAIN_RID = $00000020;
DOMAIN_ALIAS_RID_ADMINS = $00000220;
SECURITY_MANDATORY_HIGH_RID = $00003000;
TokenIntegrityLevel = 25;
var hAccessToken: THandle;
ptgGroups: PTokenGroups;
dwInfoBufferSize: DWORD;
psidAdministrators: PSID;
I: Integer;
SubAuthority: DWORD;
begin
Result:= psError;
if Win32Platform <> VER_PLATFORM_WIN32_NT then
Exit;
if not OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True, hAccessToken) then
if not OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, hAccessToken) then
Exit;
try
GetMem(ptgGroups, 1024);
try
if Win32MajorVersion < 6 then
begin
if not GetTokenInformation(hAccessToken, TokenGroups, ptgGroups, 1024, dwInfoBufferSize) then
Exit;
AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, psidAdministrators);
try
Result:= psLimitedUser;
for I:= 0 to ptgGroups.GroupCount - 1 do
if EqualSid(psidAdministrators, ptgGroups.Groups[I].Sid) then
begin
Result:= psAdmin;
Break;
end;
finally
FreeSid(psidAdministrators);
end;
end
else
begin
if GetTokenInformation(hAccessToken, TTokenInformationClass(TokenIntegrityLevel), ptgGroups, 1024, dwInfoBufferSize) and IsValidSid(PSIDAndAttributes(ptgGroups)^.Sid) then
begin
Result:= psLimitedUser;
SubAuthority:= GetSidSubAuthorityCount(PSIDAndAttributes(ptgGroups)^.Sid)^ - 1;
if GetSidSubAuthority(PSIDAndAttributes(ptgGroups)^.Sid, SubAuthority)^ >= SECURITY_MANDATORY_HIGH_RID then
Result:= psAdmin;
end;
end;
finally
FreeMem(ptgGroups);
end;
finally
CloseHandle(hAccessToken);
end;
end;
function ExtractUpDir (const ADir: String; var VSuccess: Boolean): String;
var CurrDelim, NextDelim: Integer;
s, Str: String;
begin
Str:= ExcludeTrailingBackslash(ADir);
if Length(ADir) < 4 then
begin
VSuccess:= false;
Result:= ADir;
Exit;
end;
s:= '';
CurrDelim:= 1;
repeat
NextDelim:= PosEx('\', Str, CurrDelim);
if NextDelim = 0 then
NextDelim:= Length(Str) + 1;
if NextDelim < Length(Str) then
s:= s + Copy(Str, CurrDelim, NextDelim - CurrDelim) + '\';
CurrDelim:= NextDelim + 1;
until (CurrDelim > Length(Str));
VSuccess:= DirectoryExistsUTF8(s);
Result:= s;
end;
function GetAnyFileType (const AFileName: UTF8String): UTF8String;
var FileInfo: TSHFILEINFO;
begin
Result:= '';
FillChar(FileInfo, SizeOf(FileInfo), 0);
if (SHGetFileInfo(PChar(ExtractFileExt(AFileName)), FILE_ATTRIBUTE_NORMAL, FileInfo, SizeOf(FileInfo), SHGFI_TYPENAME or SHGFI_USEFILEATTRIBUTES) <> 0) then
Result:= AnsiToUtf8(FileInfo.szTypeName);
end;
function FileSizeToStr (const AFS: Int64; const AScaleCaptions: array of String): String;
var ARSize: Real;
begin
if AFS < 1024 then
begin
Result:= Format('%d ' + AScaleCaptions[0], [AFS]);
Exit;
end;
if AFS < 1048576 then
begin
ARSize:= Round((AFS / 1024)*100)/100;
Result:= FloatToStr(ARSize) + ' ' + AScaleCaptions[1];
Exit;
end;
if AFS < 1073741824 then
begin
ARSize:= Round((AFS / 1048576)*100)/100;
Result:= FloatToStr(ARSize) + ' ' + AScaleCaptions[2];
Exit;
end;
ARSize:= Round((AFS / 1073741824)*100)/100;
Result:= FloatToStr(ARSize) + ' ' + AScaleCaptions[3];
end;
function FileSizeToStr (const AFS: Int64): String;
begin
Result:= FileSizeToStr(AFS, ['Byte', 'KB', 'MB', 'GB']);
end;
function GetRandomString (const sLength: Integer; const ARange: TRandomRanges = [rrUpperCasesLetters, rrLowerCasesLetters]; const AIncludedSymbols: String = ''; const AExcludedSymbols: String = ''): String;
const UpperCaseChars = 'ABCDEFGHIKLMNOPQRSTUVWXYZ';
LowerCaseChars = 'abcdefghiklmnopqrstuvwxyz';
NumbersChars = '0123456789';
SymbolsChars = '!"#$%&''()*+,-.:;<=>?@\]^_`{|}~';
var i, j: Integer;
Chars: String;
begin
SetLength (Result, sLength);
Chars:= AIncludedSymbols;
if rrUpperCasesLetters in ARange then
Chars:= Chars + UpperCaseChars;
if rrLowerCasesLetters in ARange then
Chars:= Chars + LowerCaseChars;
if rrNumbers in ARange then
Chars:= Chars + NumbersChars;
if rrStandartSymbols in ARange then
Chars:= Chars + SymbolsChars;
if Length(AExcludedSymbols) > 0 then
for i:= 1 to Length(AExcludedSymbols) do
begin
j:= Pos(AExcludedSymbols[i], Chars);
if j > 0 then
Delete(Chars, j, 1);
end;
for i:= 1 to sLength do
Result[i]:= Chars[Random(Length(Chars))+1];
end;
end.

View File

@ -0,0 +1,145 @@
unit VersionControl;
{$MODE Delphi}
{$codepage UTF8}
interface
uses LCLIntf, LCLType, LMessages, SysUtils, StrUtils, Forms, Classes,
{$IFDEF WINDOWS}PJVersionInfo{$ENDIF};
type TSmallVersionInfo = record
sviMajor, sviMinor: int64;
end;
type TVersionInfo = record
viMajor, viMinor, viRelease, viBuild: integer;
end;
function SmallVersionInfoToStr (const Value: TSmallVersionInfo): string; stdcall;
function VersionInfoToStr (const Value: TVersionInfo): string; stdcall;
function VersionInfoToSmallVersionInfo (const Value: TVersionInfo): TSmallVersionInfo; stdcall;
function SmallVersionInfoToVersionInfo (const Value: TSmallVersionInfo; const ANilValue: integer = 0): TVersionInfo; stdcall;
function StrToVersionInfo (const AString: string): TVersionInfo; stdcall;
function StrToSmallVersionInfo (const AString: string): TSmallVersionInfo; stdcall;
function CompareVersionInfo (const AVersionInfo1, AVersionInfo2: TVersionInfo): integer; stdcall;
function CompareSmallVersionInfo (const ASmallVersionInfo1, ASmallVersionInfo2: TSmallVersionInfo): integer; stdcall;
{$IFDEF WINDOWS}function GetApplicationVersionInfoStr (const AFileName, AVersionSTR: string): string; STDCALL;{$ENDIF}
const NilVersionInfo: TVersionInfo = (viMajor: 0; viMinor: 0; viRelease: 0; viBuild: 0);
NilSmallVersionInfo: TSmallVersionInfo = (sviMajor: 0; sviMinor: 0);
implementation
function SmallVersionInfoToStr (const Value: TSmallVersionInfo): string;
const Mask: string = '%d.%d';
begin
Result:= Format(Mask, [Value.sviMajor, Value.sviMinor]);
end;
function VersionInfoToStr (const Value: TVersionInfo): string;
const Mask: string = '%d.%d.%d.%d';
begin
Result:= Format(Mask, [Value.viMajor, Value.viMinor, Value.viRelease, Value.viBuild]);
end;
function VersionInfoToSmallVersionInfo (const Value: TVersionInfo): TSmallVersionInfo;
begin
Result.sviMajor:= Value.viMajor;
Result.sviMinor:= Value.viMinor;
end;
function SmallVersionInfoToVersionInfo (const Value: TSmallVersionInfo; const ANilValue: integer = 0): TVersionInfo;
begin
Result.viMajor:= Value.sviMajor;
Result.viMinor:= Value.sviMinor;
Result.viRelease:= ANilValue;
Result.viBuild:= ANilValue;
end;
function StrToVersionInfo (const AString: string): TVersionInfo;
var stringver: string;
CurrDelim, NextDelim, CurrIndex: Integer;
StrArray: array [1..4] of string;
begin
stringver:= AString;
CurrDelim:= 1;
CurrIndex:= 1;
repeat
NextDelim:= PosEx('.', stringver, CurrDelim);
if NextDelim = 0 then
NextDelim:= Length(stringver) + 1;
StrArray[CurrIndex]:= Copy(stringver, CurrDelim, NextDelim - CurrDelim);
CurrDelim:= NextDelim + 1;
CurrIndex:= CurrIndex + 1;
until CurrDelim > Length(stringver);
Result.viMajor:= StrToInt(StrArray[1]);
Result.viMinor:= StrToInt(StrArray[2]);
Result.viRelease:= StrToInt(StrArray[3]);
Result.viBuild:= StrToInt(StrArray[4]);
end;
function StrToSmallVersionInfo (const AString: string): TSmallVersionInfo;
var stringver: string;
CurrDelim, NextDelim: Integer;
StrArray: array [1..2] of string;
begin
stringver:= AString;
NextDelim:= PosEx('.', stringver, 1);
if NextDelim = 0 then
begin
StrArray[1]:= stringver;
Exit;
end;
StrArray[1]:= Copy(stringver, 1, NextDelim - 1);
CurrDelim:= NextDelim + 1;
NextDelim:= PosEx('.', stringver, CurrDelim);
if NextDelim = 0 then
NextDelim:= Length(stringver) + 1;
StrArray[2]:= Copy(stringver, CurrDelim, NextDelim - CurrDelim);
Result.sviMajor:= StrToInt(StrArray[1]);
Result.sviMinor:= StrToInt(StrArray[2]);
end;
function CompareVersionInfo (const AVersionInfo1, AVersionInfo2: TVersionInfo): integer;
//Result:
// 0 - AVersionInfo1 = AVersionInfo2
// -1 - AVersionInfo1 > AVersionInfo2
// 1 - AVersionInfo1 < AVersionInfo2
begin
//by default this versions are equal
Result:= 0;
//equal
if ((AVersionInfo1.viMajor = AVersionInfo2.viMajor) and
(AVersionInfo1.viMinor = AVersionInfo2.viMinor) and
(AVersionInfo1.viRelease = AVersionInfo2.viRelease) and
(AVersionInfo1.viBuild = AVersionInfo2.viBuild)) then
Result:= 0;
//more
if ((AVersionInfo1.viMajor > AVersionInfo2.viMajor) or
((AVersionInfo1.viMajor = AVersionInfo2.viMajor) and
(AVersionInfo1.viMinor > AVersionInfo2.viMinor)) or
((AVersionInfo1.viMajor = AVersionInfo2.viMajor) and
(AVersionInfo1.viMinor = AVersionInfo2.viMinor) and
(AVersionInfo1.viRelease > AVersionInfo2.viRelease)) or
((AVersionInfo1.viMajor = AVersionInfo2.viMajor) and
(AVersionInfo1.viMinor = AVersionInfo2.viMinor) and
(AVersionInfo1.viRelease = AVersionInfo2.viRelease) and
(AVersionInfo1.viBuild > AVersionInfo2.viBuild))) then
Result:= -1;
//less
if ((AVersionInfo1.viMajor < AVersionInfo2.viMajor) or
((AVersionInfo1.viMajor = AVersionInfo2.viMajor) and
(AVersionInfo1.viMinor < AVersionInfo2.viMinor)) or
((AVersionInfo1.viMajor = AVersionInfo2.viMajor) and
(AVersionInfo1.viMinor = AVersionInfo2.viMinor) and
(AVersionInfo1.viRelease < AVersionInfo2.viRelease)) or
((AVersionInfo1.viMajor = AVersionInfo2.viMajor) and
(AVersionInfo1.viMinor = AVersionInfo2.viMinor) and
(AVersionInfo1.viRelease = AVersionInfo2.viRelease) and
(AVersionInfo1.viBuild < AVersionInfo2.viBuild))) then
Result:= 1;
end;
function CompareSmallVersionInfo (const ASmallVersionInfo1, ASmallVersionInfo2: TSmallVersionInfo): integer;
var AVI1, AVI2: TVersionInfo;
begin
AVI1:= SmallVersionInfoToVersionInfo(ASmallVersionInfo1);
AVI2:= SmallVersionInfoToVersionInfo(ASmallVersionInfo2);
Result:= CompareVersionInfo(AVI1, AVI2);
end;
{$IFDEF WINDOWS}
function GetApplicationVersionInfoStr (const AFileName, AVersionSTR: string): string;
var VIC: TPJVersionInfo;
begin
VIC:= TPJVersionInfo.Create(nil);
VIC.FileName:= AFileName;
Result:= VIC.StringFileInfo[AVersionSTR];
VIC.Free;
end;
{$ENDIF WINDOWS}
end.

View File

@ -0,0 +1,93 @@
; ------------------------------------------------------------------------------
; This Source Code Form is subject to the terms of the Mozilla Public License,
; v. 2.0. If a copy of the MPL was not distributed with this file, You can
; obtain one at http://mozilla.org/MPL/2.0/
;
; Copyright (C) 2013, Peter Johnson (www.delphidabbler.com).
;
; $Rev: 1132 $
; $Date: 2013-01-14 03:31:09 +0000 (Mon, 14 Jan 2013) $
;
; Change Log for Version Information Component
; ------------------------------------------------------------------------------
Release v3.3.1 of 14 January 2013
+ Unit names are now qualified with namespace name on Delphi XE2 and later.
+ Changes to demo projects:
- Font and appearance of some controls changed.
- Controls are now themed.
- All form files now in text format.
- Forms are no longer scaled.
- 1st demo program's main window now resizes.
- 2nd demo dialogues' "help" buttona now display online examples instead of help file topics.
- Demos now need Delphi 7 as a minimum.
- New project configurations files.
+ Component source license changed to Mozilla Public License v2.0. (Demos now placed in public domain).
+ MPL text file and documentation wiki shortcut have had names changed.
+ WinHelp help file regenerated with updated copyright date.
+ Documentation revised.
Release v3.3 of 03 November 2010
+ Added operator overloads to TPJVersionNumber record when compiled with Delphi 2006 and later to:
- Support equality tests using =, <>, <, <=, > and >= operators.
- Support implicit casting to a string which formats the version number as a dotted quad (issue #12: http://code.google.com/p/ddab-lib/issues/detail?id=12).
+ Added new helper functions primarily for use with Delphi 2005 and earlier:
- CompareVerNums - compares two version number records.
- VerNumToStr - formats a version number as a dotted quad.
+ Updated TPJVersionNumber topic in help file re changes.
+ Updated HTML documentation.
Release v3.2 of 09 November 2009
+ Changed method used to get character set descriptions. These are now obtained from operating system where possible instead of from hard-wired values.
+ Added compiler directive to switch off unsafe code warnings on compilers that support the directive.
+ Added copy of Mozilla Public License.
+ Corrected error in help file.
+ Modified Demo 2 to enable it to compile on Delphi 2 and 3.
+ Updated documentation and included shortcut file that links to component Wiki.
Release v3.1.1 of 11 December 2005
+ Changed component to Mozilla public license.
+ Fixed minor bug in VIDemo project.
+ Revised HelpEgs demo project to access related help file topics.
+ Updated help file to make examples available from component's main page.
+ Updated HTML documentation.
Release v3.1 of 07 September 2003
+ Fixed to be compatible with C++ Builder - direct access to fields of TVSFixedFileInfo in property declarations were replaced by calls to an indexed property getter function.
Release v3.0.1 of 08 July 2003
+ Changed component palette from PJSoft to DelphiDabbler.
+ Updated HTML documentation.
+ Changed copyright message in help file.
Release v3.0 of 17 February 2002
+ Added ability to access all "translations" stored in a file's version information, rather than just first one. This has been done so that code using earlier versions of this component should continue to work unchanged.
+ Added new property to expose fixed file information record.
+ Added new "string array" property to give access to string information by name: this property can access any custom string information if the name is known.
+ Added properties to return number of "translations" and to select index of "translation" to be used.
+ Added properties to return language and character set codes in addition to descriptive strings.
+ All string info, language and character set properties now return values from the currently selected translation (which defaults to the first translation maintaining backward compatibilty).
+ Empty FileName property now accesses name of host application per command line rather than using Application.ExeName.
+ CharSet property now returns '' for unknown value rather than 'Unknown'.
+ Renamed TVersionNumber record to TPJVersionNumber.
+ Replaced Tvs_FixedFileInfo record with use of Windows unit defined type TVSFixedFileInfo.
+ Renamed unit to PJVersionInfo.
+ Changed component palette from "PJ Stuff" to "PJSoft".
+ Added two demo programs, one is a sample version information reading program and the other implements examples from the help file.
Release v2.1 of 28 November 1999
+ Changed unit name from VerInfo to VInfo to allow component to install under Delphi 3 & 4 (VerInfo clashes with an existing unit in these versions).
+ Removed superfluous conditional compilation directives.
+ Updated HTML documentation to separate 16 bit from 32 bit version, to to include installation notes for Delphi 3/4 and to include update history.
Release v2.0.1 of 08 July 1999
+ Changed palette where component installs to "PJ Stuff" from "Own".
+ Added HTML documentation (shared documentation with Release 1.0.1).
+ Included 16 bit Version Information Component release v1.0.1
Un-released v2.0 of 06 December 1998
+ Forked development - 32 bit development (this fork) began with v2.0 while the 16 bit version continued with v1.0.1
+ Revised for use with Win32 - not backwards compatible with v1.0
Un-released v1.0 of 26 April 1998
+ Original version - 16 bit only.

View File

@ -0,0 +1,3 @@
[InternetShortcut]
URL=http://www.delphidabbler.com/url/verinfo-docs

373
prereq/dd-verinfo/MPL-2.txt Normal file
View File

@ -0,0 +1,373 @@
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

View File

@ -0,0 +1,94 @@
charset
charset_property
charsetcode
charsetcode_property
comments
comments_property
companyname
companyname_property
currenttranslation
currenttranslation_property
filedescription
filedescription_property
fileflags
fileflags_property
fileflagsmask
fileflagsmask_property
filename
filename_property
fileos
fileos_property
filesubtype
filesubtype_property
filetype
filetype_property
fileversion
fileversion_property
fileversionnumber
fileversionnumber_property
fixedfileinfo
fixedfileinfo_property
haveinfo
haveinfo_property
internalname
internalname_property
language
language_property
languagecode
languagecode_property
legalcopyright
legalcopyright_property
legaltrademarks
legaltrademarks_property
numtranslations
numtranslations_property
originalfilename
originalfilename_property
privatebuild
privatebuild_property
productname
productname_property
productversion
productversion_property
productversionnumber
productversionnumber_property
specialbuild
specialbuild_property
stringfileinfo
stringfileinfo_property
tpjversioninfo
tpjversioninfo_charset
tpjversioninfo_charsetcode
tpjversioninfo_comments
tpjversioninfo_companyname
tpjversioninfo_currenttranslation
tpjversioninfo_example1
tpjversioninfo_example2
tpjversioninfo_example3
tpjversioninfo_example4
tpjversioninfo_filedescription
tpjversioninfo_fileflags
tpjversioninfo_fileflagsmask
tpjversioninfo_filename
tpjversioninfo_fileos
tpjversioninfo_filesubtype
tpjversioninfo_filetype
tpjversioninfo_fileversion
tpjversioninfo_fileversionnumber
tpjversioninfo_fixedfileinfo
tpjversioninfo_haveinfo
tpjversioninfo_internalname
tpjversioninfo_language
tpjversioninfo_languagecode
tpjversioninfo_legalcopyright
tpjversioninfo_legaltrademarks
tpjversioninfo_numtranslations
tpjversioninfo_object
tpjversioninfo_originalfilename
tpjversioninfo_privatebuild
tpjversioninfo_productname
tpjversioninfo_productversion
tpjversioninfo_productversionnumber
tpjversioninfo_specialbuild
tpjversioninfo_stringfileinfo
tpjversionnumber

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,926 @@
{
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/
*
* Copyright (C) 1998-2013, Peter Johnson (www.delphidabbler.com).
*
* $Rev: 1110 $
* $Date: 2013-01-13 23:26:17 +0000 (Sun, 13 Jan 2013) $
*
* Version Information Component. The component reads version information from
* executable files.
}
unit PJVersionInfo;
// Determine if certain features are supported by compiler
// * Supports_Assert - Defined if assertions supported (all compilers
// except Delphi 2).
// * Supports_ResourceString - Defined if resourcestring keyword supported (all
// compilers except Delphi 2).
// * Supports_AdvancedRecords - Defined if advanced records with record methods,
// operator overloads etc. supported (Delphi 2006
// and later).
// * Supports_RTLNameSpaces - Defined if Delphi RTL / VCL unit references
// should be qualified with namespaces.
{$DEFINE Supports_Assert}
{$DEFINE Supports_ResourceString}
{$UNDEF Supports_AdvancedRecords}
{$UNDEF Supports_RTLNameSpaces}
{$IFDEF VER90} // Delphi 2
{$UNDEF Supports_Assert}
{$UNDEF Supports_ResourceString}
{$ENDIF}
// Switch off unsafe code warnings if switch supported
{$IFDEF CONDITIONALEXPRESSIONS}
{$IF CompilerVersion >= 15.0} // >= Delphi 7
{$WARN UNSAFE_CODE OFF}
{$IFEND}
{$IF CompilerVersion >= 18.0} // >= Delphi 2006
{$DEFINE Supports_AdvancedRecords}
{$IFEND}
{$IF CompilerVersion >= 23.0} // Delphi XE2
{$DEFINE Supports_RTLNameSpaces}
{$IFEND}
{$ENDIF}
interface
uses
// Delphi
{$IFDEF Supports_RTLNameSpaces}
Winapi.Windows, System.Classes;
{$ELSE}
Windows, Classes;
{$ENDIF}
type
{
TPJVersionNumber:
Record that encapsulates version numbers.
}
TPJVersionNumber = record
V1: Word; // Major version number
V2: Word; // Minor version number
V3: Word; // Revision version number
V4: Word; // Build number
{$IFDEF Supports_AdvancedRecords}
class operator Implicit(Ver: TPJVersionNumber): string;
{Operator overload that performs implicit conversion of TPJVersionNumber
to string as dotted quad.
@param Ver [in] Version number to be converted.
@return Version number as dotted quad.
}
class operator LessThanOrEqual(Ver1, Ver2: TPJVersionNumber): Boolean;
{Operator overload that compares two version numbers to check if first is
less than or equal to the second.
@param Ver1 [in] First version number.
@param Ver2 [in] Second version number.
@return True if Ver1 <= Ver2, False otherwise.
}
class operator LessThan(Ver1, Ver2: TPJVersionNumber): Boolean;
{Operator overload that compares two version numbers to check if first is
less than second.
@param Ver1 [in] First version number.
@param Ver2 [in] Second version number.
@return True if Ver1 < Ver2, False otherwise.
}
class operator GreaterThan(Ver1, Ver2: TPJVersionNumber): Boolean;
{Operator overload that compares two version numbers to check if first is
greater than second.
@param Ver1 [in] First version number.
@param Ver2 [in] Second version number.
@return True if Ver1 > Ver2, False otherwise.
}
class operator GreaterThanOrEqual(Ver1, Ver2: TPJVersionNumber): Boolean;
{Operator overload that compares two version numbers to check if first is
greater than or equal to the second.
@param Ver1 [in] First version number.
@param Ver2 [in] Second version number.
@return True if Ver1 >= Ver2, False otherwise.
}
class operator Equal(Ver1, Ver2: TPJVersionNumber): Boolean;
{Operator overload that compares two version numbers to check for
equality.
@param Ver1 [in] First version number.
@param Ver2 [in] Second version number.
@return True if Ver1 = Ver2, False otherwise.
}
class operator NotEqual(Ver1, Ver2: TPJVersionNumber): Boolean;
{Operator overload that compares two version numbers to check for
inequality.
@param Ver1 [in] First version number.
@param Ver2 [in] Second version number.
@return True if Ver1 <> Ver2, False otherwise.
}
{$ENDIF}
end;
{
TPJVersionInfo:
Component that accesses the version information embedded in an executable
file and exposes the information as properties. Supports multi-lingual
version iformation resources.
}
TPJVersionInfo = class(TComponent)
private // properties
fFileName: string;
fHaveInfo: Boolean;
fNumTranslations: Integer;
fCurrentTranslation: Integer;
fFixedFileInfo: TVSFixedFileInfo;
procedure SetFileName(AName: string);
function GetProductVersionNumber: TPJVersionNumber;
function GetFileVersionNumber: TPJVersionNumber;
function GetLanguage: string;
function GetCharSet: string;
function GetCharSetCode: WORD;
function GetLanguageCode: WORD;
function GetCurrentTranslation: Integer;
procedure SetCurrentTranslation(const Value: Integer);
function GetStringFileInfo(const Name: string): string;
function GetStringFileInfoByIdx(Index: Integer): string;
function GetFixedFileInfoItemByIdx(Index: Integer): DWORD;
private
fPInfoBuffer: PChar; // Pointer to info buffer
fPTransBuffer: Pointer; // Pointer to translation buffer
procedure GetInfoBuffer(Len: DWORD);
{Creates an info buffer of required size.
@param Len [in] Required buffer size in characters.
}
procedure GetTransBuffer(Len: UINT);
{Creates a translation table buffer of required size.
@param Required buffer size in bytes.
}
function GetTransStr: string;
{Encodes information about the current translation in a string.
@return Required translation information.
}
protected
procedure ClearProperties; virtual;
{Forces properties to return cleared values.
}
procedure ReadVersionInfo; virtual;
{Reads version info from file named by FileName property.
}
public
constructor Create(AOwner: TComponent); override;
{Object constructor. Sets default values.
@param AOwner [in] Component that owns this one. May be nil.
}
destructor Destroy; override;
{Object destructor. Frees allocated memory.
}
property HaveInfo: Boolean
read fHaveInfo;
{Property true if file version info for the file named by the FileName
property has been successfully read}
property FixedFileInfo: TVSFixedFileInfo
read fFixedFileInfo;
{Exposes the whole fixed file info record. Following properties expose
the various fields of it}
property FileVersionNumber: TPJVersionNumber
read GetFileVersionNumber;
{Version number of file in numeric format. From fixed file info}
property ProductVersionNumber: TPJVersionNumber
read GetProductVersionNumber;
{Version number of product in numeric format. From fixed file info}
property FileOS: DWORD index 0
read GetFixedFileInfoItemByIdx;
{Code describing operating system to be used by file, From fixed file
info}
property FileType: DWORD index 1
read GetFixedFileInfoItemByIdx;
{Code descibing type of file. From fixed file info}
property FileSubType: DWORD index 2
read GetFixedFileInfoItemByIdx;
{Code describing sub-type of file - only used for certain values of
FileType property. From fixed file info}
property FileFlagsMask: DWORD index 3
read GetFixedFileInfoItemByIdx;
{Code describing which FileFlags are valid. From fixed file info}
property FileFlags: DWORD index 4
read GetFixedFileInfoItemByIdx;
{Flags describing file state. From fixed file info}
property Comments: string index 0
read GetStringFileInfoByIdx;
{String file info property giving user defined comments in current
translation}
property CompanyName: string index 1
read GetStringFileInfoByIdx;
{String file info property giving name of company in current translation}
property FileDescription: string index 2
read GetStringFileInfoByIdx;
{String file info property giving description of file in current
translation}
property FileVersion: string index 3
read GetStringFileInfoByIdx;
{String file info property giving version number of file in string format
in current translation}
property InternalName: string index 4
read GetStringFileInfoByIdx;
{String file info property giving internal name of file in current
translation}
property LegalCopyright: string index 5
read GetStringFileInfoByIdx;
{String file info property giving copyright message in current
translation}
property LegalTrademarks: string index 6
read GetStringFileInfoByIdx;
{String file info property giving trademark info in current translation}
property OriginalFileName: string index 7
read GetStringFileInfoByIdx;
{String file info property giving original name of file in current
translation}
property PrivateBuild: string index 8
read GetStringFileInfoByIdx;
{String file info property giving information about a private build of
file in current translation}
property ProductName: string index 9
read GetStringFileInfoByIdx;
{String file info property giving name of product in current translation}
property ProductVersion: string index 10
read GetStringFileInfoByIdx;
{String file info property giving version number of product in string
format in current translation}
property SpecialBuild: string index 11
read GetStringFileInfoByIdx;
{String file info property giving information about a special build of
file in current translation}
property StringFileInfo[const Name: string]: string
read GetStringFileInfo;
{Value of named string file info item in current translation. This
property can access both standard and custom string info}
property Language: string
read GetLanguage;
{Name of language in use in current translation}
property CharSet: string
read GetCharSet;
{Name of character set in use in current translation}
property LanguageCode: WORD
read GetLanguageCode;
{Code of laguage in use in current translation}
property CharSetCode: WORD
read GetCharSetCode;
{Code of character set in use in current translation}
property NumTranslations: Integer
read fNumTranslations;
{The number of difference translations (ie languages and char sets) in
the version information}
property CurrentTranslation: Integer
read GetCurrentTranslation write SetCurrentTranslation;
{Zero-based index of the current translation: this is 0 when a file is
first accessed. Set to a value in range 0..NumTranslations-1 to access
other translations. All string info, language and char set properties
return information for the current translation}
published
property FileName: string read fFileName write SetFileName;
{Name of file containing version information. If set to '' (default) the
version information comes from the containing executable file}
end;
function VerNumToStr(const Ver: TPJVersionNumber): string;
{Converts a version number to its string representation as a dotted quad.
@param Ver [in] Version number to be converted.
@return Version number as dotted quad.
}
function CompareVerNums(const Ver1, Ver2: TPJVersionNumber): Integer;
{Compares two version numbers and returns a value indicating if the first is
less than, equal to or greater than the second.
@param Ver1 [in] First version number to compare.
@param Ver2 [in] Second version number to compare.
@return 0 if Ver1 = Ver2, -ve if Ver1 < Ver2, +ve if Ver1 > Ver2.
}
procedure Register;
{Registers this component.
}
implementation
uses
{$IFDEF Supports_RTLNameSpaces}
System.SysUtils;
{$ELSE}
// Delphi
SysUtils;
{$ENDIF}
procedure Register;
{Registers this component.
}
begin
RegisterComponents('DelphiDabbler', [TPJVersionInfo]);
end;
type
// ANSI version of CPINFOEX: provides information about a code page
_cpinfoexA = packed record
MaxCharSize: UINT;
{max length in bytes of a character in the code page}
DefaultChar: array[0..MAX_DEFAULTCHAR-1] of Byte;
{default character used to translate strings to the specific code page}
LeadByte: array[0..MAX_LEADBYTES-1] of Byte;
{fixed-length array of lead byte ranges: all elements null if none}
UnicodeDefaultChar: WideChar;
{unicode default char used in translations from the specific code page}
CodePage: UINT;
{code page value}
CodePageName: array[0..MAX_PATH-1] of AnsiChar;
{full localised name of the code page}
end;
CPINFOEXA = _cpinfoexA;
PCPInfoExA = ^CPINFOEXA;
TCPInfoExA = CPINFOEXA;
// Unicode version of CPINFOEX: provides information about a code page
_cpinfoexW = packed record
MaxCharSize: UINT;
{max length in bytes of a character in the code page}
DefaultChar: array[0..MAX_DEFAULTCHAR-1] of Byte;
{default character used to translate strings to the specific code page}
LeadByte: array[0..MAX_LEADBYTES-1] of Byte;
{fixed-length array of lead byte ranges: all elements null if none}
UnicodeDefaultChar: WideChar;
{unicode default char used in translations from the specific code page}
CodePage: UINT;
{code page value}
CodePageName: array[0..MAX_PATH-1] of WideChar;
{full localised name of the code page}
end;
CPINFOEXW = _cpinfoexW;
PCPInfoExW = ^CPINFOEXW;
TCPInfoExW = CPINFOEXW;
// Set TCPInfoEx etc to required ANSI or Unicode version of structure
{$IFDEF UNICODE}
TCPInfoEx = TCPInfoExW;
PCPInfoEx = PCPInfoExW;
{$ELSE}
TCPInfoEx = TCPInfoExA;
PCPInfoEx = PCPInfoExA;
{$ENDIF}
CPINFOEX = TCPInfoEx;
var
// Pointer to Windows API GetCPInfoEx function if it exists or to GetCPInfoAlt
// otherwise
GetCPInfoExFn: function (CodePage: UINT; dwFlags: DWORD;
var lpCPInfoEx: TCPInfoEx): BOOL; stdcall;
const
// Import name of GetCPInfoEx. Unicode and ANSI versions.
{$IFDEF UNICODE}
cGetCPInfoEx = 'GetCPInfoExW';
{$ELSE}
cGetCPInfoEx = 'GetCPInfoExA';
{$ENDIF}
function GetCPInfoAlt(CodePage: UINT; dwFlags: DWORD;
var lpCPInfoEx: TCPInfoEx): BOOL; stdcall;
{Local implementation of GetCPInfoEx, for use on OSs that don't support
GetCPInfoEx. Calls older GetCPInfo API function and calculates members of
TCPInfoEx not provided by GetCPInfo.
@param CodePage [in] Code page for which information is required.
@param dwFlags [in] Reserved. Must be 0.
@param lpCPInfoEx [in/out] Structure that receives information about the
code page.
@return True on success, False on error.
}
// ---------------------------------------------------------------------------
procedure CopyByteArray(const Src: array of Byte; var Dest: array of Byte);
{Makes a copy of a byte array.
@param Src [in] Byte array to be copied.
@param Dest [in/out] In: Array to receive copy: must be same size as Src.
Out: Receives copy of Src.
}
var
Idx: Integer; // loops thru array
begin
{$IFDEF Supports_Assert}
Assert((Low(Src) = Low(Dest)) and (High(Src) = High(Dest)));
{$ENDIF}
for Idx := Low(Src) to High(Src) do
Dest[Idx] := Src[Idx];
end;
// ---------------------------------------------------------------------------
const
sCodePage = 'Code Page %d'; // description of code page if OS doesn't provide
var
OldInfo: TCPInfo; // old style code page info structure for Win95/NT4
begin
// We haven't got GetCPInfoEx: use old GetCPInfo to get some info
Result := GetCPInfo(CodePage, OldInfo);
if Result then
begin
// We update TCPInfoEx structure from old style structure and calculate
// additional info
// copy over from old style TCPInfo structure
lpCPInfoEx.MaxCharSize := OldInfo.MaxCharSize;
CopyByteArray(OldInfo.DefaultChar, lpCPInfoEx.DefaultChar);
CopyByteArray(OldInfo.LeadByte, lpCPInfoEx.LeadByte);
// no new default char
lpCPInfoEx.UnicodeDefaultChar := #0;
// store reference to code page
lpCPInfoEx.CodePage := CodePage;
// description is simply "Code Page NNN"
StrPLCopy(
lpCPInfoEx.CodePageName,
Format(sCodePage, [CodePage]),
SizeOf(lpCPInfoEx.CodePageName)
);
end;
end;
function VerNumToStr(const Ver: TPJVersionNumber): string;
{Converts a version number to its string representation as a dotted quad.
@param Ver [in] Version number to be converted.
@return Version number as dotted quad.
}
begin
Result := Format('%d.%d.%d.%d', [Ver.V1, Ver.V2, Ver.V3, Ver.V4]);
end;
function CompareVerNums(const Ver1, Ver2: TPJVersionNumber): Integer;
{Compares two version numbers and returns a value indicating if the first is
less than, equal to or greater than the second.
@param Ver1 [in] First version number to compare.
@param Ver2 [in] Second version number to compare.
@return 0 if Ver1 = Ver2, -ve if Ver1 < Ver2, +ve if Ver1 > Ver2.
}
begin
Result := Ver1.V1 - Ver2.V1;
if Result <> 0 then
Exit;
Result := Ver1.V2 - Ver2.V2;
if Result <> 0 then
Exit;
Result := Ver1.V3 - Ver2.V3;
if Result <> 0 then
Exit;
Result := Ver1.V4 - Ver2.V4;
end;
type
{
TTransRec:
Record of language code and char set codes that are returned from version
information.
}
TTransRec = packed record
Lang: Word; // language code
CharSet: Word; // character set code
end;
{
TTransRecs:
Type used to type cast translation data into an array of translation
records.
}
TTransRecs = array[0..1000] of TTransRec;
{
PTransRecs:
Pointer to an array of translation records.
}
PTransRecs = ^TTransRecs;
{ TPJVersionInfo }
procedure TPJVersionInfo.ClearProperties;
{Forces properties to return cleared values.
}
begin
// Record that we haven't read ver info: this effectively clears properties
// since each property read access method checks this flag before returning
// result
fHaveInfo := False;
end;
constructor TPJVersionInfo.Create(AOwner: TComponent);
{Object constructor. Sets default values.
@param AOwner [in] Component that owns this one. May be nil.
}
begin
inherited Create(AOwner);
// Default is no file name - refers to executable file for application
FileName := '';
end;
destructor TPJVersionInfo.Destroy;
{Object destructor. Frees allocated memory.
}
begin
// Ensure that info buffer is freed if allocated
if fPInfoBuffer <> nil then
StrDispose(fPInfoBuffer);
// Ensure that translation buffer is free if allocated
if fPTransBuffer <> nil then
FreeMem(fPTransBuffer);
inherited Destroy;
end;
function TPJVersionInfo.GetCharSet: string;
{Read accessor for CharSet property:
@return String describing character set if version info is available or
empty string if not.
}
var
Info: TCPInfoEx; // receives code page info
CP: Word; // code page
const
// Special code page messages
sUnknownCP = '%d (Unknown Code Page)'; // unknown
// Messages for pages API can't return (managed apps only)
sUTF16LE = '%d (Unicode UTF-16, little endian byte order)';
sUTF16BE = '%d (Unicode UTF-16, big endian byte order)';
sUTF32LE = '%d (Unicode UTF-32, little endian byte order)';
sUTF32BE = '%d (Unicode UTF-32, big endian byte order)';
begin
Result := '';
if fHaveInfo then
begin
CP := GetCharSetCode;
case CP of
// Check for char codes only available in managed apps (API call won't
// find them)
1200: Result := Format(sUTF16LE, [CP]);
1201: Result := Format(sUTF16BE, [CP]);
12000: Result := Format(sUTF32LE, [CP]);
12001: Result := Format(sUTF32BE, [CP]);
else
begin
// Not a known problem code page: get it from OS
if GetCPInfoExFn(CP, 0, Info) then
Result := Info.CodePageName
else
// Give up: can't find it
Result := Format(sUnknownCP, [CP]);
end;
end;
end;
end;
function TPJVersionInfo.GetCharSetCode: WORD;
{Read accessor for CharSetCode property.
@return Char set code for current translation or 0 if there is no
translation or there is no version info.
}
begin
if fHaveInfo and (GetCurrentTranslation >= 0) then
Result := PTransRecs(fPTransBuffer)^[GetCurrentTranslation].CharSet
else
Result := 0;
end;
function TPJVersionInfo.GetCurrentTranslation: Integer;
{Read accessor for CurrentTranslation property.
@return Index to current translation if version info is available or -1 if
not.
}
begin
if fHaveInfo then
Result := fCurrentTranslation
else
Result := -1;
end;
function TPJVersionInfo.GetFileVersionNumber: TPJVersionNumber;
{Read accessor for FileVersionNumber property.
@return Record containing version information. If there is no version info
then all fields will be zero.
}
begin
Result.V1 := HiWord(fFixedFileInfo.dwFileVersionMS);
Result.V2 := LoWord(fFixedFileInfo.dwFileVersionMS);
Result.V3 := HiWord(fFixedFileInfo.dwFileVersionLS);
Result.V4 := LoWord(fFixedFileInfo.dwFileVersionLS);
end;
function TPJVersionInfo.GetFixedFileInfoItemByIdx(Index: Integer): DWORD;
{Read accessor method for various DWORD fields of the fixed file information
record accessed by index.
NOTE: This is a fix for C++ Builder. Delphi is able to access the fields of
the TVSFixedFileInfo record directly in the read clause of the property
declaration but this is not possible in C++ Builder.
@param Index [in] Index of required property.
@return Required DWORD value.
}
begin
case Index of
0: Result := fFixedFileInfo.dwFileOS;
1: Result := fFixedFileInfo.dwFileType;
2: Result := fFixedFileInfo.dwFileSubType;
3: Result := fFixedFileInfo.dwFileFlagsMask;
4: Result := fFixedFileInfo.dwFileFlags;
else Result := 0;
end;
end;
procedure TPJVersionInfo.GetInfoBuffer(Len: DWORD);
{Creates an info buffer of required size.
@param Len [in] Required buffer size in characters.
}
begin
// Clear any existing buffer
if fPInfoBuffer <> nil then
StrDispose(fPInfoBuffer);
// Create the new one
fPInfoBuffer := StrAlloc(Len);
end;
function TPJVersionInfo.GetLanguage: string;
{Read accessor for Language property
@return String describing language or empty string if no version info
available.
}
const
cBufSize = 256; // size of buffer
var
Buf: array[0..Pred(cBufSize)] of Char; // stores langauge string from API call
begin
// Assume failure
Result := '';
// Try to get language name from Win API if we have ver info
if fHaveInfo and
(VerLanguageName(GetLanguageCode, Buf, Pred(cBufSize)) > 0) then
Result := Buf;
end;
function TPJVersionInfo.GetLanguageCode: WORD;
{Read accessor for LanguageCode property
@return Language code for current translation or 0 if there is no
translation or there is no version info.
}
begin
if fHaveInfo and (GetCurrentTranslation >= 0) then
Result := PTransRecs(fPTransBuffer)^[GetCurrentTranslation].Lang
else
Result := 0;
end;
function TPJVersionInfo.GetProductVersionNumber: TPJVersionNumber;
{Read accessor for ProductVersionNumber property.
@return Record containing version information. If there is no version info
then all fields will be zero.
}
begin
Result.V1 := HiWord(fFixedFileInfo.dwProductVersionMS);
Result.V2 := LoWord(fFixedFileInfo.dwProductVersionMS);
Result.V3 := HiWord(fFixedFileInfo.dwProductVersionLS);
Result.V4 := LoWord(fFixedFileInfo.dwProductVersionLS);
end;
function TPJVersionInfo.GetStringFileInfo(const Name: string): string;
{Read accessor for StringFileInfo array property.
@param Name [in] Name of required string information.
@return String associated Name or empty string if there is no version info.
}
var
CommandBuf: array[0..255] of char; // buffer to build API call command str
Ptr: Pointer; // pointer to result of API call
Len: UINT; // length of structure returned from API
begin
// Set default failure result to empty string
Result := '';
// Check if we have valid information recorded in info buffer - exit if not
if fHaveInfo then
begin
// Build API call command string for reading string file info:
// this uses info string + language and character set
StrPCopy(CommandBuf, '\StringFileInfo\' + GetTransStr + '\' + Name);
// Call API to get required string and return it if successful
if VerQueryValue(fPInfoBuffer, CommandBuf, Ptr, Len) then
Result := PChar(Ptr);
end;
end;
function TPJVersionInfo.GetStringFileInfoByIdx(Index: Integer): string;
{Read accessor for all string file info properties.
@param Index [in] Index of required property.
@return Appropriate string value of the indexed property or empty string if
property has no value or there is no version info.
}
const
cNames: array[0..11] of string =
('Comments', 'CompanyName', 'FileDescription', 'FileVersion',
'InternalName', 'LegalCopyright', 'LegalTrademarks', 'OriginalFileName',
'PrivateBuild', 'ProductName', 'ProductVersion', 'SpecialBuild');
{names of predefined string file info strings}
begin
Result := GetStringFileInfo(cNames[Index]);
end;
procedure TPJVersionInfo.GetTransBuffer(Len: UINT);
{Creates a translation table buffer of required size.
@param Required buffer size in bytes.
}
begin
// Clear any existing buffer
if fPTransBuffer <> nil then
FreeMem(fPTransBuffer);
// Create the new one
GetMem(fPTransBuffer, Len);
end;
function TPJVersionInfo.GetTransStr: string;
{Encodes information about the current translation in a string.
@return Required translation information.
}
var
TransRec: TTransRec; // translation record in array of translations
begin
if GetCurrentTranslation >= 0 then
begin
// There is a valid current translation: return hex string related to it
TransRec := PTransRecs(fPTransBuffer)^[GetCurrentTranslation];
Result := Format('%4.4x%4.4x', [TransRec.Lang, TransRec.CharSet]);
end
else
// No valid translation string: return empty string
Result := '';
end;
procedure TPJVersionInfo.ReadVersionInfo;
{Reads version info from file named by FileName property.
}
var
Len: UINT; // length of structs returned from API calls
Ptr: Pointer; // points to version info structures
InfoSize: DWORD; // size of info buffer
Dummy: DWORD; // stores 0 in call to GetFileVersionInfoSize
begin
// Record default value of HaveInfo property - no info read
fHaveInfo := False;
// Store zeros in fixed file info structure: this is used when no info
FillChar(fFixedFileInfo, SizeOf(fFixedFileInfo), 0);
// Set NumTranslations property to 0: this is value if no info
fNumTranslations := 0;
// Record required size of version info buffer
InfoSize := GetFileVersionInfoSize(PChar(fFileName), Dummy);
// Check that there was no error
if InfoSize > 0 then
begin
// Found info size OK
// Ensure we have a sufficiently large buffer allocated
GetInfoBuffer(InfoSize);
// Read file version info into storage and check success
if GetFileVersionInfo(PChar(fFileName), Dummy, InfoSize, fPInfoBuffer) then
begin
// Success: we've read file version info to storage OK
fHaveInfo := True;
// Get fixed file info & copy to own storage
VerQueryValue(fPInfoBuffer, '\', Ptr, Len);
fFixedFileInfo := PVSFixedFileInfo(Ptr)^;
// Get first translation table info from API
VerQueryValue(fPInfoBuffer, '\VarFileInfo\Translation', Ptr, Len);
// Ptr is to block of translation records each of size Len:
// work out number of translations
fNumTranslations := Len div SizeOf(TTransRec);
// store translation array in a buffer
GetTransBuffer(Len);
Move(Ptr^, fPTransBuffer^, Len);
// make first translation in block current one (-1 if no translations)
SetCurrentTranslation(0); // adjusts value to -1 if no translations
end;
end;
end;
procedure TPJVersionInfo.SetCurrentTranslation(const Value: Integer);
{Write acceesor method CurrentTranslation property
@param Index of required translation. If Value is out of range then the
property is set to -1 to indicate no translation.
}
begin
if (Value >= 0) and (Value < NumTranslations) then
fCurrentTranslation := Value
else
fCurrentTranslation := -1
end;
procedure TPJVersionInfo.SetFileName(AName: string);
{Write accessor for FileName property. Action at design time and run time is
different. At design time we simply record the property value while at run
time we store the value and read any version information from the file.
@param AName [in] New value of FileName property. If '' then property is set
to the name of the program's executable file.
}
begin
if csDesigning in ComponentState then
// We are designing, simply record the required name
fFileName := AName
else
begin
// It's run-time
// use Application exec file name if name is ''
if AName = '' then
fFileName := ParamStr(0)
else
fFileName := AName;
// clear all properties and read file version info for new file
ClearProperties;
ReadVersionInfo;
end;
end;
{$IFDEF Supports_AdvancedRecords}
{ TPJVersionNumber }
class operator TPJVersionNumber.Equal(Ver1, Ver2: TPJVersionNumber): Boolean;
{Operator overload that compares two version numbers to check for equality.
@param Ver1 [in] First version number.
@param Ver2 [in] Second version number.
@return True if Ver1 = Ver2, False otherwise.
}
begin
Result := CompareVerNums(Ver1, Ver2) = 0;
end;
class operator TPJVersionNumber.GreaterThan(Ver1,
Ver2: TPJVersionNumber): Boolean;
{Operator overload that compares two version numbers to check if first is
greater than second.
@param Ver1 [in] First version number.
@param Ver2 [in] Second version number.
@return True if Ver1 > Ver2, False otherwise.
}
begin
Result := CompareVerNums(Ver1, Ver2) > 0;
end;
class operator TPJVersionNumber.GreaterThanOrEqual(Ver1,
Ver2: TPJVersionNumber): Boolean;
{Operator overload that compares two version numbers to check if first is
greater than or equal to the second.
@param Ver1 [in] First version number.
@param Ver2 [in] Second version number.
@return True if Ver1 >= Ver2, False otherwise.
}
begin
Result := CompareVerNums(Ver1, Ver2) >= 0;
end;
class operator TPJVersionNumber.Implicit(Ver: TPJVersionNumber): string;
{Operator overload that performs implicit conversion of TPJVersionNumber to
string as dotted quad.
@param Ver [in] Version number to be converted.
@return Version number as dotted quad.
}
begin
Result := VerNumToStr(Ver);
end;
class operator TPJVersionNumber.LessThan(Ver1, Ver2: TPJVersionNumber): Boolean;
{Operator overload that compares two version numbers to check if first is less
than second.
@param Ver1 [in] First version number.
@param Ver2 [in] Second version number.
@return True if Ver1 < Ver2, False otherwise.
}
begin
Result := CompareVerNums(Ver1, Ver2) < 0;
end;
class operator TPJVersionNumber.LessThanOrEqual(Ver1,
Ver2: TPJVersionNumber): Boolean;
{Operator overload that compares two version numbers to check if first is less
than or equal to the second.
@param Ver1 [in] First version number.
@param Ver2 [in] Second version number.
@return True if Ver1 <= Ver2, False otherwise.
}
begin
Result := CompareVerNums(Ver1, Ver2) <= 0;
end;
class operator TPJVersionNumber.NotEqual(Ver1, Ver2: TPJVersionNumber): Boolean;
{Operator overload that compares two version numbers to check for inequality.
@param Ver1 [in] First version number.
@param Ver2 [in] Second version number.
@return True if Ver1 <> Ver2, False otherwise.
}
begin
Result := CompareVerNums(Ver1, Ver2) <> 0;
end;
{$ENDIF}
initialization
// Get reference to GetCPInfoEx function
GetCPInfoExFn := GetProcAddress(GetModuleHandle('Kernel32.dll'), cGetCPInfoEx);
if not Assigned(GetCPInfoExFn) then
GetCPInfoExFn := GetCPInfoAlt;
end.

View File

@ -0,0 +1,451 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!--
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/
*
* Copyright (C) 2005-2013, Peter Johnson (www.delphidabbler.com).
*
* $Rev: 1131 $
* $Date: 2013-01-14 03:27:03 +0000 (Mon, 14 Jan 2013) $
*
* Read-me file for Version Information Component.
-->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>
DelphiDabbler Version Information Component ReadMe
</title>
<style type="text/css">
body {
margin: 1em;
padding: 0;
font-family: Verdana, Arial, sans-serif;
font-size: 9pt;
line-height: 150%;
}
h1 {
margin: 0 0 1em 0;
padding: 0.5em;
border: 1px silver solid;
background-color: #eee;
font-size: 13pt;
font-weight: bold;
text-align: center;
}
h1 .subtitle {
font-style: italic;
color: #336;
}
h2 {
margin: 1em 0 0 0;
padding: 0;
padding-bottom: 6px;
border-bottom: 1px silver solid;
font-size: 11pt;
font-weight: bold;
}
h3 {
margin: 0.5em 0 0 0;
padding: 0;
font-size: 9pt;
font-weight: bold;
}
p {
margin: 0.5em 0 0 0;
padding: 0;
}
ul, ol {
margin: 0.5em 0 0 3em;
padding: 0;
}
ul {
list-style-type: square;
}
ul.spaced li,
ol.spaced li {
margin-top: 0.5em;
}
ul.spaced li,
ol.spaced li {
margin-top: 0.5em;
}
ul.unspaced li,
ol.unspaced li {
margin-top: 0;
}
ul.unspaced li.first,
ol.unspaced li.first {
margin-top: 0.5em;
}
code {
font-family: "Courier New", Courier, monospace;
}
a:link {
color: #336;
text-decoration: underline;
}
a:visited {
color: #669;
text-decoration: underline;
}
a:active {
color: #336;
text-decoration: underline;
}
a:hover {
text-decoration: underline;
}
.pullout {
border-left: 8px silver solid;
background-color: #eee;
margin: 0.5em 0 0 0;
padding: 0.25em 0.5em;
font-style: italic;
}
.indent {
margin-left: 3em;
}
.highlight {
color: #336;
font-style: italic;
font-weight: bold;
}
.endnotes {
margin: 1.5em 0 0 0;
padding: 1em 0 0 0;
border-top: 1px silver solid;
}
.comments {
font-style: italic;
}
.copyright,
.copyright a:link,
.copyright a:visited,
.copyright a:active {
margin: 1em 0 0 0;
color: gray;
font-size: 8pt;
text-align: right;
}
</style>
</head>
<body>
<h1>
<div>Version Information Component</div>
<div class="subtitle">ReadMe</div>
</h1>
<h2 id="contents">
Contents
</h2>
<ul>
<li><a href="#description">Description</a></li>
<li><a href="#installation">Installation</a></li>
<li><a href="#demo">Demo Projects</a></li>
<li><a href="#update">Update History</a></li>
<li><a href="#license">License</a></li>
<li><a href="#bugs">Bugs and Feature Requests</a></li>
<li><a href="#author">About the Author</a></li>
</ul>
<h2 id="description">
Description
</h2>
<p>
<var>TPJVersionInfo</var> is a 32 bit non-visual component for all Win32
versions of Delphi that encapsulates the version information contained in an
executable file's resources.
</p>
<p>
The component reads information from a designated file's
<var>VERSIONINFO</var> resource. The required file is specified in the
component's <var>FileName</var> property. Setting <var>FileName</var> to the
empty string fetches version information for the executable file containing
the component. The boolean <var>HaveInfo</var> property indicates whether the
file contains version information. This component can access variable file
information for each language provided in the resource.
</p>
<p>
Run-time properties enable access to to version information. Properties
enable:
</p>
<ul>
<li>
Access to fixed file information, either by field or the whole record.
</li>
<li>
Access to the number of translations stored in the version information.
</li>
<li>
Selection of the translation for which information is to be returned by
other properties.
</li>
<li>
Access to the language and code page of the current translation &ndash; by
code and by name.
</li>
<li>
Access to the string file information for the current translation &ndash;
named properties access the Microsoft-defined string information, while an
array property gives access to any string item by name.
</li>
</ul>
<p>
Version numbers are encapsulated in <var>TPJVersionNumber</var> records which,
on Delphi 2006 or later, can be directly assigned to a string and can be
compared using the normal equality operators. Helper functions are also
provided for use with earlier Delphis that can format version numbers as text
and can compare them.
</p>
<h3>
Limitations
</h3>
<p>
The component makes calls to the Windows API. Therefore the version
information being read must follow the Microsoft guidelines &ndash; be warned
that not all software complies!
</p>
<h3>
Compatibility
</h3>
<p>
<var>TPJVersionInfo</var> compiles on all Win32 versions and personalities of
Delphi. Releases up v3.3 have tested with Delphi versions 2, 3, 4, 6, 7, 2006
and 2010 while later releases have been tested on Delphi 7 and 2006 to XE3 and
are assumed to work on later versions.
</p>
<p>
The unit name changed to <code>PJVersionInfo</code> at release 3 &ndash; this
means that programs using earlier versions will need to be modified (or to
have an alias set in Delphi's Project Options) before being recompiled using
the new version. Functionally, the component is backward compatible with
earlier versions.
</p>
<h3>
Further information
</h3>
<p>
For detailed information about version information refer to the Windows SDK.
</p>
<h2 id="installation">
Installation
</h2>
<div class="pullout">
<strong>Important Note:</strong> If you are updating from an earlier version
of this component and have installed the <em>DelphiDabbler</em> About Box
Component (<var>TPJAboutBoxDlg</var>) you may need to uninstall it before
updating this component, and re-install the about box component once the
update has been installed. If the About Box Component is earlier that v3.2 it
will need to be updated to the most recent version.
</div>
<p>
The <em>Version Information Component</em> is supplied in a zip file. Before
installing you need to extract all the files from the zip file. The following
files will be extracted:
</p>
<ul>
<li>
<strong><code>PJVersionInfo.pas</code></strong> &ndash; Component source
code.
</li>
<li>
<strong><code>PJVersionInfo.dcr</code></strong> &ndash; Component palette
glyph.
</li>
<li>
<code>PJVersionInfo.hlp</code> &ndash; Help file that integrates into the
Delphi 3-7 IDE.
</li>
<li>
<code>PJVersionInfo.als</code> &ndash; Keyword file required when
integrating the help file with Delphi 6 and 7.
</li>
<li>
<code>ReadMe.htm</code> &ndash; This read-me file.
</li>
<li>
<code>ChangeLog.txt</code> &ndash; Change log.
</li>
<li>
<code>MPL-2.txt</code> &ndash; Mozilla Public License v2.0.
</li>
<li>
<code>Documentation.URL</code> &ndash; Shortcut to the component's online
documentation.
</li>
</ul>
<p>
In addition to the above files you will find the the source code of two <a
href="#demo"
>demo projects</a> along with readme files in the <code>Demos\1</code> and
<code>Demos\2</code> sub-directories.
</p>
<p>
You can now install the component into the Delphi IDE.
</p>
<p>
For Delphi 3 onwards you must include <code>PJVersionInfo.pas</code> and
<code>PJVersionInfo.dcr</code> in a design time package that is installed into
the Delphi IDE. If you need help doing this <a
href="http://www.delphidabbler.com/url/install-comp"
>see here</a>.
</p>
<p>
Note that the help file included in the download can only integrate with the
IDE in Delphi 3-7. For information on how to do this, see <a
href="http://www.delphidabbler.com/articles?article=15"
>this article</a>. Users of other versions of Delphi can either use the help
file as a stand-alone file (in which case some links won't work) or you can
use the component's <a
href="http://www.delphidabbler.com/url/verinfo-docs"
>online documentation</a>.
</p>
<h2 id="demo">
Demo Projects
</h2>
<p>
The source code for two demo projects is included. The demos are:
</p>
<ol class="spaced">
<li>
<code>VIDemo.dpr</code> is an application that can extract and display
version information from any program (provided that the program has valid
version information).
</li>
<li>
<code>HelpEgs.dpr</code> implements all the <a
href="http://delphidabbler.com/url/verinfo-egs"
>examples</a> from the online documentation and help file.
</li>
</ol>
<p>
These demos require Delphi 7 or later.
</p>
<p>
<strong>Note:</strong> To load the projects into Delphi 2007 first delete the
relevant <code>.dproj</code> file and then load the project from the
<code>.bdsproj</code> file.
</p>
<div class="pullout">
With some minor changes they will also compile as 64 bit Windows targets using
the 64 bit Delphi. (Tested with Delphi XE3). To do this create a 64 bit
Windows target, ensure that the compiler can find the component source file
(or a 64 bit compiled unit) and disable automatic version information
generation.
</div>
<h2 id="update">
Update History
</h2>
<p>
A complete change log is provided in a text file that is included in the
download.
</p>
<h2 id="license">
License
</h2>
<p>
This component is released under the terms of the <a
href="http://www.mozilla.org/MPL/2.0/"
>Mozilla Public License v2.0</a>.
</p>
<h2 id="bugs">
Bugs and Feature Requests
</h2>
<p>
Bugs can be reported or new features requested via the <a
href="http://www.delphidabbler.com/url/ddlib-issues"
>Issue Tracker</a>.
</p>
<p>
If no similar report or request has been recorded already, use the <em>New
Issue</em> link to add a new issue. Please select the <em>Defect Report from
User</em> template and be sure to specify the <code>Project-verinfo</code>
label.
</p>
<p>
Feature requests are also made using the Issue Tracker. This time please
select the <em>Feature Request</em> template and, again, specify the
<code>Project-verinfo</code> label.
</p>
<h2 id="author">
About the Author
</h2>
<p>
I'm Peter Johnson &ndash; a hobbyist programmer living in Ceredigion in West
Wales, UK, writing write mainly in Delphi. My programs and code are
available from: <a
href="http://www.delphidabbler.com/"
>http://www.delphidabbler.com/</a>.
</p>
<p>
I can be <a
href="http://www.delphidabbler.com/contact"
>contacted via the website</a>.
</p>
<div class="endnotes">
<div class="comments">
Please <a
href="http://www.delphidabbler.com/contact"
>let me know</a> if you have any comments about the component, but please
use the Issue Tracker noted above to report bugs and request new features.
</div>
<div class="copyright">
This document is copyright &copy; 2005-2013, P D Johnson, <a
href="http://www.delphidabbler.com/"
>www.delphidabbler.com</a>.
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,72 @@
<?xml version="1.0"?>
<CONFIG>
<Package Version="4">
<PathDelim Value="\"/>
<Name Value="dd_versioninfo"/>
<Author Value="Peter Johnson"/>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)\"/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<SyntaxMode Value="Delphi"/>
</SyntaxOptions>
</Parsing>
<CodeGeneration>
<SmartLinkUnit Value="True"/>
<Optimizations>
<OptimizationLevel Value="3"/>
</Optimizations>
</CodeGeneration>
<Linking>
<Debugging>
<GenerateDebugInfo Value="False"/>
<UseExternalDbgSyms Value="True"/>
</Debugging>
</Linking>
<Other>
<CompilerMessages>
<MsgFileName Value=""/>
</CompilerMessages>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
<Description Value=" TPJVersionInfo is a 32 bit non-visual component for all Win32 versions of Delphi that encapsulates the version information contained in an executable file's resources.
The component reads information from a designated file's VERSIONINFO resource. The required file is specified in the component's FileName property. Setting FileName to the empty string fetches version information for the executable file containing the component. The boolean HaveInfo property indicates whether the file contains version information. This component can access variable file information for each language provided in the resource.
Run-time properties enable access to to version information. Properties enable:
Access to fixed file information, either by field or the whole record.
Access to the number of translations stored in the version information.
Selection of the translation for which information is to be returned by other properties.
Access to the language and code page of the current translation by code and by name.
Access to the string file information for the current translation named properties access the Microsoft-defined string information, while an array property gives access to any string item by name.
Version numbers are encapsulated in TPJVersionNumber records which, on Delphi 2006 or later, can be directly assigned to a string and can be compared using the normal equality operators. Helper functions are also provided for use with earlier Delphis that can format version numbers as text and can compare them. "/>
<License Value="This Source Code Form is subject to the terms of the Mozilla Public License"/>
<Version Major="3" Minor="3" Release="1"/>
<Files Count="1">
<Item1>
<Filename Value="PJVersionInfo.pas"/>
<HasRegisterProc Value="True"/>
<UnitName Value="PJVersionInfo"/>
</Item1>
</Files>
<Type Value="RunAndDesignTime"/>
<RequiredPkgs Count="1">
<Item1>
<PackageName Value="FCL"/>
</Item1>
</RequiredPkgs>
<UsageOptions>
<UnitPath Value="$(PkgOutDir)"/>
</UsageOptions>
<PublishOptions>
<Version Value="2"/>
</PublishOptions>
</Package>
</CONFIG>

View File

@ -0,0 +1,21 @@
{ This file was automatically created by Lazarus. Do not edit!
This source is only used to compile and install the package.
}
unit dd_versioninfo;
interface
uses
PJVersionInfo, LazarusPackageIntf;
implementation
procedure Register;
begin
RegisterUnit('PJVersionInfo', @PJVersionInfo.Register);
end;
initialization
RegisterPackage('dd_versioninfo', @Register);
end.

View File

@ -0,0 +1,184 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : CreateZIPDemo1
// * Purpose : Демонстрация создания архива используя различные
// * : варианты добавления данных
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2013.
// * Version : 1.0.10
// * Home Page : http://rouse.drkb.ru
// * Home Blog : http://alexander-bagel.blogspot.ru
// ****************************************************************************
// * Stable Release : http://rouse.drkb.ru/components.php#fwzip
// * Latest Source : https://github.com/AlexanderBagel/FWZip
// ****************************************************************************
//
// Используемые источники:
// ftp://ftp.info-zip.org/pub/infozip/doc/appnote-iz-latest.zip
// http://zlib.net/zlib-1.2.5.tar.gz
// http://www.base2ti.com/
//
// Данный пример показывает различные варианты добавления информации в архив
// Для каждого из способов добавления в архиве будет создана отдельная папка
program CreateZIPDemo1;
{$APPTYPE CONSOLE}
uses
SysUtils,
Classes,
TypInfo, zlib,
FWZipWriter;
procedure CheckResult(Value: Integer);
begin
if Value < 0 then
raise Exception.Create('Ошибка добавления данных');
end;
var
Zip: TFWZipWriter;
S: TStringStream;
PresentFiles: TStringList;
SR: TSearchRec;
I, ItemIndex: Integer;
BuildZipResult: TBuildZipResult;
begin
SetCurrentDir(ExtractFilePath(ParamStr(0)));
try
Zip := TFWZipWriter.Create;
try
// У всего архива включим UTF8 кодировку (если необходимо)
Zip.UseUTF8String := True;
// добавим комментарий по необходимости
Zip.Comment := 'Общий комментарий к архиву';
// Сначала добавим в архив файлы и папки
// не существующие физически на диске
// Создаем и добавляем текстовый файл в корень архива (AddStream)
S := TStringStream.Create('Тестовый текстовый файл №1');
try
S.Position := 0;
ItemIndex := Zip.AddStream('test.txt', S);
CheckResult(ItemIndex);
// Можно добавить коментарий к самому элементу
Zip.Item[ItemIndex].Comment := 'Мой тестовый комментарий';
//TCompressionStream.Create(clDefault, S);
finally
S.Free;
end;
// Для сохранении файла в определенной папке
// достаточно указать ее наличие в пути к файлу, например вот так
S := TStringStream.Create('Тестовый текстовый файл №2');
try
S.Position := 0;
CheckResult(Zip.AddStream(
'AddStreamData\SubFolder1\Subfolder2\Test.txt', S));
finally
S.Free;
end;
// Теперь будут показаны пять вариантов добавления файлов
// физически присутствующих на диске
// Вариант первый:
// добавляем в архив содержимое папки "Create ZIP 2" вызовом
// базоовго метода AddFolder
if Zip.AddFolder('..\Create ZIP 2\') = 0 then
raise Exception.Create('Ошибка добавления данных');
// Вариант второй:
// добавляем содержимое нашей корневой директории в папку AddFolderDemo
// при помощи вызова расширенной функции AddFolder,
// в которой можем указать наименование папки внутри архива и указать
// необходимость добавления подпапок (третий параметр)
if Zip.AddFolder('AddFolderDemo', '..\..\', '*.*', False) = 0 then
raise Exception.Create('Ошибка добавления данных');
// Вариант третий. Используем те-же файлы из корневой директории,
// Только добавлять будем руками при помощи метода AddFile
PresentFiles := TStringList.Create;
try
// Для начала их все найдем
if FindFirst('..\..\*.pas', faAnyFile, SR) = 0 then
try
repeat
if (SR.Name = '.') or (SR.Name = '..') then Continue;
if SR.Attr and faDirectory <> 0 then
Continue
else
PresentFiles.Add(SR.Name);
until FindNext(SR) <> 0;
finally
FindClose(SR);
end;
// Теперь добавим по одному,
// указывая в какой папке и под каким именем их размещать.
for I := 0 to PresentFiles.Count - 1 do
CheckResult(Zip.AddFile('..\..\' + PresentFiles[I],
'AddFile\' + PresentFiles[I]));
// Четвертый вариант - добавление списком при помощи метода AddFiles.
// Каждый элемент списка должен быть сформирован следующим образом:
// "Относительный путь и имя в архиве"="Путь к файлу"
// Т.е. ValueFromIndex указывает на путь к файлу,
// а Names - относительный путь в архиве
// Если не указать относительный путь, то будет браться только имя файла.
for I := 0 to PresentFiles.Count - 1 do
PresentFiles[I] :=
'AddFiles\' + PresentFiles[I] + '=' + '..\..\' + PresentFiles[I];
if Zip.AddFiles(PresentFiles) <> PresentFiles.Count then
raise Exception.Create('Ошибка добавления данных');
finally
PresentFiles.Free;
end;
// И последний вариант, то-же добавление списком,
// только в данный список можно помещать папки. Метод AddFilesAndFolders.
// Файлы помещаются в список по тому-же принципу что и в методе AddFiles.
// Записи для папок формируются по принципу: "Относительный путь в архиве"="Путь к папке"
// Т.е. ValueFromIndex указывает на путь к папке,
// а Names - относительный путь в архиве от корня
// Здесь добавим все файлы и папки из корня проекта
PresentFiles := TStringList.Create;
try
if FindFirst('..\..\*.*', faAnyFile, SR) = 0 then
try
repeat
if (SR.Name = '.') or (SR.Name = '..') then Continue;
PresentFiles.Add('AddFilesAndFolders\' + SR.Name + '=..\..\' + SR.Name);
until FindNext(SR) <> 0;
finally
FindClose(SR);
end;
Zip.AddFilesAndFolders(PresentFiles, True);
finally
PresentFiles.Free;
end;
// Вот собственно и все - осталось создать сам архив...
ForceDirectories('..\DemoResults\');
BuildZipResult := Zip.BuildZip('..\DemoResults\CreateZIPDemo1.zip');
// ... и вывести результат
Writeln(GetEnumName(TypeInfo(TBuildZipResult), Integer(BuildZipResult)));
finally
Zip.Free;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.

View File

@ -0,0 +1,619 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{F600CDA0-59E1-4BAD-8C76-ED197FA14494}</ProjectGuid>
<MainSource>CreateZIPDemo1.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Console</AppType>
<FrameworkType>None</FrameworkType>
<ProjectVersion>14.6</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_S>false</DCC_S>
<DCC_K>false</DCC_K>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;UIDeviceFamily=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;UISupportedInterfaceOrientations=;CFBundleExecutable=;CFBundleResourceSpecification=;LSRequiresIPhoneOS=;CFBundleInfoDictionaryVersion=;CFBundleDevelopmentRegion=</VerInfo_Keys>
<DCC_F>false</DCC_F>
<VerInfo_Locale>1049</VerInfo_Locale>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
<DCC_ImageBase>00400000</DCC_ImageBase>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_DebugInformation>false</DCC_DebugInformation>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">CreateZIPDemo1.dpr</Source>
</Source>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
<VersionInfoKeys Name="CFBundleName"/>
<VersionInfoKeys Name="CFBundleDisplayName"/>
<VersionInfoKeys Name="UIDeviceFamily"/>
<VersionInfoKeys Name="CFBundleIdentifier"/>
<VersionInfoKeys Name="CFBundleVersion"/>
<VersionInfoKeys Name="CFBundlePackageType"/>
<VersionInfoKeys Name="CFBundleSignature"/>
<VersionInfoKeys Name="CFBundleAllowMixedLocalizations"/>
<VersionInfoKeys Name="UISupportedInterfaceOrientations"/>
<VersionInfoKeys Name="CFBundleExecutable"/>
<VersionInfoKeys Name="CFBundleResourceSpecification"/>
<VersionInfoKeys Name="LSRequiresIPhoneOS"/>
<VersionInfoKeys Name="CFBundleInfoDictionaryVersion"/>
<VersionInfoKeys Name="CFBundleDevelopmentRegion"/>
</VersionInfoKeys>
</Delphi.Personality>
<Platforms>
<Platform value="OSX32">False</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>
<!-- EurekaLog First Line
[Exception Log]
EurekaLog Version=6104
Activate=0
Activate Handle=1
Save Log File=1
Foreground Tab=0
Freeze Activate=0
Freeze Timeout=0
SMTP From=eurekalog@email.com
SMTP Host=
SMTP Port=25
SMTP UserID=
SMTP Password=
Append to Log=0
TerminateBtn Operation=2
Errors Number=32
Errors Terminate=3
Email Address=
Email Object=
Email Send Options=0
Output Path=
Encrypt Password=
AutoCloseDialogSecs=0
WebSendMode=0
SupportULR=
HTMLLayout Count=15
HTMLLine0="%U003Chtml%U003E"
HTMLLine1=" %U003Chead%U003E"
HTMLLine2=" %U003C/head%U003E"
HTMLLine3=" %U003Cbody TopMargin=10 LeftMargin=10%U003E"
HTMLLine4=" %U003Ctable width="100%%" border="0"%U003E"
HTMLLine5=" %U003Ctr%U003E"
HTMLLine6=" %U003Ctd nowrap%U003E"
HTMLLine7=" %U003Cfont face="Lucida Console, Courier" size="2"%U003E"
HTMLLine8=" %U003C%%HTML_TAG%%%U003E"
HTMLLine9=" %U003C/font%U003E"
HTMLLine10=" %U003C/td%U003E"
HTMLLine11=" %U003C/tr%U003E"
HTMLLine12=" %U003C/table%U003E"
HTMLLine13=" %U003C/body%U003E"
HTMLLine14="%U003C/html%U003E"
AutoCrashOperation=2
AutoCrashNumber=10
AutoCrashMinutes=1
WebURL=
WebUserID=
WebPassword=
WebPort=0
AttachedFiles=
ProxyURL=
ProxyUser=
ProxyPassword=
ProxyPort=8080
TrakerUser=
TrakerPassword=
TrakerAssignTo=
TrakerProject=
TrakerCategory=
TrakerTrialID=
ZipPassword=
PreBuildEvent=
PostSuccessfulBuildEvent=
PostFailureBuildEvent=
ExceptionDialogType=2
Count=0
EMail Message Line Count=0
loNoDuplicateErrors=0
loAppendReproduceText=0
loDeleteLogAtVersionChange=0
loAddComputerNameInLogFileName=0
loSaveModulesAndProcessesSections=1
loSaveAssemblerAndCPUSections=1
soAppStartDate=1
soAppName=1
soAppVersionNumber=1
soAppParameters=1
soAppCompilationDate=1
soAppUpTime=1
soExcDate=1
soExcAddress=1
soExcModuleName=1
soExcModuleVersion=1
soExcType=1
soExcMessage=1
soExcID=1
soExcCount=1
soExcStatus=1
soExcNote=1
soUserID=1
soUserName=1
soUserEmail=1
soUserPrivileges=1
soUserCompany=1
soActCtlsFormClass=1
soActCtlsFormText=1
soActCtlsControlClass=1
soActCtlsControlText=1
soCmpName=1
soCmpTotalMemory=1
soCmpFreeMemory=1
soCmpTotalDisk=1
soCmpFreeDisk=1
soCmpSysUpTime=1
soCmpProcessor=1
soCmpDisplayMode=1
soCmpDisplayDPI=1
soCmpVideoCard=1
soCmpPrinter=1
soOSType=1
soOSBuildN=1
soOSUpdate=1
soOSLanguage=1
soOSCharset=1
soNetIP=1
soNetSubmask=1
soNetGateway=1
soNetDNS1=1
soNetDNS2=1
soNetDHCP=1
soCustomData=1
sndShowSendDialog=1
sndShowSuccessFailureMsg=0
sndSendEntireLog=0
sndSendXMLLogCopy=0
sndSendScreenshot=1
sndUseOnlyActiveWindow=0
sndSendLastHTMLPage=1
sndSendInSeparatedThread=0
sndAddDateInFileName=0
sndAddComputerNameInFileName=0
edoSendErrorReportChecked=1
edoAttachScreenshotChecked=1
edoShowCopyToClipOption=1
edoShowDetailsButton=1
edoShowInDetailedMode=0
edoShowInTopMostMode=0
edoUseEurekaLogLookAndFeel=0
edoShowSendErrorReportOption=1
edoShowAttachScreenshotOption=1
edoShowCustomButton=0
csoShowDLLs=1
csoShowBPLs=1
csoShowBorlandThreads=1
csoShowWindowsThreads=1
csoDoNotStoreProcNames=0
boPauseBorlandThreads=0
boDoNotPauseMainThread=0
boPauseWindowsThreads=0
boUseMainModuleOptions=1
boCopyLogInCaseOfError=1
boSaveCompressedCopyInCaseOfError=0
boHandleSafeCallExceptions=1
boCallRTLExceptionEvent=0
boCatchHandledExceptions=0
loCatchLeaks=0
loGroupsSonLeaks=1
loHideBorlandLeaks=1
loFreeAllLeaks=1
loCatchLeaksExceptions=1
cfoReduceFileSize=1
cfoCheckFileCorruption=0
cfoUseEL7=0
Count mtInformationMsgCaption=1
mtInformationMsgCaption0="Information."
Count mtQuestionMsgCaption=1
mtQuestionMsgCaption0="Question."
Count mtErrorMsgCaption=1
mtErrorMsgCaption0="Error."
Count mtDialog_Caption=1
mtDialog_Caption0="Error occurred"
Count mtDialog_ErrorMsgCaption=2
mtDialog_ErrorMsgCaption0="An error has occurred during program execution."
mtDialog_ErrorMsgCaption1="Please read the following information for further details."
Count mtDialog_GeneralCaption=1
mtDialog_GeneralCaption0="General"
Count mtDialog_GeneralHeader=1
mtDialog_GeneralHeader0="General Information"
Count mtDialog_CallStackCaption=1
mtDialog_CallStackCaption0="Call Stack"
Count mtDialog_CallStackHeader=1
mtDialog_CallStackHeader0="Call Stack Information"
Count mtDialog_ModulesCaption=1
mtDialog_ModulesCaption0="Modules"
Count mtDialog_ModulesHeader=1
mtDialog_ModulesHeader0="Modules Information"
Count mtDialog_ProcessesCaption=1
mtDialog_ProcessesCaption0="Processes"
Count mtDialog_ProcessesHeader=1
mtDialog_ProcessesHeader0="Processes Information"
Count mtDialog_AsmCaption=1
mtDialog_AsmCaption0="Assembler"
Count mtDialog_AsmHeader=1
mtDialog_AsmHeader0="Assembler Information"
Count mtDialog_CPUCaption=1
mtDialog_CPUCaption0="CPU"
Count mtDialog_CPUHeader=1
mtDialog_CPUHeader0="CPU Information"
Count mtDialog_OKButtonCaption=1
mtDialog_OKButtonCaption0="%U0026OK"
Count mtDialog_TerminateButtonCaption=1
mtDialog_TerminateButtonCaption0="%U0026Terminate"
Count mtDialog_RestartButtonCaption=1
mtDialog_RestartButtonCaption0="%U0026Restart"
Count mtDialog_DetailsButtonCaption=1
mtDialog_DetailsButtonCaption0="%U0026Details"
Count mtDialog_CustomButtonCaption=1
mtDialog_CustomButtonCaption0="%U0026Help"
Count mtDialog_SendMessage=1
mtDialog_SendMessage0="%U0026Send this error via Internet"
Count mtDialog_ScreenshotMessage=1
mtDialog_ScreenshotMessage0="%U0026Attach a Screenshot image"
Count mtDialog_CopyMessage=1
mtDialog_CopyMessage0="%U0026Copy to Clipboard"
Count mtDialog_SupportMessage=1
mtDialog_SupportMessage0="Go to the Support Page"
Count mtMSDialog_ErrorMsgCaption=1
mtMSDialog_ErrorMsgCaption0="The application has encountered a problem. We are sorry for the inconvenience."
Count mtMSDialog_RestartCaption=1
mtMSDialog_RestartCaption0="Restart application."
Count mtMSDialog_TerminateCaption=1
mtMSDialog_TerminateCaption0="Terminate application."
Count mtMSDialog_PleaseCaption=1
mtMSDialog_PleaseCaption0="Please tell us about this problem."
Count mtMSDialog_DescriptionCaption=1
mtMSDialog_DescriptionCaption0="We have created an error report that you can send to us. We will treat this report as confidential and anonymous."
Count mtMSDialog_SeeDetailsCaption=1
mtMSDialog_SeeDetailsCaption0="To see what data the error report contains,"
Count mtMSDialog_SeeClickCaption=1
mtMSDialog_SeeClickCaption0="click here."
Count mtMSDialog_HowToReproduceCaption=1
mtMSDialog_HowToReproduceCaption0="What were you doing when the problem happened (optional)?"
Count mtMSDialog_EmailCaption=1
mtMSDialog_EmailCaption0="Email address (optional):"
Count mtMSDialog_SendButtonCaption=1
mtMSDialog_SendButtonCaption0="%U0026Send Error Report"
Count mtMSDialog_NoSendButtonCaption=1
mtMSDialog_NoSendButtonCaption0="%U0026Don't Send"
Count mtLog_AppHeader=1
mtLog_AppHeader0="Application"
Count mtLog_AppStartDate=1
mtLog_AppStartDate0="Start Date"
Count mtLog_AppName=1
mtLog_AppName0="Name/Description"
Count mtLog_AppVersionNumber=1
mtLog_AppVersionNumber0="Version Number"
Count mtLog_AppParameters=1
mtLog_AppParameters0="Parameters"
Count mtLog_AppCompilationDate=1
mtLog_AppCompilationDate0="Compilation Date"
Count mtLog_AppUpTime=1
mtLog_AppUpTime0="Up Time"
Count mtLog_ExcHeader=1
mtLog_ExcHeader0="Exception"
Count mtLog_ExcDate=1
mtLog_ExcDate0="Date"
Count mtLog_ExcAddress=1
mtLog_ExcAddress0="Address"
Count mtLog_ExcModuleName=1
mtLog_ExcModuleName0="Module Name"
Count mtLog_ExcModuleVersion=1
mtLog_ExcModuleVersion0="Module Version"
Count mtLog_ExcType=1
mtLog_ExcType0="Type"
Count mtLog_ExcMessage=1
mtLog_ExcMessage0="Message"
Count mtLog_ExcID=1
mtLog_ExcID0="ID"
Count mtLog_ExcCount=1
mtLog_ExcCount0="Count"
Count mtLog_ExcStatus=1
mtLog_ExcStatus0="Status"
Count mtLog_ExcNote=1
mtLog_ExcNote0="Note"
Count mtLog_UserHeader=1
mtLog_UserHeader0="User"
Count mtLog_UserID=1
mtLog_UserID0="ID"
Count mtLog_UserName=1
mtLog_UserName0="Name"
Count mtLog_UserEmail=1
mtLog_UserEmail0="Email"
Count mtLog_UserCompany=1
mtLog_UserCompany0="Company"
Count mtLog_UserPrivileges=1
mtLog_UserPrivileges0="Privileges"
Count mtLog_ActCtrlsHeader=1
mtLog_ActCtrlsHeader0="Active Controls"
Count mtLog_ActCtrlsFormClass=1
mtLog_ActCtrlsFormClass0="Form Class"
Count mtLog_ActCtrlsFormText=1
mtLog_ActCtrlsFormText0="Form Text"
Count mtLog_ActCtrlsControlClass=1
mtLog_ActCtrlsControlClass0="Control Class"
Count mtLog_ActCtrlsControlText=1
mtLog_ActCtrlsControlText0="Control Text"
Count mtLog_CmpHeader=1
mtLog_CmpHeader0="Computer"
Count mtLog_CmpName=1
mtLog_CmpName0="Name"
Count mtLog_CmpTotalMemory=1
mtLog_CmpTotalMemory0="Total Memory"
Count mtLog_CmpFreeMemory=1
mtLog_CmpFreeMemory0="Free Memory"
Count mtLog_CmpTotalDisk=1
mtLog_CmpTotalDisk0="Total Disk"
Count mtLog_CmpFreeDisk=1
mtLog_CmpFreeDisk0="Free Disk"
Count mtLog_CmpSystemUpTime=1
mtLog_CmpSystemUpTime0="System Up Time"
Count mtLog_CmpProcessor=1
mtLog_CmpProcessor0="Processor"
Count mtLog_CmpDisplayMode=1
mtLog_CmpDisplayMode0="Display Mode"
Count mtLog_CmpDisplayDPI=1
mtLog_CmpDisplayDPI0="Display DPI"
Count mtLog_CmpVideoCard=1
mtLog_CmpVideoCard0="Video Card"
Count mtLog_CmpPrinter=1
mtLog_CmpPrinter0="Printer"
Count mtLog_OSHeader=1
mtLog_OSHeader0="Operating System"
Count mtLog_OSType=1
mtLog_OSType0="Type"
Count mtLog_OSBuildN=1
mtLog_OSBuildN0="Build #"
Count mtLog_OSUpdate=1
mtLog_OSUpdate0="Update"
Count mtLog_OSLanguage=1
mtLog_OSLanguage0="Language"
Count mtLog_OSCharset=1
mtLog_OSCharset0="Charset"
Count mtLog_NetHeader=1
mtLog_NetHeader0="Network"
Count mtLog_NetIP=1
mtLog_NetIP0="IP Address"
Count mtLog_NetSubmask=1
mtLog_NetSubmask0="Submask"
Count mtLog_NetGateway=1
mtLog_NetGateway0="Gateway"
Count mtLog_NetDNS1=1
mtLog_NetDNS10="DNS 1"
Count mtLog_NetDNS2=1
mtLog_NetDNS20="DNS 2"
Count mtLog_NetDHCP=1
mtLog_NetDHCP0="DHCP"
Count mtLog_CustInfoHeader=1
mtLog_CustInfoHeader0="Custom Information"
Count mtCallStack_Address=1
mtCallStack_Address0="Address"
Count mtCallStack_Name=1
mtCallStack_Name0="Module"
Count mtCallStack_Unit=1
mtCallStack_Unit0="Unit"
Count mtCallStack_Class=1
mtCallStack_Class0="Class"
Count mtCallStack_Procedure=1
mtCallStack_Procedure0="Procedure/Method"
Count mtCallStack_Line=1
mtCallStack_Line0="Line"
Count mtCallStack_MainThread=1
mtCallStack_MainThread0="Main"
Count mtCallStack_ExceptionThread=1
mtCallStack_ExceptionThread0="Exception Thread"
Count mtCallStack_RunningThread=1
mtCallStack_RunningThread0="Running Thread"
Count mtCallStack_CallingThread=1
mtCallStack_CallingThread0="Calling Thread"
Count mtCallStack_ThreadID=1
mtCallStack_ThreadID0="ID"
Count mtCallStack_ThreadPriority=1
mtCallStack_ThreadPriority0="Priority"
Count mtCallStack_ThreadClass=1
mtCallStack_ThreadClass0="Class"
Count mtCallStack_LeakCaption=1
mtCallStack_LeakCaption0="Memory Leak"
Count mtCallStack_LeakData=1
mtCallStack_LeakData0="Data"
Count mtCallStack_LeakType=1
mtCallStack_LeakType0="Type"
Count mtCallStack_LeakSize=1
mtCallStack_LeakSize0="Total size"
Count mtCallStack_LeakCount=1
mtCallStack_LeakCount0="Count"
Count mtSendDialog_Caption=1
mtSendDialog_Caption0="Send."
Count mtSendDialog_Message=1
mtSendDialog_Message0="Message"
Count mtSendDialog_Resolving=1
mtSendDialog_Resolving0="Resolving DNS..."
Count mtSendDialog_Login=1
mtSendDialog_Login0="Login..."
Count mtSendDialog_Connecting=1
mtSendDialog_Connecting0="Connecting with server..."
Count mtSendDialog_Connected=1
mtSendDialog_Connected0="Connected with server."
Count mtSendDialog_Sending=1
mtSendDialog_Sending0="Sending message..."
Count mtSendDialog_Sent=1
mtSendDialog_Sent0="Message sent."
Count mtSendDialog_SelectProject=1
mtSendDialog_SelectProject0="Select project..."
Count mtSendDialog_Searching=1
mtSendDialog_Searching0="Searching..."
Count mtSendDialog_Modifying=1
mtSendDialog_Modifying0="Modifying..."
Count mtSendDialog_Disconnecting=1
mtSendDialog_Disconnecting0="Disconnecting..."
Count mtSendDialog_Disconnected=1
mtSendDialog_Disconnected0="Disconnected."
Count mtReproduceDialog_Caption=1
mtReproduceDialog_Caption0="Request"
Count mtReproduceDialog_Request=1
mtReproduceDialog_Request0="Please describe the steps to reproduce the error:"
Count mtReproduceDialog_OKButtonCaption=1
mtReproduceDialog_OKButtonCaption0="%U0026OK"
Count mtModules_Handle=1
mtModules_Handle0="Handle"
Count mtModules_Name=1
mtModules_Name0="Name"
Count mtModules_Description=1
mtModules_Description0="Description"
Count mtModules_Version=1
mtModules_Version0="Version"
Count mtModules_Size=1
mtModules_Size0="Size"
Count mtModules_LastModified=1
mtModules_LastModified0="Modified"
Count mtModules_Path=1
mtModules_Path0="Path"
Count mtProcesses_ID=1
mtProcesses_ID0="ID"
Count mtProcesses_Name=1
mtProcesses_Name0="Name"
Count mtProcesses_Description=1
mtProcesses_Description0="Description"
Count mtProcesses_Version=1
mtProcesses_Version0="Version"
Count mtProcesses_Memory=1
mtProcesses_Memory0="Memory"
Count mtProcesses_Priority=1
mtProcesses_Priority0="Priority"
Count mtProcesses_Threads=1
mtProcesses_Threads0="Threads"
Count mtProcesses_Path=1
mtProcesses_Path0="Path"
Count mtCPU_Registers=1
mtCPU_Registers0="Registers"
Count mtCPU_Stack=1
mtCPU_Stack0="Stack"
Count mtCPU_MemoryDump=1
mtCPU_MemoryDump0="Memory Dump"
Count mtSend_SuccessMsg=1
mtSend_SuccessMsg0="The message was sent successfully."
Count mtSend_FailureMsg=1
mtSend_FailureMsg0="Sorry, sending the message didn't work."
Count mtSend_BugClosedMsg=2
mtSend_BugClosedMsg0="These BUG is just closed."
mtSend_BugClosedMsg1="Contact the program support to obtain an update."
Count mtSend_UnknownErrorMsg=1
mtSend_UnknownErrorMsg0="Unknown error."
Count mtSend_InvalidLoginMsg=1
mtSend_InvalidLoginMsg0="Invalid login request."
Count mtSend_InvalidSearchMsg=1
mtSend_InvalidSearchMsg0="Invalid search request."
Count mtSend_InvalidSelectionMsg=1
mtSend_InvalidSelectionMsg0="Invalid selection request."
Count mtSend_InvalidInsertMsg=1
mtSend_InvalidInsertMsg0="Invalid insert request."
Count mtSend_InvalidModifyMsg=1
mtSend_InvalidModifyMsg0="Invalid modify request."
Count mtFileCrackedMsg=2
mtFileCrackedMsg0="This file is cracked."
mtFileCrackedMsg1="The application will be closed."
Count mtException_LeakMultiFree=1
mtException_LeakMultiFree0="Multi Free memory leak."
Count mtException_LeakMemoryOverrun=1
mtException_LeakMemoryOverrun0="Memory Overrun leak."
Count mtException_AntiFreeze=1
mtException_AntiFreeze0="The application seems to be frozen."
Count mtInvalidEmailMsg=1
mtInvalidEmailMsg0="Invalid email."
TextsCollection=English
EurekaLog Last Line -->

View File

@ -0,0 +1,81 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : CreateZIPDemo2
// * Purpose : Äåìîíñòðàöèÿ èçìåíåíèÿ äîáàâëåííûõ çàïèñåé
// * Author : Àëåêñàíäð (Rouse_) Áàãåëü
// * Copyright : © Fangorn Wizards Lab 1998 - 2013.
// * Version : 1.0.10
// * Home Page : http://rouse.drkb.ru
// * Home Blog : http://alexander-bagel.blogspot.ru
// ****************************************************************************
// * Stable Release : http://rouse.drkb.ru/components.php#fwzip
// * Latest Source : https://github.com/AlexanderBagel/FWZip
// ****************************************************************************
//
// Èñïîëüçóåìûå èñòî÷íèêè:
// ftp://ftp.info-zip.org/pub/infozip/doc/appnote-iz-latest.zip
// http://zlib.net/zlib-1.2.5.tar.gz
// http://www.base2ti.com/
//
// Äàííûé ïðèìåð ïîêàçûâàåò ðàçëè÷íûå âàðèàíòû èçìåíåíèÿ çàïèñåé
// â åùå íå ñôîðìèðîâàííîì àðõèâå.
program CreateZIPDemo2;
{$APPTYPE CONSOLE}
uses
SysUtils,
TypInfo,
FWZipZLib,
FWZipWriter;
var
Zip: TFWZipWriter;
Item: TFWZipWriterItem;
I: Integer;
BuildZipResult: TBuildZipResult;
begin
SetCurrentDir(ExtractFilePath(ParamStr(0)));
try
Zip := TFWZipWriter.Create;
try
// Äëÿ íà÷àëà äîáàâèì â êîðåíü àðõèâà ôàéëû èç êîðíåâîé äèðåêòîðèè
Zip.AddFolder('..\..\', False);
// Òåïåðü èçìåíèì èì ñâîéñòâà:
for I := 0 to Zip.Count - 1 do
begin
Item := Zip[I];
// Èçìåíèì êîìåíòàðèé
Item.Comment := 'Òåñòîâûé êîìåíòàðèé ê ôàéëó ' + Item.FileName;
// Óñòàíîâèì ïàðîëü
Item.Password := 'password';
// Èçìåíèì òèï ñæàòèÿ
Item.CompressionLevel := TCompressionLevel(Byte(I mod 3));
end;
// Òåïåðü êàæäûé ýëåìåíò àðõèâà èìååò êîìåíòàðèé, çàøèôðîâàí ïàðîëåì è
// èìååò ñîáñòâåííóþ ñòåïåíü ñæàòèÿ â çàâèñèìîñòè îò ñâîåé
// ïîðÿäêîâîé ïîçèöèè â àðõèâå.
// Íó è ñàì àðõèâ òàê-æå èìååò êîìåíòàðèé.
Zip.Comment := 'Òåñòîâûé êîìåíòàðèé êî âñåìó àðõèâó';
// ñîçäàåì àðõèâ è âûâîäèì ðåçóëüòàò
ForceDirectories('..\DemoResults\');
BuildZipResult := Zip.BuildZip('..\DemoResults\CreateZIPDemo2.zip');
// ... è âûâåñòè ðåçóëüòàò
Writeln(GetEnumName(TypeInfo(TBuildZipResult), Integer(BuildZipResult)));
finally
Zip.Free;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.

View File

@ -0,0 +1,619 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{15CDC38C-E807-44D8-BC70-FBEB85865A1B}</ProjectGuid>
<MainSource>CreateZIPDemo2.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Console</AppType>
<FrameworkType>None</FrameworkType>
<ProjectVersion>14.6</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_S>false</DCC_S>
<DCC_K>false</DCC_K>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;UIDeviceFamily=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;UISupportedInterfaceOrientations=;CFBundleExecutable=;CFBundleResourceSpecification=;LSRequiresIPhoneOS=;CFBundleInfoDictionaryVersion=;CFBundleDevelopmentRegion=</VerInfo_Keys>
<DCC_F>false</DCC_F>
<VerInfo_Locale>1049</VerInfo_Locale>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
<DCC_ImageBase>00400000</DCC_ImageBase>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_DebugInformation>false</DCC_DebugInformation>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">CreateZIPDemo2.dpr</Source>
</Source>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
<VersionInfoKeys Name="CFBundleName"/>
<VersionInfoKeys Name="CFBundleDisplayName"/>
<VersionInfoKeys Name="UIDeviceFamily"/>
<VersionInfoKeys Name="CFBundleIdentifier"/>
<VersionInfoKeys Name="CFBundleVersion"/>
<VersionInfoKeys Name="CFBundlePackageType"/>
<VersionInfoKeys Name="CFBundleSignature"/>
<VersionInfoKeys Name="CFBundleAllowMixedLocalizations"/>
<VersionInfoKeys Name="UISupportedInterfaceOrientations"/>
<VersionInfoKeys Name="CFBundleExecutable"/>
<VersionInfoKeys Name="CFBundleResourceSpecification"/>
<VersionInfoKeys Name="LSRequiresIPhoneOS"/>
<VersionInfoKeys Name="CFBundleInfoDictionaryVersion"/>
<VersionInfoKeys Name="CFBundleDevelopmentRegion"/>
</VersionInfoKeys>
</Delphi.Personality>
<Platforms>
<Platform value="OSX32">False</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>
<!-- EurekaLog First Line
[Exception Log]
EurekaLog Version=6104
Activate=0
Activate Handle=1
Save Log File=1
Foreground Tab=0
Freeze Activate=0
Freeze Timeout=0
SMTP From=eurekalog@email.com
SMTP Host=
SMTP Port=25
SMTP UserID=
SMTP Password=
Append to Log=0
TerminateBtn Operation=2
Errors Number=32
Errors Terminate=3
Email Address=
Email Object=
Email Send Options=0
Output Path=
Encrypt Password=
AutoCloseDialogSecs=0
WebSendMode=0
SupportULR=
HTMLLayout Count=15
HTMLLine0="%U003Chtml%U003E"
HTMLLine1=" %U003Chead%U003E"
HTMLLine2=" %U003C/head%U003E"
HTMLLine3=" %U003Cbody TopMargin=10 LeftMargin=10%U003E"
HTMLLine4=" %U003Ctable width="100%%" border="0"%U003E"
HTMLLine5=" %U003Ctr%U003E"
HTMLLine6=" %U003Ctd nowrap%U003E"
HTMLLine7=" %U003Cfont face="Lucida Console, Courier" size="2"%U003E"
HTMLLine8=" %U003C%%HTML_TAG%%%U003E"
HTMLLine9=" %U003C/font%U003E"
HTMLLine10=" %U003C/td%U003E"
HTMLLine11=" %U003C/tr%U003E"
HTMLLine12=" %U003C/table%U003E"
HTMLLine13=" %U003C/body%U003E"
HTMLLine14="%U003C/html%U003E"
AutoCrashOperation=2
AutoCrashNumber=10
AutoCrashMinutes=1
WebURL=
WebUserID=
WebPassword=
WebPort=0
AttachedFiles=
ProxyURL=
ProxyUser=
ProxyPassword=
ProxyPort=8080
TrakerUser=
TrakerPassword=
TrakerAssignTo=
TrakerProject=
TrakerCategory=
TrakerTrialID=
ZipPassword=
PreBuildEvent=
PostSuccessfulBuildEvent=
PostFailureBuildEvent=
ExceptionDialogType=2
Count=0
EMail Message Line Count=0
loNoDuplicateErrors=0
loAppendReproduceText=0
loDeleteLogAtVersionChange=0
loAddComputerNameInLogFileName=0
loSaveModulesAndProcessesSections=1
loSaveAssemblerAndCPUSections=1
soAppStartDate=1
soAppName=1
soAppVersionNumber=1
soAppParameters=1
soAppCompilationDate=1
soAppUpTime=1
soExcDate=1
soExcAddress=1
soExcModuleName=1
soExcModuleVersion=1
soExcType=1
soExcMessage=1
soExcID=1
soExcCount=1
soExcStatus=1
soExcNote=1
soUserID=1
soUserName=1
soUserEmail=1
soUserPrivileges=1
soUserCompany=1
soActCtlsFormClass=1
soActCtlsFormText=1
soActCtlsControlClass=1
soActCtlsControlText=1
soCmpName=1
soCmpTotalMemory=1
soCmpFreeMemory=1
soCmpTotalDisk=1
soCmpFreeDisk=1
soCmpSysUpTime=1
soCmpProcessor=1
soCmpDisplayMode=1
soCmpDisplayDPI=1
soCmpVideoCard=1
soCmpPrinter=1
soOSType=1
soOSBuildN=1
soOSUpdate=1
soOSLanguage=1
soOSCharset=1
soNetIP=1
soNetSubmask=1
soNetGateway=1
soNetDNS1=1
soNetDNS2=1
soNetDHCP=1
soCustomData=1
sndShowSendDialog=1
sndShowSuccessFailureMsg=0
sndSendEntireLog=0
sndSendXMLLogCopy=0
sndSendScreenshot=1
sndUseOnlyActiveWindow=0
sndSendLastHTMLPage=1
sndSendInSeparatedThread=0
sndAddDateInFileName=0
sndAddComputerNameInFileName=0
edoSendErrorReportChecked=1
edoAttachScreenshotChecked=1
edoShowCopyToClipOption=1
edoShowDetailsButton=1
edoShowInDetailedMode=0
edoShowInTopMostMode=0
edoUseEurekaLogLookAndFeel=0
edoShowSendErrorReportOption=1
edoShowAttachScreenshotOption=1
edoShowCustomButton=0
csoShowDLLs=1
csoShowBPLs=1
csoShowBorlandThreads=1
csoShowWindowsThreads=1
csoDoNotStoreProcNames=0
boPauseBorlandThreads=0
boDoNotPauseMainThread=0
boPauseWindowsThreads=0
boUseMainModuleOptions=1
boCopyLogInCaseOfError=1
boSaveCompressedCopyInCaseOfError=0
boHandleSafeCallExceptions=1
boCallRTLExceptionEvent=0
boCatchHandledExceptions=0
loCatchLeaks=0
loGroupsSonLeaks=1
loHideBorlandLeaks=1
loFreeAllLeaks=1
loCatchLeaksExceptions=1
cfoReduceFileSize=1
cfoCheckFileCorruption=0
cfoUseEL7=0
Count mtInformationMsgCaption=1
mtInformationMsgCaption0="Information."
Count mtQuestionMsgCaption=1
mtQuestionMsgCaption0="Question."
Count mtErrorMsgCaption=1
mtErrorMsgCaption0="Error."
Count mtDialog_Caption=1
mtDialog_Caption0="Error occurred"
Count mtDialog_ErrorMsgCaption=2
mtDialog_ErrorMsgCaption0="An error has occurred during program execution."
mtDialog_ErrorMsgCaption1="Please read the following information for further details."
Count mtDialog_GeneralCaption=1
mtDialog_GeneralCaption0="General"
Count mtDialog_GeneralHeader=1
mtDialog_GeneralHeader0="General Information"
Count mtDialog_CallStackCaption=1
mtDialog_CallStackCaption0="Call Stack"
Count mtDialog_CallStackHeader=1
mtDialog_CallStackHeader0="Call Stack Information"
Count mtDialog_ModulesCaption=1
mtDialog_ModulesCaption0="Modules"
Count mtDialog_ModulesHeader=1
mtDialog_ModulesHeader0="Modules Information"
Count mtDialog_ProcessesCaption=1
mtDialog_ProcessesCaption0="Processes"
Count mtDialog_ProcessesHeader=1
mtDialog_ProcessesHeader0="Processes Information"
Count mtDialog_AsmCaption=1
mtDialog_AsmCaption0="Assembler"
Count mtDialog_AsmHeader=1
mtDialog_AsmHeader0="Assembler Information"
Count mtDialog_CPUCaption=1
mtDialog_CPUCaption0="CPU"
Count mtDialog_CPUHeader=1
mtDialog_CPUHeader0="CPU Information"
Count mtDialog_OKButtonCaption=1
mtDialog_OKButtonCaption0="%U0026OK"
Count mtDialog_TerminateButtonCaption=1
mtDialog_TerminateButtonCaption0="%U0026Terminate"
Count mtDialog_RestartButtonCaption=1
mtDialog_RestartButtonCaption0="%U0026Restart"
Count mtDialog_DetailsButtonCaption=1
mtDialog_DetailsButtonCaption0="%U0026Details"
Count mtDialog_CustomButtonCaption=1
mtDialog_CustomButtonCaption0="%U0026Help"
Count mtDialog_SendMessage=1
mtDialog_SendMessage0="%U0026Send this error via Internet"
Count mtDialog_ScreenshotMessage=1
mtDialog_ScreenshotMessage0="%U0026Attach a Screenshot image"
Count mtDialog_CopyMessage=1
mtDialog_CopyMessage0="%U0026Copy to Clipboard"
Count mtDialog_SupportMessage=1
mtDialog_SupportMessage0="Go to the Support Page"
Count mtMSDialog_ErrorMsgCaption=1
mtMSDialog_ErrorMsgCaption0="The application has encountered a problem. We are sorry for the inconvenience."
Count mtMSDialog_RestartCaption=1
mtMSDialog_RestartCaption0="Restart application."
Count mtMSDialog_TerminateCaption=1
mtMSDialog_TerminateCaption0="Terminate application."
Count mtMSDialog_PleaseCaption=1
mtMSDialog_PleaseCaption0="Please tell us about this problem."
Count mtMSDialog_DescriptionCaption=1
mtMSDialog_DescriptionCaption0="We have created an error report that you can send to us. We will treat this report as confidential and anonymous."
Count mtMSDialog_SeeDetailsCaption=1
mtMSDialog_SeeDetailsCaption0="To see what data the error report contains,"
Count mtMSDialog_SeeClickCaption=1
mtMSDialog_SeeClickCaption0="click here."
Count mtMSDialog_HowToReproduceCaption=1
mtMSDialog_HowToReproduceCaption0="What were you doing when the problem happened (optional)?"
Count mtMSDialog_EmailCaption=1
mtMSDialog_EmailCaption0="Email address (optional):"
Count mtMSDialog_SendButtonCaption=1
mtMSDialog_SendButtonCaption0="%U0026Send Error Report"
Count mtMSDialog_NoSendButtonCaption=1
mtMSDialog_NoSendButtonCaption0="%U0026Don't Send"
Count mtLog_AppHeader=1
mtLog_AppHeader0="Application"
Count mtLog_AppStartDate=1
mtLog_AppStartDate0="Start Date"
Count mtLog_AppName=1
mtLog_AppName0="Name/Description"
Count mtLog_AppVersionNumber=1
mtLog_AppVersionNumber0="Version Number"
Count mtLog_AppParameters=1
mtLog_AppParameters0="Parameters"
Count mtLog_AppCompilationDate=1
mtLog_AppCompilationDate0="Compilation Date"
Count mtLog_AppUpTime=1
mtLog_AppUpTime0="Up Time"
Count mtLog_ExcHeader=1
mtLog_ExcHeader0="Exception"
Count mtLog_ExcDate=1
mtLog_ExcDate0="Date"
Count mtLog_ExcAddress=1
mtLog_ExcAddress0="Address"
Count mtLog_ExcModuleName=1
mtLog_ExcModuleName0="Module Name"
Count mtLog_ExcModuleVersion=1
mtLog_ExcModuleVersion0="Module Version"
Count mtLog_ExcType=1
mtLog_ExcType0="Type"
Count mtLog_ExcMessage=1
mtLog_ExcMessage0="Message"
Count mtLog_ExcID=1
mtLog_ExcID0="ID"
Count mtLog_ExcCount=1
mtLog_ExcCount0="Count"
Count mtLog_ExcStatus=1
mtLog_ExcStatus0="Status"
Count mtLog_ExcNote=1
mtLog_ExcNote0="Note"
Count mtLog_UserHeader=1
mtLog_UserHeader0="User"
Count mtLog_UserID=1
mtLog_UserID0="ID"
Count mtLog_UserName=1
mtLog_UserName0="Name"
Count mtLog_UserEmail=1
mtLog_UserEmail0="Email"
Count mtLog_UserCompany=1
mtLog_UserCompany0="Company"
Count mtLog_UserPrivileges=1
mtLog_UserPrivileges0="Privileges"
Count mtLog_ActCtrlsHeader=1
mtLog_ActCtrlsHeader0="Active Controls"
Count mtLog_ActCtrlsFormClass=1
mtLog_ActCtrlsFormClass0="Form Class"
Count mtLog_ActCtrlsFormText=1
mtLog_ActCtrlsFormText0="Form Text"
Count mtLog_ActCtrlsControlClass=1
mtLog_ActCtrlsControlClass0="Control Class"
Count mtLog_ActCtrlsControlText=1
mtLog_ActCtrlsControlText0="Control Text"
Count mtLog_CmpHeader=1
mtLog_CmpHeader0="Computer"
Count mtLog_CmpName=1
mtLog_CmpName0="Name"
Count mtLog_CmpTotalMemory=1
mtLog_CmpTotalMemory0="Total Memory"
Count mtLog_CmpFreeMemory=1
mtLog_CmpFreeMemory0="Free Memory"
Count mtLog_CmpTotalDisk=1
mtLog_CmpTotalDisk0="Total Disk"
Count mtLog_CmpFreeDisk=1
mtLog_CmpFreeDisk0="Free Disk"
Count mtLog_CmpSystemUpTime=1
mtLog_CmpSystemUpTime0="System Up Time"
Count mtLog_CmpProcessor=1
mtLog_CmpProcessor0="Processor"
Count mtLog_CmpDisplayMode=1
mtLog_CmpDisplayMode0="Display Mode"
Count mtLog_CmpDisplayDPI=1
mtLog_CmpDisplayDPI0="Display DPI"
Count mtLog_CmpVideoCard=1
mtLog_CmpVideoCard0="Video Card"
Count mtLog_CmpPrinter=1
mtLog_CmpPrinter0="Printer"
Count mtLog_OSHeader=1
mtLog_OSHeader0="Operating System"
Count mtLog_OSType=1
mtLog_OSType0="Type"
Count mtLog_OSBuildN=1
mtLog_OSBuildN0="Build #"
Count mtLog_OSUpdate=1
mtLog_OSUpdate0="Update"
Count mtLog_OSLanguage=1
mtLog_OSLanguage0="Language"
Count mtLog_OSCharset=1
mtLog_OSCharset0="Charset"
Count mtLog_NetHeader=1
mtLog_NetHeader0="Network"
Count mtLog_NetIP=1
mtLog_NetIP0="IP Address"
Count mtLog_NetSubmask=1
mtLog_NetSubmask0="Submask"
Count mtLog_NetGateway=1
mtLog_NetGateway0="Gateway"
Count mtLog_NetDNS1=1
mtLog_NetDNS10="DNS 1"
Count mtLog_NetDNS2=1
mtLog_NetDNS20="DNS 2"
Count mtLog_NetDHCP=1
mtLog_NetDHCP0="DHCP"
Count mtLog_CustInfoHeader=1
mtLog_CustInfoHeader0="Custom Information"
Count mtCallStack_Address=1
mtCallStack_Address0="Address"
Count mtCallStack_Name=1
mtCallStack_Name0="Module"
Count mtCallStack_Unit=1
mtCallStack_Unit0="Unit"
Count mtCallStack_Class=1
mtCallStack_Class0="Class"
Count mtCallStack_Procedure=1
mtCallStack_Procedure0="Procedure/Method"
Count mtCallStack_Line=1
mtCallStack_Line0="Line"
Count mtCallStack_MainThread=1
mtCallStack_MainThread0="Main"
Count mtCallStack_ExceptionThread=1
mtCallStack_ExceptionThread0="Exception Thread"
Count mtCallStack_RunningThread=1
mtCallStack_RunningThread0="Running Thread"
Count mtCallStack_CallingThread=1
mtCallStack_CallingThread0="Calling Thread"
Count mtCallStack_ThreadID=1
mtCallStack_ThreadID0="ID"
Count mtCallStack_ThreadPriority=1
mtCallStack_ThreadPriority0="Priority"
Count mtCallStack_ThreadClass=1
mtCallStack_ThreadClass0="Class"
Count mtCallStack_LeakCaption=1
mtCallStack_LeakCaption0="Memory Leak"
Count mtCallStack_LeakData=1
mtCallStack_LeakData0="Data"
Count mtCallStack_LeakType=1
mtCallStack_LeakType0="Type"
Count mtCallStack_LeakSize=1
mtCallStack_LeakSize0="Total size"
Count mtCallStack_LeakCount=1
mtCallStack_LeakCount0="Count"
Count mtSendDialog_Caption=1
mtSendDialog_Caption0="Send."
Count mtSendDialog_Message=1
mtSendDialog_Message0="Message"
Count mtSendDialog_Resolving=1
mtSendDialog_Resolving0="Resolving DNS..."
Count mtSendDialog_Login=1
mtSendDialog_Login0="Login..."
Count mtSendDialog_Connecting=1
mtSendDialog_Connecting0="Connecting with server..."
Count mtSendDialog_Connected=1
mtSendDialog_Connected0="Connected with server."
Count mtSendDialog_Sending=1
mtSendDialog_Sending0="Sending message..."
Count mtSendDialog_Sent=1
mtSendDialog_Sent0="Message sent."
Count mtSendDialog_SelectProject=1
mtSendDialog_SelectProject0="Select project..."
Count mtSendDialog_Searching=1
mtSendDialog_Searching0="Searching..."
Count mtSendDialog_Modifying=1
mtSendDialog_Modifying0="Modifying..."
Count mtSendDialog_Disconnecting=1
mtSendDialog_Disconnecting0="Disconnecting..."
Count mtSendDialog_Disconnected=1
mtSendDialog_Disconnected0="Disconnected."
Count mtReproduceDialog_Caption=1
mtReproduceDialog_Caption0="Request"
Count mtReproduceDialog_Request=1
mtReproduceDialog_Request0="Please describe the steps to reproduce the error:"
Count mtReproduceDialog_OKButtonCaption=1
mtReproduceDialog_OKButtonCaption0="%U0026OK"
Count mtModules_Handle=1
mtModules_Handle0="Handle"
Count mtModules_Name=1
mtModules_Name0="Name"
Count mtModules_Description=1
mtModules_Description0="Description"
Count mtModules_Version=1
mtModules_Version0="Version"
Count mtModules_Size=1
mtModules_Size0="Size"
Count mtModules_LastModified=1
mtModules_LastModified0="Modified"
Count mtModules_Path=1
mtModules_Path0="Path"
Count mtProcesses_ID=1
mtProcesses_ID0="ID"
Count mtProcesses_Name=1
mtProcesses_Name0="Name"
Count mtProcesses_Description=1
mtProcesses_Description0="Description"
Count mtProcesses_Version=1
mtProcesses_Version0="Version"
Count mtProcesses_Memory=1
mtProcesses_Memory0="Memory"
Count mtProcesses_Priority=1
mtProcesses_Priority0="Priority"
Count mtProcesses_Threads=1
mtProcesses_Threads0="Threads"
Count mtProcesses_Path=1
mtProcesses_Path0="Path"
Count mtCPU_Registers=1
mtCPU_Registers0="Registers"
Count mtCPU_Stack=1
mtCPU_Stack0="Stack"
Count mtCPU_MemoryDump=1
mtCPU_MemoryDump0="Memory Dump"
Count mtSend_SuccessMsg=1
mtSend_SuccessMsg0="The message was sent successfully."
Count mtSend_FailureMsg=1
mtSend_FailureMsg0="Sorry, sending the message didn't work."
Count mtSend_BugClosedMsg=2
mtSend_BugClosedMsg0="These BUG is just closed."
mtSend_BugClosedMsg1="Contact the program support to obtain an update."
Count mtSend_UnknownErrorMsg=1
mtSend_UnknownErrorMsg0="Unknown error."
Count mtSend_InvalidLoginMsg=1
mtSend_InvalidLoginMsg0="Invalid login request."
Count mtSend_InvalidSearchMsg=1
mtSend_InvalidSearchMsg0="Invalid search request."
Count mtSend_InvalidSelectionMsg=1
mtSend_InvalidSelectionMsg0="Invalid selection request."
Count mtSend_InvalidInsertMsg=1
mtSend_InvalidInsertMsg0="Invalid insert request."
Count mtSend_InvalidModifyMsg=1
mtSend_InvalidModifyMsg0="Invalid modify request."
Count mtFileCrackedMsg=2
mtFileCrackedMsg0="This file is cracked."
mtFileCrackedMsg1="The application will be closed."
Count mtException_LeakMultiFree=1
mtException_LeakMultiFree0="Multi Free memory leak."
Count mtException_LeakMemoryOverrun=1
mtException_LeakMemoryOverrun0="Memory Overrun leak."
Count mtException_AntiFreeze=1
mtException_AntiFreeze0="The application seems to be frozen."
Count mtInvalidEmailMsg=1
mtInvalidEmailMsg0="Invalid email."
TextsCollection=English
EurekaLog Last Line -->

View File

@ -0,0 +1,101 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : ExctractZIPDemo1
// * Purpose : Äåìîíñòðàöèÿ ðàñïàêîâêè àðõèâà.
// * : Èñïîëüçóåòñÿ àðõèâ ñîçäàííûé äåìîïðèëîæåíèåì CreateZIPDemo1
// * Author : Àëåêñàíäð (Rouse_) Áàãåëü
// * Copyright : © Fangorn Wizards Lab 1998 - 2013.
// * Version : 1.0.10
// * Home Page : http://rouse.drkb.ru
// * Home Blog : http://alexander-bagel.blogspot.ru
// ****************************************************************************
// * Stable Release : http://rouse.drkb.ru/components.php#fwzip
// * Latest Source : https://github.com/AlexanderBagel/FWZip
// ****************************************************************************
//
// Èñïîëüçóåìûå èñòî÷íèêè:
// ftp://ftp.info-zip.org/pub/infozip/doc/appnote-iz-latest.zip
// http://zlib.net/zlib-1.2.5.tar.gz
// http://www.base2ti.com/
//
// Äàííûé ïðèìåð ïîêàçûâàåò äâà âàðèàíòà èçâëå÷åíèÿ èíôîðìàöèè èç àðõèâà.
program ExctractZIPDemo1;
{$APPTYPE CONSOLE}
uses
Windows,
Classes,
SysUtils,
TypInfo,
FWZipReader;
function ExtractResultStr(Value: TExtractResult): string;
begin
Result := GetEnumName(TypeInfo(TExtractResult), Integer(Value));
end;
var
Zip: TFWZipReader;
Index: Integer;
S: TStringStream;
OemString: AnsiString;
begin
SetCurrentDir(ExtractFilePath(ParamStr(0)));
try
Zip := TFWZipReader.Create;
try
// Îòêðûâàåì ðàíåå ñîçäàííûé àðõèâ
Zip.LoadFromFile('..\DemoResults\CreateZIPDemo1.zip');
// Ïåðâûé âàðèàíò ðàñïàêîâêè - ðó÷íîé äîñòóï ê êàæäîìó ýëåìåíòó àðõèâà
// Â ïðèìåðå CreateZIPDemo1 ìû ñîçäàëè â êîðíå àðõèâà ôàéë Test.txt
// Íàì íåîáõîäèìî ïîëó÷èòü èíäåêñ ýòîãî ýëåìåíòà â àðõèâå
Index := Zip.GetElementIndex('test.txt');
if Index >= 0 then
begin
// Ðàñïàêîâàòü ìîæíî â ïàìÿòü:
S := TStringStream.Create('');
try
Zip[Index].ExtractToStream(S, '');
// Ôàéë èçâëå÷åí, âûâåäåì åãî ñîäåðæèìîå â îêíî êîíñîëè
{$IFDEF UNICODE}
Writeln(OemString);
{$ELSE}
OemString := AnsiString(S.DataString);
AnsiToOem(PAnsiChar(OemString), PAnsiChar(OemString));
Writeln(OemString);
{$ENDIF}
finally
S.Free;
end;
// Ðàñïàêîâàòü òàê-æå ìîæíî íà äèñê:
Write('Extract "', Zip[Index].FileName, '": ');
Writeln(ExtractResultStr(
Zip[Index].Extract('..\DemoResults\CreateZIPDemo1\ManualExtract\', '')));
end;
// Òàêèì-æå îáðàçîì ìîæíî ïîëó÷èòü ñîäåðæèìîå îñòàëüíûõ ôàéëîâ
// Âòîðîé âàðèàíò ðàñïàêîâêè - àâòîìàòè÷åñêîé ðàñïàêîâêà àðõèâà
// â óêàçàííóþ ïàïêó íà äèñêå
Zip.ExtractAll('..\DemoResults\CreateZIPDemo1\');
// Òðåòèé âàðèàíò ðàñïàêîâêè - àâòîìàòè÷åñêàÿ ðàñïàêîâêà ïî ìàñêå
// (äàííûé êîä ðàñïàêóåò âñå ôàéëû íàõîäÿùèåñÿ â ïàïêå AddFolderDemo àðõèâà)
Zip.ExtractAll('AddFolderDemo*', '..\DemoResults\CreateZIPDemo1\ExtractMasked\');
finally
Zip.Free;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.

View File

@ -0,0 +1,619 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{B06883A2-58D3-4606-BFC2-63551788655E}</ProjectGuid>
<MainSource>ExctractZIPDemo1.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Console</AppType>
<FrameworkType>None</FrameworkType>
<ProjectVersion>14.6</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_S>false</DCC_S>
<DCC_K>false</DCC_K>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;UIDeviceFamily=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;UISupportedInterfaceOrientations=;CFBundleExecutable=;CFBundleResourceSpecification=;LSRequiresIPhoneOS=;CFBundleInfoDictionaryVersion=;CFBundleDevelopmentRegion=</VerInfo_Keys>
<DCC_F>false</DCC_F>
<VerInfo_Locale>1049</VerInfo_Locale>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace)</DCC_Namespace>
<DCC_ImageBase>00400000</DCC_ImageBase>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<DCC_Namespace>System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_DebugInformation>false</DCC_DebugInformation>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">ExctractZIPDemo1.dpr</Source>
</Source>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
<VersionInfoKeys Name="CFBundleName"/>
<VersionInfoKeys Name="CFBundleDisplayName"/>
<VersionInfoKeys Name="UIDeviceFamily"/>
<VersionInfoKeys Name="CFBundleIdentifier"/>
<VersionInfoKeys Name="CFBundleVersion"/>
<VersionInfoKeys Name="CFBundlePackageType"/>
<VersionInfoKeys Name="CFBundleSignature"/>
<VersionInfoKeys Name="CFBundleAllowMixedLocalizations"/>
<VersionInfoKeys Name="UISupportedInterfaceOrientations"/>
<VersionInfoKeys Name="CFBundleExecutable"/>
<VersionInfoKeys Name="CFBundleResourceSpecification"/>
<VersionInfoKeys Name="LSRequiresIPhoneOS"/>
<VersionInfoKeys Name="CFBundleInfoDictionaryVersion"/>
<VersionInfoKeys Name="CFBundleDevelopmentRegion"/>
</VersionInfoKeys>
</Delphi.Personality>
<Platforms>
<Platform value="OSX32">False</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>
<!-- EurekaLog First Line
[Exception Log]
EurekaLog Version=6104
Activate=0
Activate Handle=1
Save Log File=1
Foreground Tab=0
Freeze Activate=0
Freeze Timeout=0
SMTP From=eurekalog@email.com
SMTP Host=
SMTP Port=25
SMTP UserID=
SMTP Password=
Append to Log=0
TerminateBtn Operation=2
Errors Number=32
Errors Terminate=3
Email Address=
Email Object=
Email Send Options=0
Output Path=
Encrypt Password=
AutoCloseDialogSecs=0
WebSendMode=0
SupportULR=
HTMLLayout Count=15
HTMLLine0="%U003Chtml%U003E"
HTMLLine1=" %U003Chead%U003E"
HTMLLine2=" %U003C/head%U003E"
HTMLLine3=" %U003Cbody TopMargin=10 LeftMargin=10%U003E"
HTMLLine4=" %U003Ctable width="100%%" border="0"%U003E"
HTMLLine5=" %U003Ctr%U003E"
HTMLLine6=" %U003Ctd nowrap%U003E"
HTMLLine7=" %U003Cfont face="Lucida Console, Courier" size="2"%U003E"
HTMLLine8=" %U003C%%HTML_TAG%%%U003E"
HTMLLine9=" %U003C/font%U003E"
HTMLLine10=" %U003C/td%U003E"
HTMLLine11=" %U003C/tr%U003E"
HTMLLine12=" %U003C/table%U003E"
HTMLLine13=" %U003C/body%U003E"
HTMLLine14="%U003C/html%U003E"
AutoCrashOperation=2
AutoCrashNumber=10
AutoCrashMinutes=1
WebURL=
WebUserID=
WebPassword=
WebPort=0
AttachedFiles=
ProxyURL=
ProxyUser=
ProxyPassword=
ProxyPort=8080
TrakerUser=
TrakerPassword=
TrakerAssignTo=
TrakerProject=
TrakerCategory=
TrakerTrialID=
ZipPassword=
PreBuildEvent=
PostSuccessfulBuildEvent=
PostFailureBuildEvent=
ExceptionDialogType=2
Count=0
EMail Message Line Count=0
loNoDuplicateErrors=0
loAppendReproduceText=0
loDeleteLogAtVersionChange=0
loAddComputerNameInLogFileName=0
loSaveModulesAndProcessesSections=1
loSaveAssemblerAndCPUSections=1
soAppStartDate=1
soAppName=1
soAppVersionNumber=1
soAppParameters=1
soAppCompilationDate=1
soAppUpTime=1
soExcDate=1
soExcAddress=1
soExcModuleName=1
soExcModuleVersion=1
soExcType=1
soExcMessage=1
soExcID=1
soExcCount=1
soExcStatus=1
soExcNote=1
soUserID=1
soUserName=1
soUserEmail=1
soUserPrivileges=1
soUserCompany=1
soActCtlsFormClass=1
soActCtlsFormText=1
soActCtlsControlClass=1
soActCtlsControlText=1
soCmpName=1
soCmpTotalMemory=1
soCmpFreeMemory=1
soCmpTotalDisk=1
soCmpFreeDisk=1
soCmpSysUpTime=1
soCmpProcessor=1
soCmpDisplayMode=1
soCmpDisplayDPI=1
soCmpVideoCard=1
soCmpPrinter=1
soOSType=1
soOSBuildN=1
soOSUpdate=1
soOSLanguage=1
soOSCharset=1
soNetIP=1
soNetSubmask=1
soNetGateway=1
soNetDNS1=1
soNetDNS2=1
soNetDHCP=1
soCustomData=1
sndShowSendDialog=1
sndShowSuccessFailureMsg=0
sndSendEntireLog=0
sndSendXMLLogCopy=0
sndSendScreenshot=1
sndUseOnlyActiveWindow=0
sndSendLastHTMLPage=1
sndSendInSeparatedThread=0
sndAddDateInFileName=0
sndAddComputerNameInFileName=0
edoSendErrorReportChecked=1
edoAttachScreenshotChecked=1
edoShowCopyToClipOption=1
edoShowDetailsButton=1
edoShowInDetailedMode=0
edoShowInTopMostMode=0
edoUseEurekaLogLookAndFeel=0
edoShowSendErrorReportOption=1
edoShowAttachScreenshotOption=1
edoShowCustomButton=0
csoShowDLLs=1
csoShowBPLs=1
csoShowBorlandThreads=1
csoShowWindowsThreads=1
csoDoNotStoreProcNames=0
boPauseBorlandThreads=0
boDoNotPauseMainThread=0
boPauseWindowsThreads=0
boUseMainModuleOptions=1
boCopyLogInCaseOfError=1
boSaveCompressedCopyInCaseOfError=0
boHandleSafeCallExceptions=1
boCallRTLExceptionEvent=0
boCatchHandledExceptions=0
loCatchLeaks=0
loGroupsSonLeaks=1
loHideBorlandLeaks=1
loFreeAllLeaks=1
loCatchLeaksExceptions=1
cfoReduceFileSize=1
cfoCheckFileCorruption=0
cfoUseEL7=0
Count mtInformationMsgCaption=1
mtInformationMsgCaption0="Information."
Count mtQuestionMsgCaption=1
mtQuestionMsgCaption0="Question."
Count mtErrorMsgCaption=1
mtErrorMsgCaption0="Error."
Count mtDialog_Caption=1
mtDialog_Caption0="Error occurred"
Count mtDialog_ErrorMsgCaption=2
mtDialog_ErrorMsgCaption0="An error has occurred during program execution."
mtDialog_ErrorMsgCaption1="Please read the following information for further details."
Count mtDialog_GeneralCaption=1
mtDialog_GeneralCaption0="General"
Count mtDialog_GeneralHeader=1
mtDialog_GeneralHeader0="General Information"
Count mtDialog_CallStackCaption=1
mtDialog_CallStackCaption0="Call Stack"
Count mtDialog_CallStackHeader=1
mtDialog_CallStackHeader0="Call Stack Information"
Count mtDialog_ModulesCaption=1
mtDialog_ModulesCaption0="Modules"
Count mtDialog_ModulesHeader=1
mtDialog_ModulesHeader0="Modules Information"
Count mtDialog_ProcessesCaption=1
mtDialog_ProcessesCaption0="Processes"
Count mtDialog_ProcessesHeader=1
mtDialog_ProcessesHeader0="Processes Information"
Count mtDialog_AsmCaption=1
mtDialog_AsmCaption0="Assembler"
Count mtDialog_AsmHeader=1
mtDialog_AsmHeader0="Assembler Information"
Count mtDialog_CPUCaption=1
mtDialog_CPUCaption0="CPU"
Count mtDialog_CPUHeader=1
mtDialog_CPUHeader0="CPU Information"
Count mtDialog_OKButtonCaption=1
mtDialog_OKButtonCaption0="%U0026OK"
Count mtDialog_TerminateButtonCaption=1
mtDialog_TerminateButtonCaption0="%U0026Terminate"
Count mtDialog_RestartButtonCaption=1
mtDialog_RestartButtonCaption0="%U0026Restart"
Count mtDialog_DetailsButtonCaption=1
mtDialog_DetailsButtonCaption0="%U0026Details"
Count mtDialog_CustomButtonCaption=1
mtDialog_CustomButtonCaption0="%U0026Help"
Count mtDialog_SendMessage=1
mtDialog_SendMessage0="%U0026Send this error via Internet"
Count mtDialog_ScreenshotMessage=1
mtDialog_ScreenshotMessage0="%U0026Attach a Screenshot image"
Count mtDialog_CopyMessage=1
mtDialog_CopyMessage0="%U0026Copy to Clipboard"
Count mtDialog_SupportMessage=1
mtDialog_SupportMessage0="Go to the Support Page"
Count mtMSDialog_ErrorMsgCaption=1
mtMSDialog_ErrorMsgCaption0="The application has encountered a problem. We are sorry for the inconvenience."
Count mtMSDialog_RestartCaption=1
mtMSDialog_RestartCaption0="Restart application."
Count mtMSDialog_TerminateCaption=1
mtMSDialog_TerminateCaption0="Terminate application."
Count mtMSDialog_PleaseCaption=1
mtMSDialog_PleaseCaption0="Please tell us about this problem."
Count mtMSDialog_DescriptionCaption=1
mtMSDialog_DescriptionCaption0="We have created an error report that you can send to us. We will treat this report as confidential and anonymous."
Count mtMSDialog_SeeDetailsCaption=1
mtMSDialog_SeeDetailsCaption0="To see what data the error report contains,"
Count mtMSDialog_SeeClickCaption=1
mtMSDialog_SeeClickCaption0="click here."
Count mtMSDialog_HowToReproduceCaption=1
mtMSDialog_HowToReproduceCaption0="What were you doing when the problem happened (optional)?"
Count mtMSDialog_EmailCaption=1
mtMSDialog_EmailCaption0="Email address (optional):"
Count mtMSDialog_SendButtonCaption=1
mtMSDialog_SendButtonCaption0="%U0026Send Error Report"
Count mtMSDialog_NoSendButtonCaption=1
mtMSDialog_NoSendButtonCaption0="%U0026Don't Send"
Count mtLog_AppHeader=1
mtLog_AppHeader0="Application"
Count mtLog_AppStartDate=1
mtLog_AppStartDate0="Start Date"
Count mtLog_AppName=1
mtLog_AppName0="Name/Description"
Count mtLog_AppVersionNumber=1
mtLog_AppVersionNumber0="Version Number"
Count mtLog_AppParameters=1
mtLog_AppParameters0="Parameters"
Count mtLog_AppCompilationDate=1
mtLog_AppCompilationDate0="Compilation Date"
Count mtLog_AppUpTime=1
mtLog_AppUpTime0="Up Time"
Count mtLog_ExcHeader=1
mtLog_ExcHeader0="Exception"
Count mtLog_ExcDate=1
mtLog_ExcDate0="Date"
Count mtLog_ExcAddress=1
mtLog_ExcAddress0="Address"
Count mtLog_ExcModuleName=1
mtLog_ExcModuleName0="Module Name"
Count mtLog_ExcModuleVersion=1
mtLog_ExcModuleVersion0="Module Version"
Count mtLog_ExcType=1
mtLog_ExcType0="Type"
Count mtLog_ExcMessage=1
mtLog_ExcMessage0="Message"
Count mtLog_ExcID=1
mtLog_ExcID0="ID"
Count mtLog_ExcCount=1
mtLog_ExcCount0="Count"
Count mtLog_ExcStatus=1
mtLog_ExcStatus0="Status"
Count mtLog_ExcNote=1
mtLog_ExcNote0="Note"
Count mtLog_UserHeader=1
mtLog_UserHeader0="User"
Count mtLog_UserID=1
mtLog_UserID0="ID"
Count mtLog_UserName=1
mtLog_UserName0="Name"
Count mtLog_UserEmail=1
mtLog_UserEmail0="Email"
Count mtLog_UserCompany=1
mtLog_UserCompany0="Company"
Count mtLog_UserPrivileges=1
mtLog_UserPrivileges0="Privileges"
Count mtLog_ActCtrlsHeader=1
mtLog_ActCtrlsHeader0="Active Controls"
Count mtLog_ActCtrlsFormClass=1
mtLog_ActCtrlsFormClass0="Form Class"
Count mtLog_ActCtrlsFormText=1
mtLog_ActCtrlsFormText0="Form Text"
Count mtLog_ActCtrlsControlClass=1
mtLog_ActCtrlsControlClass0="Control Class"
Count mtLog_ActCtrlsControlText=1
mtLog_ActCtrlsControlText0="Control Text"
Count mtLog_CmpHeader=1
mtLog_CmpHeader0="Computer"
Count mtLog_CmpName=1
mtLog_CmpName0="Name"
Count mtLog_CmpTotalMemory=1
mtLog_CmpTotalMemory0="Total Memory"
Count mtLog_CmpFreeMemory=1
mtLog_CmpFreeMemory0="Free Memory"
Count mtLog_CmpTotalDisk=1
mtLog_CmpTotalDisk0="Total Disk"
Count mtLog_CmpFreeDisk=1
mtLog_CmpFreeDisk0="Free Disk"
Count mtLog_CmpSystemUpTime=1
mtLog_CmpSystemUpTime0="System Up Time"
Count mtLog_CmpProcessor=1
mtLog_CmpProcessor0="Processor"
Count mtLog_CmpDisplayMode=1
mtLog_CmpDisplayMode0="Display Mode"
Count mtLog_CmpDisplayDPI=1
mtLog_CmpDisplayDPI0="Display DPI"
Count mtLog_CmpVideoCard=1
mtLog_CmpVideoCard0="Video Card"
Count mtLog_CmpPrinter=1
mtLog_CmpPrinter0="Printer"
Count mtLog_OSHeader=1
mtLog_OSHeader0="Operating System"
Count mtLog_OSType=1
mtLog_OSType0="Type"
Count mtLog_OSBuildN=1
mtLog_OSBuildN0="Build #"
Count mtLog_OSUpdate=1
mtLog_OSUpdate0="Update"
Count mtLog_OSLanguage=1
mtLog_OSLanguage0="Language"
Count mtLog_OSCharset=1
mtLog_OSCharset0="Charset"
Count mtLog_NetHeader=1
mtLog_NetHeader0="Network"
Count mtLog_NetIP=1
mtLog_NetIP0="IP Address"
Count mtLog_NetSubmask=1
mtLog_NetSubmask0="Submask"
Count mtLog_NetGateway=1
mtLog_NetGateway0="Gateway"
Count mtLog_NetDNS1=1
mtLog_NetDNS10="DNS 1"
Count mtLog_NetDNS2=1
mtLog_NetDNS20="DNS 2"
Count mtLog_NetDHCP=1
mtLog_NetDHCP0="DHCP"
Count mtLog_CustInfoHeader=1
mtLog_CustInfoHeader0="Custom Information"
Count mtCallStack_Address=1
mtCallStack_Address0="Address"
Count mtCallStack_Name=1
mtCallStack_Name0="Module"
Count mtCallStack_Unit=1
mtCallStack_Unit0="Unit"
Count mtCallStack_Class=1
mtCallStack_Class0="Class"
Count mtCallStack_Procedure=1
mtCallStack_Procedure0="Procedure/Method"
Count mtCallStack_Line=1
mtCallStack_Line0="Line"
Count mtCallStack_MainThread=1
mtCallStack_MainThread0="Main"
Count mtCallStack_ExceptionThread=1
mtCallStack_ExceptionThread0="Exception Thread"
Count mtCallStack_RunningThread=1
mtCallStack_RunningThread0="Running Thread"
Count mtCallStack_CallingThread=1
mtCallStack_CallingThread0="Calling Thread"
Count mtCallStack_ThreadID=1
mtCallStack_ThreadID0="ID"
Count mtCallStack_ThreadPriority=1
mtCallStack_ThreadPriority0="Priority"
Count mtCallStack_ThreadClass=1
mtCallStack_ThreadClass0="Class"
Count mtCallStack_LeakCaption=1
mtCallStack_LeakCaption0="Memory Leak"
Count mtCallStack_LeakData=1
mtCallStack_LeakData0="Data"
Count mtCallStack_LeakType=1
mtCallStack_LeakType0="Type"
Count mtCallStack_LeakSize=1
mtCallStack_LeakSize0="Total size"
Count mtCallStack_LeakCount=1
mtCallStack_LeakCount0="Count"
Count mtSendDialog_Caption=1
mtSendDialog_Caption0="Send."
Count mtSendDialog_Message=1
mtSendDialog_Message0="Message"
Count mtSendDialog_Resolving=1
mtSendDialog_Resolving0="Resolving DNS..."
Count mtSendDialog_Login=1
mtSendDialog_Login0="Login..."
Count mtSendDialog_Connecting=1
mtSendDialog_Connecting0="Connecting with server..."
Count mtSendDialog_Connected=1
mtSendDialog_Connected0="Connected with server."
Count mtSendDialog_Sending=1
mtSendDialog_Sending0="Sending message..."
Count mtSendDialog_Sent=1
mtSendDialog_Sent0="Message sent."
Count mtSendDialog_SelectProject=1
mtSendDialog_SelectProject0="Select project..."
Count mtSendDialog_Searching=1
mtSendDialog_Searching0="Searching..."
Count mtSendDialog_Modifying=1
mtSendDialog_Modifying0="Modifying..."
Count mtSendDialog_Disconnecting=1
mtSendDialog_Disconnecting0="Disconnecting..."
Count mtSendDialog_Disconnected=1
mtSendDialog_Disconnected0="Disconnected."
Count mtReproduceDialog_Caption=1
mtReproduceDialog_Caption0="Request"
Count mtReproduceDialog_Request=1
mtReproduceDialog_Request0="Please describe the steps to reproduce the error:"
Count mtReproduceDialog_OKButtonCaption=1
mtReproduceDialog_OKButtonCaption0="%U0026OK"
Count mtModules_Handle=1
mtModules_Handle0="Handle"
Count mtModules_Name=1
mtModules_Name0="Name"
Count mtModules_Description=1
mtModules_Description0="Description"
Count mtModules_Version=1
mtModules_Version0="Version"
Count mtModules_Size=1
mtModules_Size0="Size"
Count mtModules_LastModified=1
mtModules_LastModified0="Modified"
Count mtModules_Path=1
mtModules_Path0="Path"
Count mtProcesses_ID=1
mtProcesses_ID0="ID"
Count mtProcesses_Name=1
mtProcesses_Name0="Name"
Count mtProcesses_Description=1
mtProcesses_Description0="Description"
Count mtProcesses_Version=1
mtProcesses_Version0="Version"
Count mtProcesses_Memory=1
mtProcesses_Memory0="Memory"
Count mtProcesses_Priority=1
mtProcesses_Priority0="Priority"
Count mtProcesses_Threads=1
mtProcesses_Threads0="Threads"
Count mtProcesses_Path=1
mtProcesses_Path0="Path"
Count mtCPU_Registers=1
mtCPU_Registers0="Registers"
Count mtCPU_Stack=1
mtCPU_Stack0="Stack"
Count mtCPU_MemoryDump=1
mtCPU_MemoryDump0="Memory Dump"
Count mtSend_SuccessMsg=1
mtSend_SuccessMsg0="The message was sent successfully."
Count mtSend_FailureMsg=1
mtSend_FailureMsg0="Sorry, sending the message didn't work."
Count mtSend_BugClosedMsg=2
mtSend_BugClosedMsg0="These BUG is just closed."
mtSend_BugClosedMsg1="Contact the program support to obtain an update."
Count mtSend_UnknownErrorMsg=1
mtSend_UnknownErrorMsg0="Unknown error."
Count mtSend_InvalidLoginMsg=1
mtSend_InvalidLoginMsg0="Invalid login request."
Count mtSend_InvalidSearchMsg=1
mtSend_InvalidSearchMsg0="Invalid search request."
Count mtSend_InvalidSelectionMsg=1
mtSend_InvalidSelectionMsg0="Invalid selection request."
Count mtSend_InvalidInsertMsg=1
mtSend_InvalidInsertMsg0="Invalid insert request."
Count mtSend_InvalidModifyMsg=1
mtSend_InvalidModifyMsg0="Invalid modify request."
Count mtFileCrackedMsg=2
mtFileCrackedMsg0="This file is cracked."
mtFileCrackedMsg1="The application will be closed."
Count mtException_LeakMultiFree=1
mtException_LeakMultiFree0="Multi Free memory leak."
Count mtException_LeakMemoryOverrun=1
mtException_LeakMemoryOverrun0="Memory Overrun leak."
Count mtException_AntiFreeze=1
mtException_AntiFreeze0="The application seems to be frozen."
Count mtInvalidEmailMsg=1
mtInvalidEmailMsg0="Invalid email."
TextsCollection=English
EurekaLog Last Line -->

View File

@ -0,0 +1,126 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : ExctractZIPDemo2
// * Purpose : Äåìîíñòðàöèÿ ðàñïàêîâêè çàøèôðîâàííîãî àðõèâà.
// * Author : Àëåêñàíäð (Rouse_) Áàãåëü
// * Copyright : © Fangorn Wizards Lab 1998 - 2013.
// * Version : 1.0.10
// * Home Page : http://rouse.drkb.ru
// * Home Blog : http://alexander-bagel.blogspot.ru
// ****************************************************************************
// * Stable Release : http://rouse.drkb.ru/components.php#fwzip
// * Latest Source : https://github.com/AlexanderBagel/FWZip
// ****************************************************************************
//
// Èñïîëüçóåìûå èñòî÷íèêè:
// ftp://ftp.info-zip.org/pub/infozip/doc/appnote-iz-latest.zip
// http://zlib.net/zlib-1.2.5.tar.gz
// http://www.base2ti.com/
//
// Äàííûé ïðèìåð ïîêàçûâàåò ñîçäàíèå è ðàñïàêîâêó çàøèôðîâàííîãî àðõèâà.
// Äëÿ äåìîíñòðàöèè ðàáîòû ñî ñïèñêîì ïàðîëåé ìû ñîçäàäèì àðõèâ,
// â êîòîðîì êàæäîìó ýëåìåíòó íàçíà÷èì ïðîèçâîëüíûé ïàðîëü èç ñïèñêà.
// Ïðè ÷åì êîä èçëå÷åíèÿ äàííûõ íå áóäåò çíàòü êàêîìó ôàéëó
// êàêîé èç ïàðîëåé ñîîòâåòñòâóåò è åñòü ëè ïàðîëü âîîáùå.
program ExctractZIPDemo2;
{$APPTYPE CONSOLE}
uses
SysUtils,
FWZipWriter,
FWZipReader,
FWZipConsts;
const
PasswordList: array [0..3] of string = (
'', 'password1', 'password2', 'password3');
procedure OnPassword(Self, Sender: TObject; const FileName: string;
var Password: string; var CancelExtract: Boolean);
begin
Password := PasswordList[3];
end;
var
Writer: TFWZipWriter;
Reader: TFWZipReader;
Item: TFWZipWriterItem;
I: Integer;
ExtractResult: TExtractResult;
Method: TMethod;
begin
SetCurrentDir(ExtractFilePath(ParamStr(0)));
try
Writer := TFWZipWriter.Create;
try
// Äëÿ íà÷àëà äîáàâèì â êîðåíü àðõèâà ôàéëû èç êîðíåâîé äèðåêòîðèè
Writer.AddFolder('..\..\', False);
// Òåïåðü íàçíà÷èì èì ïàðîëè ñëó÷àéíûì îáðàçîì
Randomize;
// Ó ïåðâîãî ýëåìåíòà ïàðîëü âñåãäà áóäåò ïðèñóòñòâîâàòü (äëÿ äåìîíñòðàöèè)
Item := Writer[0];
Item.Password := PasswordList[Random(3) + 1];
Item.NeedDescriptor := True;
for I := 1 to Writer.Count - 1 do
begin
Item := Writer[I];
// Åñëè èñïîëüçóåòñÿ øèôðîâàíèå æåëàòåëüíî âêëþ÷àòü äåñêðèïòîð ôàéëà
// ñì. Readme.txt
Item.NeedDescriptor := True;
Item.Password := PasswordList[Random(4)];
end;
// Ñîõðàíÿåì ðåçóëüòàò
ForceDirectories('..\DemoResults\');
Writer.BuildZip('..\DemoResults\ExctractZIPDemo2.zip');
finally
Writer.Free;
end;
Reader := TFWZipReader.Create;
try
Reader.LoadFromFile('..\DemoResults\ExctractZIPDemo2.zip');
// Òåïåðü íàøà çàäà÷à èçâëå÷ü äàííûå èç àðõèâà
//  ðó÷íîì ðåæèìå ðàñïàêîâêè ïðèäåòñÿ ïåðåáèðàòü ïàðîëè ñàìîñòîÿòåëüíî
// Íàïðèìåð âîò òàê:
I := 0;
repeat
ExtractResult := Reader[0].Extract(
'..\DemoResults\ExctractZIPDemo2\ManualExtract\', PasswordList[I]);
Inc(I);
until ExtractResult <> erNeedPassword;
// Åñëè ïðåäïîëàãàåòñÿ èñïîëüçîâàòü ðåæèì àâòîìàòè÷åñêîé ðàñïàêîâêè,
// òî óêàçàòü ïàðîëè ìîæíî äâóìÿ ñïîñîáàìè
// 1. ÷åðåç ñïèñîê ïàðîëåé
Reader.PasswordList.Add(PasswordList[1]);
Reader.PasswordList.Add(PasswordList[2]);
// 2. ÷åðåç îáðàáîò÷èê
Method.Code := @OnPassword;
Method.Data := Reader;
Reader.OnPassword := TZipNeedPasswordEvent(Method);
// äëÿ äåìîíñòðàöèè â ñïèñîê ïàðîëåé äîáàâëåíû òîëüêî äâà ïàðîëÿ
// òðåòèé áóäåò ïåðåäàí ÷åðåç îáðàáîò÷èê ñîáûòèÿ OnPassword
Reader.ExtractAll('..\DemoResults\ExctractZIPDemo2\');
finally
Reader.Free;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.

View File

@ -0,0 +1,619 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{307D5F68-F671-4EF6-85EA-CF49C71350C7}</ProjectGuid>
<MainSource>ExctractZIPDemo2.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Console</AppType>
<FrameworkType>None</FrameworkType>
<ProjectVersion>14.6</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_S>false</DCC_S>
<DCC_K>false</DCC_K>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;UIDeviceFamily=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;UISupportedInterfaceOrientations=;CFBundleExecutable=;CFBundleResourceSpecification=;LSRequiresIPhoneOS=;CFBundleInfoDictionaryVersion=;CFBundleDevelopmentRegion=</VerInfo_Keys>
<DCC_F>false</DCC_F>
<VerInfo_Locale>1049</VerInfo_Locale>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
<DCC_ImageBase>00400000</DCC_ImageBase>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_DebugInformation>false</DCC_DebugInformation>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">ExctractZIPDemo2.dpr</Source>
</Source>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
<VersionInfoKeys Name="CFBundleName"/>
<VersionInfoKeys Name="CFBundleDisplayName"/>
<VersionInfoKeys Name="UIDeviceFamily"/>
<VersionInfoKeys Name="CFBundleIdentifier"/>
<VersionInfoKeys Name="CFBundleVersion"/>
<VersionInfoKeys Name="CFBundlePackageType"/>
<VersionInfoKeys Name="CFBundleSignature"/>
<VersionInfoKeys Name="CFBundleAllowMixedLocalizations"/>
<VersionInfoKeys Name="UISupportedInterfaceOrientations"/>
<VersionInfoKeys Name="CFBundleExecutable"/>
<VersionInfoKeys Name="CFBundleResourceSpecification"/>
<VersionInfoKeys Name="LSRequiresIPhoneOS"/>
<VersionInfoKeys Name="CFBundleInfoDictionaryVersion"/>
<VersionInfoKeys Name="CFBundleDevelopmentRegion"/>
</VersionInfoKeys>
</Delphi.Personality>
<Platforms>
<Platform value="OSX32">False</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>
<!-- EurekaLog First Line
[Exception Log]
EurekaLog Version=6104
Activate=0
Activate Handle=1
Save Log File=1
Foreground Tab=0
Freeze Activate=0
Freeze Timeout=0
SMTP From=eurekalog@email.com
SMTP Host=
SMTP Port=25
SMTP UserID=
SMTP Password=
Append to Log=0
TerminateBtn Operation=2
Errors Number=32
Errors Terminate=3
Email Address=
Email Object=
Email Send Options=0
Output Path=
Encrypt Password=
AutoCloseDialogSecs=0
WebSendMode=0
SupportULR=
HTMLLayout Count=15
HTMLLine0="%U003Chtml%U003E"
HTMLLine1=" %U003Chead%U003E"
HTMLLine2=" %U003C/head%U003E"
HTMLLine3=" %U003Cbody TopMargin=10 LeftMargin=10%U003E"
HTMLLine4=" %U003Ctable width="100%%" border="0"%U003E"
HTMLLine5=" %U003Ctr%U003E"
HTMLLine6=" %U003Ctd nowrap%U003E"
HTMLLine7=" %U003Cfont face="Lucida Console, Courier" size="2"%U003E"
HTMLLine8=" %U003C%%HTML_TAG%%%U003E"
HTMLLine9=" %U003C/font%U003E"
HTMLLine10=" %U003C/td%U003E"
HTMLLine11=" %U003C/tr%U003E"
HTMLLine12=" %U003C/table%U003E"
HTMLLine13=" %U003C/body%U003E"
HTMLLine14="%U003C/html%U003E"
AutoCrashOperation=2
AutoCrashNumber=10
AutoCrashMinutes=1
WebURL=
WebUserID=
WebPassword=
WebPort=0
AttachedFiles=
ProxyURL=
ProxyUser=
ProxyPassword=
ProxyPort=8080
TrakerUser=
TrakerPassword=
TrakerAssignTo=
TrakerProject=
TrakerCategory=
TrakerTrialID=
ZipPassword=
PreBuildEvent=
PostSuccessfulBuildEvent=
PostFailureBuildEvent=
ExceptionDialogType=2
Count=0
EMail Message Line Count=0
loNoDuplicateErrors=0
loAppendReproduceText=0
loDeleteLogAtVersionChange=0
loAddComputerNameInLogFileName=0
loSaveModulesAndProcessesSections=1
loSaveAssemblerAndCPUSections=1
soAppStartDate=1
soAppName=1
soAppVersionNumber=1
soAppParameters=1
soAppCompilationDate=1
soAppUpTime=1
soExcDate=1
soExcAddress=1
soExcModuleName=1
soExcModuleVersion=1
soExcType=1
soExcMessage=1
soExcID=1
soExcCount=1
soExcStatus=1
soExcNote=1
soUserID=1
soUserName=1
soUserEmail=1
soUserPrivileges=1
soUserCompany=1
soActCtlsFormClass=1
soActCtlsFormText=1
soActCtlsControlClass=1
soActCtlsControlText=1
soCmpName=1
soCmpTotalMemory=1
soCmpFreeMemory=1
soCmpTotalDisk=1
soCmpFreeDisk=1
soCmpSysUpTime=1
soCmpProcessor=1
soCmpDisplayMode=1
soCmpDisplayDPI=1
soCmpVideoCard=1
soCmpPrinter=1
soOSType=1
soOSBuildN=1
soOSUpdate=1
soOSLanguage=1
soOSCharset=1
soNetIP=1
soNetSubmask=1
soNetGateway=1
soNetDNS1=1
soNetDNS2=1
soNetDHCP=1
soCustomData=1
sndShowSendDialog=1
sndShowSuccessFailureMsg=0
sndSendEntireLog=0
sndSendXMLLogCopy=0
sndSendScreenshot=1
sndUseOnlyActiveWindow=0
sndSendLastHTMLPage=1
sndSendInSeparatedThread=0
sndAddDateInFileName=0
sndAddComputerNameInFileName=0
edoSendErrorReportChecked=1
edoAttachScreenshotChecked=1
edoShowCopyToClipOption=1
edoShowDetailsButton=1
edoShowInDetailedMode=0
edoShowInTopMostMode=0
edoUseEurekaLogLookAndFeel=0
edoShowSendErrorReportOption=1
edoShowAttachScreenshotOption=1
edoShowCustomButton=0
csoShowDLLs=1
csoShowBPLs=1
csoShowBorlandThreads=1
csoShowWindowsThreads=1
csoDoNotStoreProcNames=0
boPauseBorlandThreads=0
boDoNotPauseMainThread=0
boPauseWindowsThreads=0
boUseMainModuleOptions=1
boCopyLogInCaseOfError=1
boSaveCompressedCopyInCaseOfError=0
boHandleSafeCallExceptions=1
boCallRTLExceptionEvent=0
boCatchHandledExceptions=0
loCatchLeaks=0
loGroupsSonLeaks=1
loHideBorlandLeaks=1
loFreeAllLeaks=1
loCatchLeaksExceptions=1
cfoReduceFileSize=1
cfoCheckFileCorruption=0
cfoUseEL7=0
Count mtInformationMsgCaption=1
mtInformationMsgCaption0="Information."
Count mtQuestionMsgCaption=1
mtQuestionMsgCaption0="Question."
Count mtErrorMsgCaption=1
mtErrorMsgCaption0="Error."
Count mtDialog_Caption=1
mtDialog_Caption0="Error occurred"
Count mtDialog_ErrorMsgCaption=2
mtDialog_ErrorMsgCaption0="An error has occurred during program execution."
mtDialog_ErrorMsgCaption1="Please read the following information for further details."
Count mtDialog_GeneralCaption=1
mtDialog_GeneralCaption0="General"
Count mtDialog_GeneralHeader=1
mtDialog_GeneralHeader0="General Information"
Count mtDialog_CallStackCaption=1
mtDialog_CallStackCaption0="Call Stack"
Count mtDialog_CallStackHeader=1
mtDialog_CallStackHeader0="Call Stack Information"
Count mtDialog_ModulesCaption=1
mtDialog_ModulesCaption0="Modules"
Count mtDialog_ModulesHeader=1
mtDialog_ModulesHeader0="Modules Information"
Count mtDialog_ProcessesCaption=1
mtDialog_ProcessesCaption0="Processes"
Count mtDialog_ProcessesHeader=1
mtDialog_ProcessesHeader0="Processes Information"
Count mtDialog_AsmCaption=1
mtDialog_AsmCaption0="Assembler"
Count mtDialog_AsmHeader=1
mtDialog_AsmHeader0="Assembler Information"
Count mtDialog_CPUCaption=1
mtDialog_CPUCaption0="CPU"
Count mtDialog_CPUHeader=1
mtDialog_CPUHeader0="CPU Information"
Count mtDialog_OKButtonCaption=1
mtDialog_OKButtonCaption0="%U0026OK"
Count mtDialog_TerminateButtonCaption=1
mtDialog_TerminateButtonCaption0="%U0026Terminate"
Count mtDialog_RestartButtonCaption=1
mtDialog_RestartButtonCaption0="%U0026Restart"
Count mtDialog_DetailsButtonCaption=1
mtDialog_DetailsButtonCaption0="%U0026Details"
Count mtDialog_CustomButtonCaption=1
mtDialog_CustomButtonCaption0="%U0026Help"
Count mtDialog_SendMessage=1
mtDialog_SendMessage0="%U0026Send this error via Internet"
Count mtDialog_ScreenshotMessage=1
mtDialog_ScreenshotMessage0="%U0026Attach a Screenshot image"
Count mtDialog_CopyMessage=1
mtDialog_CopyMessage0="%U0026Copy to Clipboard"
Count mtDialog_SupportMessage=1
mtDialog_SupportMessage0="Go to the Support Page"
Count mtMSDialog_ErrorMsgCaption=1
mtMSDialog_ErrorMsgCaption0="The application has encountered a problem. We are sorry for the inconvenience."
Count mtMSDialog_RestartCaption=1
mtMSDialog_RestartCaption0="Restart application."
Count mtMSDialog_TerminateCaption=1
mtMSDialog_TerminateCaption0="Terminate application."
Count mtMSDialog_PleaseCaption=1
mtMSDialog_PleaseCaption0="Please tell us about this problem."
Count mtMSDialog_DescriptionCaption=1
mtMSDialog_DescriptionCaption0="We have created an error report that you can send to us. We will treat this report as confidential and anonymous."
Count mtMSDialog_SeeDetailsCaption=1
mtMSDialog_SeeDetailsCaption0="To see what data the error report contains,"
Count mtMSDialog_SeeClickCaption=1
mtMSDialog_SeeClickCaption0="click here."
Count mtMSDialog_HowToReproduceCaption=1
mtMSDialog_HowToReproduceCaption0="What were you doing when the problem happened (optional)?"
Count mtMSDialog_EmailCaption=1
mtMSDialog_EmailCaption0="Email address (optional):"
Count mtMSDialog_SendButtonCaption=1
mtMSDialog_SendButtonCaption0="%U0026Send Error Report"
Count mtMSDialog_NoSendButtonCaption=1
mtMSDialog_NoSendButtonCaption0="%U0026Don't Send"
Count mtLog_AppHeader=1
mtLog_AppHeader0="Application"
Count mtLog_AppStartDate=1
mtLog_AppStartDate0="Start Date"
Count mtLog_AppName=1
mtLog_AppName0="Name/Description"
Count mtLog_AppVersionNumber=1
mtLog_AppVersionNumber0="Version Number"
Count mtLog_AppParameters=1
mtLog_AppParameters0="Parameters"
Count mtLog_AppCompilationDate=1
mtLog_AppCompilationDate0="Compilation Date"
Count mtLog_AppUpTime=1
mtLog_AppUpTime0="Up Time"
Count mtLog_ExcHeader=1
mtLog_ExcHeader0="Exception"
Count mtLog_ExcDate=1
mtLog_ExcDate0="Date"
Count mtLog_ExcAddress=1
mtLog_ExcAddress0="Address"
Count mtLog_ExcModuleName=1
mtLog_ExcModuleName0="Module Name"
Count mtLog_ExcModuleVersion=1
mtLog_ExcModuleVersion0="Module Version"
Count mtLog_ExcType=1
mtLog_ExcType0="Type"
Count mtLog_ExcMessage=1
mtLog_ExcMessage0="Message"
Count mtLog_ExcID=1
mtLog_ExcID0="ID"
Count mtLog_ExcCount=1
mtLog_ExcCount0="Count"
Count mtLog_ExcStatus=1
mtLog_ExcStatus0="Status"
Count mtLog_ExcNote=1
mtLog_ExcNote0="Note"
Count mtLog_UserHeader=1
mtLog_UserHeader0="User"
Count mtLog_UserID=1
mtLog_UserID0="ID"
Count mtLog_UserName=1
mtLog_UserName0="Name"
Count mtLog_UserEmail=1
mtLog_UserEmail0="Email"
Count mtLog_UserCompany=1
mtLog_UserCompany0="Company"
Count mtLog_UserPrivileges=1
mtLog_UserPrivileges0="Privileges"
Count mtLog_ActCtrlsHeader=1
mtLog_ActCtrlsHeader0="Active Controls"
Count mtLog_ActCtrlsFormClass=1
mtLog_ActCtrlsFormClass0="Form Class"
Count mtLog_ActCtrlsFormText=1
mtLog_ActCtrlsFormText0="Form Text"
Count mtLog_ActCtrlsControlClass=1
mtLog_ActCtrlsControlClass0="Control Class"
Count mtLog_ActCtrlsControlText=1
mtLog_ActCtrlsControlText0="Control Text"
Count mtLog_CmpHeader=1
mtLog_CmpHeader0="Computer"
Count mtLog_CmpName=1
mtLog_CmpName0="Name"
Count mtLog_CmpTotalMemory=1
mtLog_CmpTotalMemory0="Total Memory"
Count mtLog_CmpFreeMemory=1
mtLog_CmpFreeMemory0="Free Memory"
Count mtLog_CmpTotalDisk=1
mtLog_CmpTotalDisk0="Total Disk"
Count mtLog_CmpFreeDisk=1
mtLog_CmpFreeDisk0="Free Disk"
Count mtLog_CmpSystemUpTime=1
mtLog_CmpSystemUpTime0="System Up Time"
Count mtLog_CmpProcessor=1
mtLog_CmpProcessor0="Processor"
Count mtLog_CmpDisplayMode=1
mtLog_CmpDisplayMode0="Display Mode"
Count mtLog_CmpDisplayDPI=1
mtLog_CmpDisplayDPI0="Display DPI"
Count mtLog_CmpVideoCard=1
mtLog_CmpVideoCard0="Video Card"
Count mtLog_CmpPrinter=1
mtLog_CmpPrinter0="Printer"
Count mtLog_OSHeader=1
mtLog_OSHeader0="Operating System"
Count mtLog_OSType=1
mtLog_OSType0="Type"
Count mtLog_OSBuildN=1
mtLog_OSBuildN0="Build #"
Count mtLog_OSUpdate=1
mtLog_OSUpdate0="Update"
Count mtLog_OSLanguage=1
mtLog_OSLanguage0="Language"
Count mtLog_OSCharset=1
mtLog_OSCharset0="Charset"
Count mtLog_NetHeader=1
mtLog_NetHeader0="Network"
Count mtLog_NetIP=1
mtLog_NetIP0="IP Address"
Count mtLog_NetSubmask=1
mtLog_NetSubmask0="Submask"
Count mtLog_NetGateway=1
mtLog_NetGateway0="Gateway"
Count mtLog_NetDNS1=1
mtLog_NetDNS10="DNS 1"
Count mtLog_NetDNS2=1
mtLog_NetDNS20="DNS 2"
Count mtLog_NetDHCP=1
mtLog_NetDHCP0="DHCP"
Count mtLog_CustInfoHeader=1
mtLog_CustInfoHeader0="Custom Information"
Count mtCallStack_Address=1
mtCallStack_Address0="Address"
Count mtCallStack_Name=1
mtCallStack_Name0="Module"
Count mtCallStack_Unit=1
mtCallStack_Unit0="Unit"
Count mtCallStack_Class=1
mtCallStack_Class0="Class"
Count mtCallStack_Procedure=1
mtCallStack_Procedure0="Procedure/Method"
Count mtCallStack_Line=1
mtCallStack_Line0="Line"
Count mtCallStack_MainThread=1
mtCallStack_MainThread0="Main"
Count mtCallStack_ExceptionThread=1
mtCallStack_ExceptionThread0="Exception Thread"
Count mtCallStack_RunningThread=1
mtCallStack_RunningThread0="Running Thread"
Count mtCallStack_CallingThread=1
mtCallStack_CallingThread0="Calling Thread"
Count mtCallStack_ThreadID=1
mtCallStack_ThreadID0="ID"
Count mtCallStack_ThreadPriority=1
mtCallStack_ThreadPriority0="Priority"
Count mtCallStack_ThreadClass=1
mtCallStack_ThreadClass0="Class"
Count mtCallStack_LeakCaption=1
mtCallStack_LeakCaption0="Memory Leak"
Count mtCallStack_LeakData=1
mtCallStack_LeakData0="Data"
Count mtCallStack_LeakType=1
mtCallStack_LeakType0="Type"
Count mtCallStack_LeakSize=1
mtCallStack_LeakSize0="Total size"
Count mtCallStack_LeakCount=1
mtCallStack_LeakCount0="Count"
Count mtSendDialog_Caption=1
mtSendDialog_Caption0="Send."
Count mtSendDialog_Message=1
mtSendDialog_Message0="Message"
Count mtSendDialog_Resolving=1
mtSendDialog_Resolving0="Resolving DNS..."
Count mtSendDialog_Login=1
mtSendDialog_Login0="Login..."
Count mtSendDialog_Connecting=1
mtSendDialog_Connecting0="Connecting with server..."
Count mtSendDialog_Connected=1
mtSendDialog_Connected0="Connected with server."
Count mtSendDialog_Sending=1
mtSendDialog_Sending0="Sending message..."
Count mtSendDialog_Sent=1
mtSendDialog_Sent0="Message sent."
Count mtSendDialog_SelectProject=1
mtSendDialog_SelectProject0="Select project..."
Count mtSendDialog_Searching=1
mtSendDialog_Searching0="Searching..."
Count mtSendDialog_Modifying=1
mtSendDialog_Modifying0="Modifying..."
Count mtSendDialog_Disconnecting=1
mtSendDialog_Disconnecting0="Disconnecting..."
Count mtSendDialog_Disconnected=1
mtSendDialog_Disconnected0="Disconnected."
Count mtReproduceDialog_Caption=1
mtReproduceDialog_Caption0="Request"
Count mtReproduceDialog_Request=1
mtReproduceDialog_Request0="Please describe the steps to reproduce the error:"
Count mtReproduceDialog_OKButtonCaption=1
mtReproduceDialog_OKButtonCaption0="%U0026OK"
Count mtModules_Handle=1
mtModules_Handle0="Handle"
Count mtModules_Name=1
mtModules_Name0="Name"
Count mtModules_Description=1
mtModules_Description0="Description"
Count mtModules_Version=1
mtModules_Version0="Version"
Count mtModules_Size=1
mtModules_Size0="Size"
Count mtModules_LastModified=1
mtModules_LastModified0="Modified"
Count mtModules_Path=1
mtModules_Path0="Path"
Count mtProcesses_ID=1
mtProcesses_ID0="ID"
Count mtProcesses_Name=1
mtProcesses_Name0="Name"
Count mtProcesses_Description=1
mtProcesses_Description0="Description"
Count mtProcesses_Version=1
mtProcesses_Version0="Version"
Count mtProcesses_Memory=1
mtProcesses_Memory0="Memory"
Count mtProcesses_Priority=1
mtProcesses_Priority0="Priority"
Count mtProcesses_Threads=1
mtProcesses_Threads0="Threads"
Count mtProcesses_Path=1
mtProcesses_Path0="Path"
Count mtCPU_Registers=1
mtCPU_Registers0="Registers"
Count mtCPU_Stack=1
mtCPU_Stack0="Stack"
Count mtCPU_MemoryDump=1
mtCPU_MemoryDump0="Memory Dump"
Count mtSend_SuccessMsg=1
mtSend_SuccessMsg0="The message was sent successfully."
Count mtSend_FailureMsg=1
mtSend_FailureMsg0="Sorry, sending the message didn't work."
Count mtSend_BugClosedMsg=2
mtSend_BugClosedMsg0="These BUG is just closed."
mtSend_BugClosedMsg1="Contact the program support to obtain an update."
Count mtSend_UnknownErrorMsg=1
mtSend_UnknownErrorMsg0="Unknown error."
Count mtSend_InvalidLoginMsg=1
mtSend_InvalidLoginMsg0="Invalid login request."
Count mtSend_InvalidSearchMsg=1
mtSend_InvalidSearchMsg0="Invalid search request."
Count mtSend_InvalidSelectionMsg=1
mtSend_InvalidSelectionMsg0="Invalid selection request."
Count mtSend_InvalidInsertMsg=1
mtSend_InvalidInsertMsg0="Invalid insert request."
Count mtSend_InvalidModifyMsg=1
mtSend_InvalidModifyMsg0="Invalid modify request."
Count mtFileCrackedMsg=2
mtFileCrackedMsg0="This file is cracked."
mtFileCrackedMsg1="The application will be closed."
Count mtException_LeakMultiFree=1
mtException_LeakMultiFree0="Multi Free memory leak."
Count mtException_LeakMemoryOverrun=1
mtException_LeakMemoryOverrun0="Memory Overrun leak."
Count mtException_AntiFreeze=1
mtException_AntiFreeze0="The application seems to be frozen."
Count mtInvalidEmailMsg=1
mtInvalidEmailMsg0="Invalid email."
TextsCollection=English
EurekaLog Last Line -->

View File

@ -0,0 +1,46 @@
#------------------------------------------------------------------------------
VERSION = BWS.01
#------------------------------------------------------------------------------
!ifndef ROOT
ROOT = $(MAKEDIR)\..
!endif
#------------------------------------------------------------------------------
MAKE = $(ROOT)\bin\make.exe -$(MAKEFLAGS) -f$**
DCC = $(ROOT)\bin\dcc32.exe $**
BRCC = $(ROOT)\bin\brcc32.exe $**
#------------------------------------------------------------------------------
PROJECTS = CreateZIPDemo1.exe CreateZIPDemo2.exe ExctractZIPDemo1.exe \
ExctractZIPDemo2.exe FWZipPerfomance.exe BuildWithException.exe \
UseExDataBlob.exe ZipAnalizer.exe ZipAnalizer2.exe
#------------------------------------------------------------------------------
default: $(PROJECTS)
#------------------------------------------------------------------------------
CreateZIPDemo1.exe: Create ZIP 1\CreateZIPDemo1.dpr
$(DCC)
CreateZIPDemo2.exe: Create ZIP 2\CreateZIPDemo2.dpr
$(DCC)
ExctractZIPDemo1.exe: Extract ZIP 1\ExctractZIPDemo1.dpr
$(DCC)
ExctractZIPDemo2.exe: Extract ZIP 2\ExctractZIPDemo2.dpr
$(DCC)
FWZipPerfomance.exe: PerfomanceTest\FWZipPerfomance.dpr
$(DCC)
BuildWithException.exe: Test Build With Exception\BuildWithException.dpr
$(DCC)
UseExDataBlob.exe: Use ZIP ExData\UseExDataBlob.dpr
$(DCC)
ZipAnalizer.exe: ZipAnalizer\ZipAnalizer.dpr
$(DCC)
ZipAnalizer2.exe: ZipAnalizer2\ZipAnalizer2.dpr
$(DCC)

View File

@ -0,0 +1,132 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{DEBDAF2E-104F-436D-8AFC-8BAC60505E64}</ProjectGuid>
</PropertyGroup>
<ItemGroup>
<Projects Include="Create ZIP 1\CreateZIPDemo1.dproj">
<Dependencies/>
</Projects>
<Projects Include="Create ZIP 2\CreateZIPDemo2.dproj">
<Dependencies/>
</Projects>
<Projects Include="Extract ZIP 1\ExctractZIPDemo1.dproj">
<Dependencies/>
</Projects>
<Projects Include="Extract ZIP 2\ExctractZIPDemo2.dproj">
<Dependencies/>
</Projects>
<Projects Include="PerfomanceTest\FWZipPerfomance.dproj">
<Dependencies/>
</Projects>
<Projects Include="Test Build With Exception\BuildWithException.dproj">
<Dependencies/>
</Projects>
<Projects Include="Use ZIP ExData\UseExDataBlob.dproj">
<Dependencies/>
</Projects>
<Projects Include="ZipAnalizer\ZipAnalizer.dproj">
<Dependencies/>
</Projects>
<Projects Include="ZipAnalizer2\ZipAnalizer2.dproj">
<Dependencies/>
</Projects>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Default.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Default.Personality/>
</BorlandProject>
</ProjectExtensions>
<Target Name="CreateZIPDemo1">
<MSBuild Projects="Create ZIP 1\CreateZIPDemo1.dproj"/>
</Target>
<Target Name="CreateZIPDemo1:Clean">
<MSBuild Projects="Create ZIP 1\CreateZIPDemo1.dproj" Targets="Clean"/>
</Target>
<Target Name="CreateZIPDemo1:Make">
<MSBuild Projects="Create ZIP 1\CreateZIPDemo1.dproj" Targets="Make"/>
</Target>
<Target Name="CreateZIPDemo2">
<MSBuild Projects="Create ZIP 2\CreateZIPDemo2.dproj"/>
</Target>
<Target Name="CreateZIPDemo2:Clean">
<MSBuild Projects="Create ZIP 2\CreateZIPDemo2.dproj" Targets="Clean"/>
</Target>
<Target Name="CreateZIPDemo2:Make">
<MSBuild Projects="Create ZIP 2\CreateZIPDemo2.dproj" Targets="Make"/>
</Target>
<Target Name="ExctractZIPDemo1">
<MSBuild Projects="Extract ZIP 1\ExctractZIPDemo1.dproj"/>
</Target>
<Target Name="ExctractZIPDemo1:Clean">
<MSBuild Projects="Extract ZIP 1\ExctractZIPDemo1.dproj" Targets="Clean"/>
</Target>
<Target Name="ExctractZIPDemo1:Make">
<MSBuild Projects="Extract ZIP 1\ExctractZIPDemo1.dproj" Targets="Make"/>
</Target>
<Target Name="ExctractZIPDemo2">
<MSBuild Projects="Extract ZIP 2\ExctractZIPDemo2.dproj"/>
</Target>
<Target Name="ExctractZIPDemo2:Clean">
<MSBuild Projects="Extract ZIP 2\ExctractZIPDemo2.dproj" Targets="Clean"/>
</Target>
<Target Name="ExctractZIPDemo2:Make">
<MSBuild Projects="Extract ZIP 2\ExctractZIPDemo2.dproj" Targets="Make"/>
</Target>
<Target Name="FWZipPerfomance">
<MSBuild Projects="PerfomanceTest\FWZipPerfomance.dproj"/>
</Target>
<Target Name="FWZipPerfomance:Clean">
<MSBuild Projects="PerfomanceTest\FWZipPerfomance.dproj" Targets="Clean"/>
</Target>
<Target Name="FWZipPerfomance:Make">
<MSBuild Projects="PerfomanceTest\FWZipPerfomance.dproj" Targets="Make"/>
</Target>
<Target Name="BuildWithException">
<MSBuild Projects="Test Build With Exception\BuildWithException.dproj"/>
</Target>
<Target Name="BuildWithException:Clean">
<MSBuild Projects="Test Build With Exception\BuildWithException.dproj" Targets="Clean"/>
</Target>
<Target Name="BuildWithException:Make">
<MSBuild Projects="Test Build With Exception\BuildWithException.dproj" Targets="Make"/>
</Target>
<Target Name="UseExDataBlob">
<MSBuild Projects="Use ZIP ExData\UseExDataBlob.dproj"/>
</Target>
<Target Name="UseExDataBlob:Clean">
<MSBuild Projects="Use ZIP ExData\UseExDataBlob.dproj" Targets="Clean"/>
</Target>
<Target Name="UseExDataBlob:Make">
<MSBuild Projects="Use ZIP ExData\UseExDataBlob.dproj" Targets="Make"/>
</Target>
<Target Name="ZipAnalizer">
<MSBuild Projects="ZipAnalizer\ZipAnalizer.dproj"/>
</Target>
<Target Name="ZipAnalizer:Clean">
<MSBuild Projects="ZipAnalizer\ZipAnalizer.dproj" Targets="Clean"/>
</Target>
<Target Name="ZipAnalizer:Make">
<MSBuild Projects="ZipAnalizer\ZipAnalizer.dproj" Targets="Make"/>
</Target>
<Target Name="ZipAnalizer2">
<MSBuild Projects="ZipAnalizer2\ZipAnalizer2.dproj"/>
</Target>
<Target Name="ZipAnalizer2:Clean">
<MSBuild Projects="ZipAnalizer2\ZipAnalizer2.dproj" Targets="Clean"/>
</Target>
<Target Name="ZipAnalizer2:Make">
<MSBuild Projects="ZipAnalizer2\ZipAnalizer2.dproj" Targets="Make"/>
</Target>
<Target Name="Build">
<CallTarget Targets="CreateZIPDemo1;CreateZIPDemo2;ExctractZIPDemo1;ExctractZIPDemo2;FWZipPerfomance;BuildWithException;UseExDataBlob;ZipAnalizer;ZipAnalizer2"/>
</Target>
<Target Name="Clean">
<CallTarget Targets="CreateZIPDemo1:Clean;CreateZIPDemo2:Clean;ExctractZIPDemo1:Clean;ExctractZIPDemo2:Clean;FWZipPerfomance:Clean;BuildWithException:Clean;UseExDataBlob:Clean;ZipAnalizer:Clean;ZipAnalizer2:Clean"/>
</Target>
<Target Name="Make">
<CallTarget Targets="CreateZIPDemo1:Make;CreateZIPDemo2:Make;ExctractZIPDemo1:Make;ExctractZIPDemo2:Make;FWZipPerfomance:Make;BuildWithException:Make;UseExDataBlob:Make;ZipAnalizer:Make;ZipAnalizer2:Make"/>
</Target>
<Import Project="$(BDS)\Bin\CodeGear.Group.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Group.Targets')"/>
</Project>

View File

@ -0,0 +1,174 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{BEF6069D-A5FD-48FE-A930-0CE57B83DC93}</ProjectGuid>
<MainSource>FWZipPerfomance.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>3</TargetedPlatforms>
<AppType>Application</AppType>
<FrameworkType>VCL</FrameworkType>
<ProjectVersion>14.6</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win64</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
<Base_Win64>true</Base_Win64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_N>false</DCC_N>
<DCC_ImageBase>00400000</DCC_ImageBase>
<DCC_E>false</DCC_E>
<VerInfo_Locale>1049</VerInfo_Locale>
<DCC_Namespace>Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace)</DCC_Namespace>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;UIDeviceFamily=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;UISupportedInterfaceOrientations=;CFBundleExecutable=;CFBundleResourceSpecification=;LSRequiresIPhoneOS=;CFBundleInfoDictionaryVersion=;CFBundleDevelopmentRegion=</VerInfo_Keys>
<DCC_S>false</DCC_S>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_Namespace>System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Locale>1033</VerInfo_Locale>
<Icon_MainIcon>FWZipPerfomance_Icon.ico</Icon_MainIcon>
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<DCC_Namespace>System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
<Icon_MainIcon>FWZipPerfomance_Icon.ico</Icon_MainIcon>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_DebugInformation>false</DCC_DebugInformation>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Locale>1033</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<DCC_DebugDCUs>true</DCC_DebugDCUs>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="Unit1.pas">
<Form>Form1</Form>
</DCCReference>
<DCCReference Include="..\..\FWZipConsts.pas"/>
<DCCReference Include="..\..\FWZipCrc32.pas"/>
<DCCReference Include="..\..\FWZipCrypt.pas"/>
<DCCReference Include="..\..\FWZipReader.pas"/>
<DCCReference Include="..\..\FWZipStream.pas"/>
<DCCReference Include="..\..\FWZipWriter.pas"/>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">FWZipPerfomance.dpr</Source>
</Source>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
<VersionInfoKeys Name="CFBundleName"/>
<VersionInfoKeys Name="CFBundleDisplayName"/>
<VersionInfoKeys Name="UIDeviceFamily"/>
<VersionInfoKeys Name="CFBundleIdentifier"/>
<VersionInfoKeys Name="CFBundleVersion"/>
<VersionInfoKeys Name="CFBundlePackageType"/>
<VersionInfoKeys Name="CFBundleSignature"/>
<VersionInfoKeys Name="CFBundleAllowMixedLocalizations"/>
<VersionInfoKeys Name="UISupportedInterfaceOrientations"/>
<VersionInfoKeys Name="CFBundleExecutable"/>
<VersionInfoKeys Name="CFBundleResourceSpecification"/>
<VersionInfoKeys Name="LSRequiresIPhoneOS"/>
<VersionInfoKeys Name="CFBundleInfoDictionaryVersion"/>
<VersionInfoKeys Name="CFBundleDevelopmentRegion"/>
</VersionInfoKeys>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k180.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp180.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
</Delphi.Personality>
<Platforms>
<Platform value="Win32">True</Platform>
<Platform value="Win64">True</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>

View File

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="9"/>
<PathDelim Value="\"/>
<General>
<Flags>
<MainUnitHasUsesSectionForAllUnits Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="FWZipPerfomance"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<i18n>
<EnableI18N LFM="False"/>
</i18n>
<VersionInfo>
<StringTable ProductVersion=""/>
</VersionInfo>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
</PublishOptions>
<RunParams>
<local>
<FormatVersion Value="1"/>
</local>
</RunParams>
<RequiredPackages Count="2">
<Item1>
<PackageName Value="fwzip"/>
</Item1>
<Item2>
<PackageName Value="LCL"/>
</Item2>
</RequiredPackages>
<Units Count="2">
<Unit0>
<Filename Value="FWZipPerfomance.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
<Unit1>
<Filename Value="Unit1.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="Form1"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="Unit1"/>
</Unit1>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<IncludeFiles Value="..\.."/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<SyntaxMode Value="delphi"/>
</SyntaxOptions>
</Parsing>
<Linking>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
<Other>
<CompilerMessages>
<MsgFileName Value=""/>
</CompilerMessages>
<CustomOptions Value="-dBorland -dVer150 -dDelphi7 -dCompiler6_Up -dPUREPASCAL"/>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

View File

@ -0,0 +1,13 @@
program FWZipPerfomance;
{$MODE Delphi}
uses
Forms, Interfaces,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,285 @@
object Form1: TForm1
Left = 381
Height = 654
Top = 183
Width = 578
Caption = 'Тест производительности FWZip'
ClientHeight = 654
ClientWidth = 578
Color = clBtnFace
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Position = poScreenCenter
LCLVersion = '1.2.4.0'
object GroupBox1: TGroupBox
Left = 8
Height = 105
Top = 8
Width = 527
Anchors = [akTop, akLeft, akRight]
Caption = 'Настройки сжатия'
ClientHeight = 87
ClientWidth = 523
TabOrder = 0
object LabeledEdit1: TLabeledEdit
Left = 14
Height = 21
Top = 26
Width = 465
Anchors = [akTop, akLeft, akRight]
EditLabel.AnchorSideLeft.Control = LabeledEdit1
EditLabel.AnchorSideRight.Control = LabeledEdit1
EditLabel.AnchorSideRight.Side = asrBottom
EditLabel.AnchorSideBottom.Control = LabeledEdit1
EditLabel.Left = 14
EditLabel.Height = 13
EditLabel.Top = 10
EditLabel.Width = 465
EditLabel.Caption = 'Выберите папку для сжатия:'
EditLabel.ParentColor = False
TabOrder = 0
Text = 'D:\StroyInfo 5'
OnChange = LabeledEdit1Change
end
object Button1: TButton
Left = 485
Height = 25
Hint = 'Обзор...'
Top = 24
Width = 26
Anchors = [akTop, akRight]
Caption = '...'
OnClick = Button1Click
ParentShowHint = False
ShowHint = True
TabOrder = 1
end
object CheckBox1: TCheckBox
Left = 14
Height = 19
Top = 58
Width = 141
Caption = 'Шифровать при сжатии'
OnClick = CheckBox1Click
TabOrder = 2
end
object LabeledEdit2: TLabeledEdit
Left = 262
Height = 21
Top = 56
Width = 168
Anchors = [akTop, akLeft, akRight]
EditLabel.AnchorSideTop.Control = LabeledEdit2
EditLabel.AnchorSideTop.Side = asrCenter
EditLabel.AnchorSideRight.Control = LabeledEdit2
EditLabel.AnchorSideBottom.Control = LabeledEdit2
EditLabel.AnchorSideBottom.Side = asrBottom
EditLabel.Left = 175
EditLabel.Height = 13
EditLabel.Top = 60
EditLabel.Width = 84
EditLabel.Caption = 'Укажите пароль'
EditLabel.ParentColor = False
Enabled = False
LabelPosition = lpLeft
TabOrder = 3
end
object Button2: TButton
Left = 436
Height = 25
Top = 55
Width = 75
Anchors = [akTop, akRight]
Caption = 'Сжать'
OnClick = Button2Click
TabOrder = 4
end
end
object GroupBox2: TGroupBox
Left = 8
Height = 137
Top = 128
Width = 527
Anchors = [akTop, akLeft, akRight]
Caption = 'Настройки распаковки'
ClientHeight = 119
ClientWidth = 523
TabOrder = 1
object LabeledEdit3: TLabeledEdit
Left = 14
Height = 21
Top = 26
Width = 465
Anchors = [akTop, akLeft, akRight]
EditLabel.AnchorSideLeft.Control = LabeledEdit3
EditLabel.AnchorSideRight.Control = LabeledEdit3
EditLabel.AnchorSideRight.Side = asrBottom
EditLabel.AnchorSideBottom.Control = LabeledEdit3
EditLabel.Left = 14
EditLabel.Height = 13
EditLabel.Top = 10
EditLabel.Width = 465
EditLabel.Caption = 'Выберите архив для распаковки:'
EditLabel.ParentColor = False
TabOrder = 0
OnChange = LabeledEdit3Change
end
object Button3: TButton
Left = 485
Height = 25
Hint = 'Обзор...'
Top = 24
Width = 26
Anchors = [akTop, akRight]
Caption = '...'
OnClick = Button3Click
ParentShowHint = False
ShowHint = True
TabOrder = 1
end
object CheckBox2: TCheckBox
Left = 14
Height = 19
Top = 58
Width = 117
Caption = 'Архив зашифрован'
OnClick = CheckBox2Click
TabOrder = 2
end
object LabeledEdit4: TLabeledEdit
Left = 262
Height = 21
Top = 56
Width = 163
Anchors = [akTop, akLeft, akRight]
EditLabel.AnchorSideTop.Control = LabeledEdit4
EditLabel.AnchorSideTop.Side = asrCenter
EditLabel.AnchorSideRight.Control = LabeledEdit4
EditLabel.AnchorSideBottom.Control = LabeledEdit4
EditLabel.AnchorSideBottom.Side = asrBottom
EditLabel.Left = 175
EditLabel.Height = 13
EditLabel.Top = 60
EditLabel.Width = 84
EditLabel.Caption = 'Укажите пароль'
EditLabel.ParentColor = False
Enabled = False
LabelPosition = lpLeft
TabOrder = 3
end
object Button4: TButton
Left = 436
Height = 25
Top = 54
Width = 75
Anchors = [akTop, akRight]
Caption = 'Распаковать'
OnClick = Button4Click
TabOrder = 4
end
object Button6: TButton
Tag = 1
Left = 436
Height = 25
Top = 85
Width = 75
Anchors = [akTop, akRight]
Caption = 'Проверить'
OnClick = Button4Click
TabOrder = 5
end
end
object GroupBox3: TGroupBox
Left = 8
Height = 178
Top = 271
Width = 527
Anchors = [akTop, akLeft, akRight]
Caption = 'Производительность:'
ClientHeight = 160
ClientWidth = 523
TabOrder = 2
object Label1: TLabel
Left = 14
Height = 13
Top = 10
Width = 163
Caption = 'Текущий расход памяти: 0 байт'
ParentColor = False
end
object Label2: TLabel
Left = 14
Height = 13
Top = 29
Width = 163
Caption = 'Пиковый расход памяти: 0 байт'
ParentColor = False
end
object Label3: TLabel
Left = 14
Height = 13
Top = 48
Width = 166
Caption = 'Общее количество элементов: 0'
ParentColor = False
end
object Label4: TLabel
Left = 14
Height = 13
Top = 67
Width = 142
Caption = 'Общее размер элементов: 0'
ParentColor = False
end
object Label5: TLabel
Left = 14
Height = 13
Top = 95
Width = 497
Anchors = [akTop, akLeft, akRight]
AutoSize = False
ParentColor = False
end
object ProgressBar1: TProgressBar
Left = 14
Height = 17
Top = 114
Width = 494
Anchors = [akTop, akLeft, akRight]
TabOrder = 0
end
object ProgressBar2: TProgressBar
Left = 14
Height = 17
Top = 137
Width = 494
Anchors = [akTop, akLeft, akRight]
TabOrder = 1
end
object Button5: TButton
Left = 433
Height = 25
Top = 83
Width = 75
Anchors = [akTop, akRight]
Caption = 'Остановить'
OnClick = Button5Click
TabOrder = 2
Visible = False
end
end
object Memo1: TMemo
Left = 8
Height = 146
Top = 456
Width = 527
Anchors = [akTop, akLeft, akRight, akBottom]
ScrollBars = ssVertical
TabOrder = 3
end
object OpenDialog1: TOpenDialog
left = 376
top = 224
end
end

View File

@ -0,0 +1,300 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip - FWZipPerfomance
// * Purpose : Тестирование производительности FWZip
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2013.
// * Version : 1.0.10
// * Home Page : http://rouse.drkb.ru
// * Home Blog : http://alexander-bagel.blogspot.ru
// ****************************************************************************
// * Stable Release : http://rouse.drkb.ru/components.php#fwzip
// * Latest Source : https://github.com/AlexanderBagel/FWZip
// ****************************************************************************
//
// Используемые источники:
// ftp://ftp.info-zip.org/pub/infozip/doc/appnote-iz-latest.zip
// http://zlib.net/zlib-1.2.5.tar.gz
// http://www.base2ti.com/
//
unit Unit1;
{$MODE Delphi}
interface
{$WARN SYMBOL_PLATFORM OFF}
{$WARN SYMBOL_DEPRECATED OFF}
{$WARN UNIT_PLATFORM OFF}
uses
LCLIntf, LCLType, LMessages, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, FileCtrl, ComCtrls, FileUtil,
FWZipWriter, FWZipReader, FWZipConsts, Contnrs;
type
TForm1 = class(TForm)
GroupBox1: TGroupBox;
LabeledEdit1: TLabeledEdit;
Button1: TButton;
CheckBox1: TCheckBox;
LabeledEdit2: TLabeledEdit;
Button2: TButton;
GroupBox2: TGroupBox;
LabeledEdit3: TLabeledEdit;
Button3: TButton;
CheckBox2: TCheckBox;
LabeledEdit4: TLabeledEdit;
Button4: TButton;
OpenDialog1: TOpenDialog;
GroupBox3: TGroupBox;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
ProgressBar1: TProgressBar;
ProgressBar2: TProgressBar;
Label5: TLabel;
Button5: TButton;
Button6: TButton;
Memo1: TMemo;
procedure CheckBox1Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure LabeledEdit1Change(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure CheckBox2Click(Sender: TObject);
procedure LabeledEdit3Change(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
private
InitialHeapSize, MaxHeapSize, AverageHeapSize: Int64;
TotalGetHeapStatusCount: Integer;
StopProcess: Boolean;
procedure OnProgress(Sender: TObject; const FileName: string;
Percent, TotalPercent: Byte; var Cancel: Boolean;
ProgressState: TProgressState);
procedure UpdateMemoryStatus;
procedure SetEnabledState(Value: Boolean);
procedure ClearZipData;
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
procedure TForm1.Button1Click(Sender: TObject);
var
Dir: string;
begin
if SelectDirectory('Укажите папку для сжатия', '', Dir) then
LabeledEdit1.Text := Dir;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
I: Integer;
TotalSize: Int64;
Heap: THeapStatus;
TicCount: DWORD;
Item: TFWZipWriterItem;
Writer: TFWZipWriter;
begin
Writer := TFWZipWriter.Create;
try
Writer.UseUTF8String:= true;
DeleteFileUTF8(IncludeTrailingPathDelimiter(LabeledEdit1.Text) + 'FWZipTest.zip'); { *Converted from DeleteFile* }
Writer.AddFolder('', LabeledEdit1.Text, '');
TotalSize := 0;
InitialHeapSize := 0;
for I := 0 to Writer.Count - 1 do
begin
Item := Writer[I];
Inc(TotalSize, Item.Size);
Inc(InitialHeapSize, SizeOf(TCentralDirectoryFileHeaderEx));
if LabeledEdit2.Text <> '' then
begin
Item.Password := LabeledEdit2.Text;
Item.NeedDescriptor := True;
end;
end;
Label3.Caption := 'Общее количество элементов: ' + IntToStr(Writer.Count);
Label4.Caption := 'Общий размер элементов: ' + IntToStr(TotalSize);
Writer.OnProgress := OnProgress;
SetEnabledState(False);
try
Heap := GetHeapStatus;
Inc(InitialHeapSize, Heap.Overhead + Heap.TotalAllocated);
MaxHeapSize := 0;
AverageHeapSize := 0;
TotalGetHeapStatusCount := 0;
StopProcess := False;
TicCount := GetTickCount;
Writer.BuildZip(
IncludeTrailingPathDelimiter(LabeledEdit1.Text) + 'FWZipTest.zip');
if TotalGetHeapStatusCount = 0 then
TotalGetHeapStatusCount := 1;
ShowMessage(Format(
'Пиковый расход памяти: %d байт' + sLineBreak +
'Средний расход памяти: %d байт' + sLineBreak +
'Общее время работы: %d секунд',
[MaxHeapSize, AverageHeapSize div TotalGetHeapStatusCount,
(GetTickCount - TicCount) div 1000]));
finally
SetEnabledState(True);
end;
finally
Writer.Free;
ClearZipData;
end;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
if OpenDialog1.Execute then
LabeledEdit3.Text := OpenDialog1.FileName;
end;
procedure TForm1.Button4Click(Sender: TObject);
var
I: Integer;
TotalSize: Int64;
Heap: THeapStatus;
TicCount: DWORD;
Path: string;
Reader: TFWZipReader;
begin
SetLength(Path, MAX_PATH);
Path := LabeledEdit3.Text;
Path := ChangeFileExt(Path, '');
Reader := TFWZipReader.Create;
try
Reader.LoadFromFile(LabeledEdit3.Text);
TotalSize := 0;
for I := 0 to Reader.Count - 1 do
Inc(TotalSize, Reader[I].UncompressedSize);
Label3.Caption := 'Общее количество элементов: ' + IntToStr(Reader.Count);
Label4.Caption := 'Общий размер элементов: ' + IntToStr(TotalSize);
Reader.OnProgress := OnProgress;
if LabeledEdit4.Text <> '' then
Reader.PasswordList.Add(LabeledEdit4.Text);
SetEnabledState(False);
try
Heap := GetHeapStatus;
InitialHeapSize := Heap.Overhead + Heap.TotalAllocated;
MaxHeapSize := 0;
AverageHeapSize := 0;
TotalGetHeapStatusCount := 0;
StopProcess := False;
Memo1.Lines.Clear;
TicCount := GetTickCount;
if TButton(Sender).Tag = 0 then
Reader.ExtractAll(Path)
else
Reader.Check;
if TotalGetHeapStatusCount = 0 then
TotalGetHeapStatusCount := 1;
ShowMessage(Format(
'Пиковый расход памяти: %d байт' + sLineBreak +
'Средний расход памяти: %d байт' + sLineBreak +
'Общее время работы: %d секунд',
[MaxHeapSize, AverageHeapSize div TotalGetHeapStatusCount,
(GetTickCount - TicCount) div 1000]));
finally
SetEnabledState(True);
end;
finally
Reader.Free;
ClearZipData;
end;
end;
procedure TForm1.Button5Click(Sender: TObject);
begin
StopProcess := True;
end;
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
LabeledEdit2.Enabled := CheckBox1.Checked;
end;
procedure TForm1.CheckBox2Click(Sender: TObject);
begin
LabeledEdit4.Enabled := CheckBox2.Checked;
end;
procedure TForm1.ClearZipData;
begin
Label1.Caption := 'Текущий расход памяти: 0 байт';
Label2.Caption := 'Пиковый расход памяти: 0 байт';
Label3.Caption := 'Общее количество элементов: 0';
Label4.Caption := 'Общий размер элементов: 0';
Label5.Caption := '';
end;
procedure TForm1.LabeledEdit1Change(Sender: TObject);
begin
Button2.Enabled := DirectoryExistsUTF8(LabeledEdit1.Text); { *Converted from DirectoryExists* }
end;
procedure TForm1.LabeledEdit3Change(Sender: TObject);
begin
Button4.Enabled := FileExistsUTF8(LabeledEdit3.Text); { *Converted from FileExists* }
end;
procedure TForm1.OnProgress(Sender: TObject; const FileName: string; Percent,
TotalPercent: Byte; var Cancel: Boolean; ProgressState: TProgressState);
const
p: array [TProgressState] of string = ('psStart', 'psInitialization',
'psInProgress', 'psFinalization', 'psEnd', 'psException');
begin
Cancel := StopProcess;
Label5.Caption := Format('(%d) %s', [Percent, FileName]);
ProgressBar1.Position := Percent;
ProgressBar2.Position := TotalPercent;
Memo1.Lines.Add(Format('%s - %s percent %d total %d',
[FileName, P[ProgressState], Percent, TotalPercent]));
UpdateMemoryStatus;
end;
procedure TForm1.SetEnabledState(Value: Boolean);
begin
Button1.Enabled := Value;
Button2.Enabled := Value;
Button3.Enabled := Value;
Button4.Enabled := Value;
Button5.Visible := not Value;
Button6.Enabled := Value;
LabeledEdit1.Enabled := Value;
LabeledEdit2.Enabled := Value;
LabeledEdit3.Enabled := Value;
LabeledEdit4.Enabled := Value;
CheckBox1.Enabled := Value;
CheckBox2.Enabled := Value;
end;
procedure TForm1.UpdateMemoryStatus;
var
HeapStatus: THeapStatus;
HeapSize: Int64;
begin
HeapStatus := GetHeapStatus;
HeapSize := HeapStatus.Overhead + HeapStatus.TotalAllocated;
Dec(HeapSize, InitialHeapSize);
if HeapSize > MaxHeapSize then
MaxHeapSize := HeapSize;
Inc(TotalGetHeapStatusCount);
Inc(AverageHeapSize, HeapSize);
Label1.Caption := 'Текущий расход памяти: ' + IntToStr(HeapSize) + ' байт';
Label2.Caption := 'Пиковый расход памяти: ' + IntToStr(MaxHeapSize) + ' байт';
Application.ProcessMessages;
Application.ProcessMessages;
end;
end.

View File

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="9"/>
<PathDelim Value="\"/>
<General>
<Flags>
<MainUnitHasUsesSectionForAllUnits Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="-1"/>
<Title Value="FWZipPerfomance"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<i18n>
<EnableI18N LFM="False"/>
</i18n>
<VersionInfo>
<StringTable ProductVersion=""/>
</VersionInfo>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
</PublishOptions>
<RunParams>
<local>
<FormatVersion Value="1"/>
</local>
</RunParams>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<SyntaxMode Value="delphi"/>
</SyntaxOptions>
</Parsing>
<Other>
<CompilerMessages>
<MsgFileName Value=""/>
</CompilerMessages>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

View File

@ -0,0 +1,116 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="9"/>
<PathDelim Value="\"/>
<General>
<Flags>
<MainUnitHasUsesSectionForAllUnits Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="FWZipPerfomance"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<i18n>
<EnableI18N LFM="False"/>
</i18n>
<VersionInfo>
<StringTable ProductVersion=""/>
</VersionInfo>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
</PublishOptions>
<RunParams>
<local>
<FormatVersion Value="1"/>
</local>
</RunParams>
<RequiredPackages Count="1">
<Item1>
<PackageName Value="LCL"/>
</Item1>
</RequiredPackages>
<Units Count="8">
<Unit0>
<Filename Value="FWZipPerfomance.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
<Unit1>
<Filename Value="Unit1.pas"/>
<IsPartOfProject Value="True"/>
<HasResources Value="True"/>
</Unit1>
<Unit2>
<Filename Value="..\..\FWZipConsts.pas"/>
<IsPartOfProject Value="True"/>
</Unit2>
<Unit3>
<Filename Value="..\..\FWZipCrc32.pas"/>
<IsPartOfProject Value="True"/>
</Unit3>
<Unit4>
<Filename Value="..\..\FWZipCrypt.pas"/>
<IsPartOfProject Value="True"/>
</Unit4>
<Unit5>
<Filename Value="..\..\FWZipReader.pas"/>
<IsPartOfProject Value="True"/>
</Unit5>
<Unit6>
<Filename Value="..\..\FWZipStream.pas"/>
<IsPartOfProject Value="True"/>
</Unit6>
<Unit7>
<Filename Value="..\..\FWZipWriter.pas"/>
<IsPartOfProject Value="True"/>
</Unit7>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<IncludeFiles Value="..\.."/>
<OtherUnitFiles Value="..\.."/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<SyntaxMode Value="delphi"/>
</SyntaxOptions>
</Parsing>
<Linking>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
<Other>
<CompilerMessages>
<MsgFileName Value=""/>
</CompilerMessages>
<CustomOptions Value="-dBorland -dVer150 -dDelphi7 -dCompiler6_Up -dPUREPASCAL"/>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

View File

@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="9"/>
<PathDelim Value="\"/>
<General>
<Flags>
<MainUnitHasUsesSectionForAllUnits Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="FWZipPerfomance"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<i18n>
<EnableI18N LFM="False"/>
</i18n>
<VersionInfo>
<StringTable ProductVersion=""/>
</VersionInfo>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
</PublishOptions>
<RunParams>
<local>
<FormatVersion Value="1"/>
</local>
</RunParams>
<RequiredPackages Count="1">
<Item1>
<PackageName Value="LCL"/>
</Item1>
</RequiredPackages>
<Units Count="8">
<Unit0>
<Filename Value="FWZipPerfomance.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
<Unit1>
<Filename Value="Unit1.pas"/>
<IsPartOfProject Value="True"/>
<HasResources Value="True"/>
<UnitName Value="Unit1"/>
</Unit1>
<Unit2>
<Filename Value="..\..\FWZipConsts.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="FWZipConsts"/>
</Unit2>
<Unit3>
<Filename Value="..\..\FWZipCrc32.pas"/>
<IsPartOfProject Value="True"/>
</Unit3>
<Unit4>
<Filename Value="..\..\FWZipCrypt.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="FWZipCrypt"/>
</Unit4>
<Unit5>
<Filename Value="..\..\FWZipReader.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="FWZipReader"/>
</Unit5>
<Unit6>
<Filename Value="..\..\FWZipStream.pas"/>
<IsPartOfProject Value="True"/>
</Unit6>
<Unit7>
<Filename Value="..\..\FWZipWriter.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="FWZipWriter"/>
</Unit7>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<IncludeFiles Value="..\.."/>
<OtherUnitFiles Value="..\.."/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<SyntaxMode Value="delphi"/>
</SyntaxOptions>
</Parsing>
<Linking>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
<Other>
<CompilerMessages>
<MsgFileName Value=""/>
</CompilerMessages>
<CustomOptions Value="-dBorland -dVer150 -dDelphi7 -dCompiler6_Up -dPUREPASCAL"/>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

View File

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="9"/>
<PathDelim Value="\"/>
<General>
<Flags>
<MainUnitHasUsesSectionForAllUnits Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="FWZipPerfomance"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<i18n>
<EnableI18N LFM="False"/>
</i18n>
<VersionInfo>
<StringTable ProductVersion=""/>
</VersionInfo>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
</PublishOptions>
<RunParams>
<local>
<FormatVersion Value="1"/>
</local>
</RunParams>
<RequiredPackages Count="1">
<Item1>
<PackageName Value="LCL"/>
</Item1>
</RequiredPackages>
<Units Count="2">
<Unit0>
<Filename Value="FWZipPerfomance.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
<Unit1>
<Filename Value="Unit1.pas"/>
<IsPartOfProject Value="True"/>
<HasResources Value="True"/>
<UnitName Value="Unit1"/>
</Unit1>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<IncludeFiles Value="..\.."/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<SyntaxMode Value="delphi"/>
</SyntaxOptions>
</Parsing>
<Linking>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
<Other>
<CompilerMessages>
<MsgFileName Value=""/>
</CompilerMessages>
<CustomOptions Value="-dBorland -dVer150 -dDelphi7 -dCompiler6_Up -dPUREPASCAL"/>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

View File

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="9"/>
<PathDelim Value="\"/>
<General>
<Flags>
<MainUnitHasUsesSectionForAllUnits Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="FWZipPerfomance"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<i18n>
<EnableI18N LFM="False"/>
</i18n>
<VersionInfo>
<StringTable ProductVersion=""/>
</VersionInfo>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
</PublishOptions>
<RunParams>
<local>
<FormatVersion Value="1"/>
</local>
</RunParams>
<RequiredPackages Count="1">
<Item1>
<PackageName Value="LCL"/>
</Item1>
</RequiredPackages>
<Units Count="2">
<Unit0>
<Filename Value="FWZipPerfomance.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
<Unit1>
<Filename Value="Unit1.pas"/>
<IsPartOfProject Value="True"/>
<HasResources Value="True"/>
<UnitName Value="Unit1"/>
</Unit1>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<IncludeFiles Value="..\.."/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<SyntaxMode Value="delphi"/>
</SyntaxOptions>
</Parsing>
<Linking>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
<Other>
<CompilerMessages>
<MsgFileName Value=""/>
</CompilerMessages>
<CustomOptions Value="-dBorland -dVer150 -dDelphi7 -dCompiler6_Up -dPUREPASCAL"/>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

View File

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="9"/>
<PathDelim Value="\"/>
<General>
<Flags>
<MainUnitHasUsesSectionForAllUnits Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="FWZipPerfomance"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<i18n>
<EnableI18N LFM="False"/>
</i18n>
<VersionInfo>
<StringTable ProductVersion=""/>
</VersionInfo>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
</PublishOptions>
<RunParams>
<local>
<FormatVersion Value="1"/>
</local>
</RunParams>
<RequiredPackages Count="2">
<Item1>
<PackageName Value="fwzip"/>
</Item1>
<Item2>
<PackageName Value="LCL"/>
</Item2>
</RequiredPackages>
<Units Count="2">
<Unit0>
<Filename Value="FWZipPerfomance.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
<Unit1>
<Filename Value="Unit1.pas"/>
<IsPartOfProject Value="True"/>
<HasResources Value="True"/>
<UnitName Value="Unit1"/>
</Unit1>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<IncludeFiles Value="..\.."/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<SyntaxMode Value="delphi"/>
</SyntaxOptions>
</Parsing>
<Linking>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
<Other>
<CompilerMessages>
<MsgFileName Value=""/>
</CompilerMessages>
<CustomOptions Value="-dBorland -dVer150 -dDelphi7 -dCompiler6_Up -dPUREPASCAL"/>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

View File

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="9"/>
<PathDelim Value="\"/>
<General>
<Flags>
<MainUnitHasUsesSectionForAllUnits Value="False"/>
<MainUnitHasCreateFormStatements Value="False"/>
<MainUnitHasTitleStatement Value="False"/>
</Flags>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="FWZipPerfomance"/>
<UseAppBundle Value="False"/>
<ResourceType Value="res"/>
</General>
<i18n>
<EnableI18N LFM="False"/>
</i18n>
<VersionInfo>
<StringTable ProductVersion=""/>
</VersionInfo>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
</PublishOptions>
<RunParams>
<local>
<FormatVersion Value="1"/>
</local>
</RunParams>
<RequiredPackages Count="2">
<Item1>
<PackageName Value="fwzip"/>
</Item1>
<Item2>
<PackageName Value="LCL"/>
</Item2>
</RequiredPackages>
<Units Count="2">
<Unit0>
<Filename Value="FWZipPerfomance.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
<Unit1>
<Filename Value="Unit1.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="Form1"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="Unit1"/>
</Unit1>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<IncludeFiles Value="..\.."/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<SyntaxMode Value="delphi"/>
</SyntaxOptions>
</Parsing>
<Linking>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
<Other>
<CompilerMessages>
<MsgFileName Value=""/>
</CompilerMessages>
<CustomOptions Value="-dBorland -dVer150 -dDelphi7 -dCompiler6_Up -dPUREPASCAL"/>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

View File

@ -0,0 +1,19 @@
program FWZipPerfomance;
uses
Forms,
Unit1 in 'Unit1.pas' {Form1},
FWZipConsts in '..\..\FWZipConsts.pas',
FWZipCrc32 in '..\..\FWZipCrc32.pas',
FWZipCrypt in '..\..\FWZipCrypt.pas',
FWZipReader in '..\..\FWZipReader.pas',
FWZipStream in '..\..\FWZipStream.pas',
FWZipWriter in '..\..\FWZipWriter.pas';
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

View File

@ -0,0 +1,21 @@
program FWZipPerfomance;
{$MODE Delphi}
uses
Forms, Interfaces,
Unit1 in 'Unit1.pas' {Form1},
FWZipConsts in '..\..\FWZipConsts.pas',
FWZipCrc32 in '..\..\FWZipCrc32.pas',
FWZipCrypt in '..\..\FWZipCrypt.pas',
FWZipReader in '..\..\FWZipReader.pas',
FWZipStream in '..\..\FWZipStream.pas',
FWZipWriter in '..\..\FWZipWriter.pas';
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

View File

@ -0,0 +1,19 @@
program FWZipPerfomance;
{$MODE Delphi}
uses
Forms, Interfaces,
Unit1 in 'Unit1.pas' {Form1},
FWZipConsts in '..\..\FWZipConsts.pas',
FWZipCrc32 in '..\..\FWZipCrc32.pas',
FWZipCrypt in '..\..\FWZipCrypt.pas',
FWZipReader in '..\..\FWZipReader.pas',
FWZipStream in '..\..\FWZipStream.pas',
FWZipWriter in '..\..\FWZipWriter.pas';
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectSession>
<PathDelim Value="\"/>
<Version Value="9"/>
<BuildModes Active="Default"/>
<JumpHistory Count="0" HistoryIndex="-1"/>
</ProjectSession>
<SkipCheckLCLInterfaces Value="True"/>
<EditorMacros Count="0"/>
</CONFIG>

View File

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectSession>
<PathDelim Value="\"/>
<Version Value="9"/>
<BuildModes Active="Default"/>
<Units Count="8">
<Unit0>
<Filename Value="FWZipPerfomance.lpr"/>
<IsPartOfProject Value="True"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="0"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
<UsageCount Value="20"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit0>
<Unit1>
<Filename Value="Unit1.pas"/>
<IsPartOfProject Value="True"/>
<HasResources Value="True"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit1>
<Unit2>
<Filename Value="..\..\FWZipConsts.pas"/>
<IsPartOfProject Value="True"/>
<UsageCount Value="20"/>
</Unit2>
<Unit3>
<Filename Value="..\..\FWZipCrc32.pas"/>
<IsPartOfProject Value="True"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit3>
<Unit4>
<Filename Value="..\..\FWZipCrypt.pas"/>
<IsPartOfProject Value="True"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit4>
<Unit5>
<Filename Value="..\..\FWZipReader.pas"/>
<IsPartOfProject Value="True"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit5>
<Unit6>
<Filename Value="..\..\FWZipStream.pas"/>
<IsPartOfProject Value="True"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit6>
<Unit7>
<Filename Value="..\..\FWZipWriter.pas"/>
<IsPartOfProject Value="True"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit7>
</Units>
<General>
<ActiveWindowIndexAtStart Value="0"/>
</General>
<JumpHistory Count="0" HistoryIndex="-1"/>
</ProjectSession>
<SkipCheckLCLInterfaces Value="True"/>
<EditorMacros Count="0"/>
</CONFIG>

View File

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectSession>
<PathDelim Value="\"/>
<Version Value="9"/>
<BuildModes Active="Default"/>
<Units Count="8">
<Unit0>
<Filename Value="FWZipPerfomance.lpr"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="0"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
<UsageCount Value="20"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit0>
<Unit1>
<Filename Value="Unit1.pas"/>
<IsPartOfProject Value="True"/>
<HasResources Value="True"/>
<UnitName Value="Unit1"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit1>
<Unit2>
<Filename Value="..\..\FWZipConsts.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="FWZipConsts"/>
<EditorIndex Value="1"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
<UsageCount Value="20"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit2>
<Unit3>
<Filename Value="..\..\FWZipCrc32.pas"/>
<IsPartOfProject Value="True"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit3>
<Unit4>
<Filename Value="..\..\FWZipCrypt.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="FWZipCrypt"/>
<EditorIndex Value="2"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
<UsageCount Value="20"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit4>
<Unit5>
<Filename Value="..\..\FWZipReader.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="FWZipReader"/>
<EditorIndex Value="3"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
<UsageCount Value="20"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit5>
<Unit6>
<Filename Value="..\..\FWZipStream.pas"/>
<IsPartOfProject Value="True"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit6>
<Unit7>
<Filename Value="..\..\FWZipWriter.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="FWZipWriter"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="4"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
<UsageCount Value="20"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit7>
</Units>
<General>
<ActiveWindowIndexAtStart Value="0"/>
</General>
<JumpHistory Count="0" HistoryIndex="-1"/>
</ProjectSession>
<SkipCheckLCLInterfaces Value="True"/>
<EditorMacros Count="0"/>
</CONFIG>

View File

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectSession>
<PathDelim Value="\"/>
<Version Value="9"/>
<BuildModes Active="Default"/>
<Units Count="8">
<Unit0>
<Filename Value="FWZipPerfomance.lpr"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="0"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="10" Y="4"/>
<UsageCount Value="20"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit0>
<Unit1>
<Filename Value="Unit1.pas"/>
<IsPartOfProject Value="True"/>
<HasResources Value="True"/>
<UnitName Value="Unit1"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="1"/>
<WindowIndex Value="0"/>
<TopLine Value="37"/>
<CursorPos X="1" Y="1"/>
<UsageCount Value="20"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit1>
<Unit2>
<Filename Value="..\..\FWZipConsts.pas"/>
<UnitName Value="FWZipConsts"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit2>
<Unit3>
<Filename Value="..\..\FWZipCrc32.pas"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit3>
<Unit4>
<Filename Value="..\..\FWZipCrypt.pas"/>
<UnitName Value="FWZipCrypt"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit4>
<Unit5>
<Filename Value="..\..\FWZipReader.pas"/>
<UnitName Value="FWZipReader"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit5>
<Unit6>
<Filename Value="..\..\FWZipStream.pas"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit6>
<Unit7>
<Filename Value="..\..\FWZipWriter.pas"/>
<UnitName Value="FWZipWriter"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="2"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit7>
</Units>
<General>
<ActiveWindowIndexAtStart Value="0"/>
</General>
<JumpHistory Count="0" HistoryIndex="-1"/>
</ProjectSession>
<SkipCheckLCLInterfaces Value="True"/>
<Debugging>
<BreakPoints Count="1">
<Item1>
<Kind Value="bpkSource"/>
<WatchScope Value="wpsLocal"/>
<WatchKind Value="wpkWrite"/>
<Source Value="Unit1.pas"/>
<Line Value="1"/>
</Item1>
</BreakPoints>
</Debugging>
<EditorMacros Count="0"/>
</CONFIG>

View File

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectSession>
<PathDelim Value="\"/>
<Version Value="9"/>
<BuildModes Active="Default"/>
<Units Count="8">
<Unit0>
<Filename Value="FWZipPerfomance.lpr"/>
<IsPartOfProject Value="True"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="0"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="31" Y="5"/>
<UsageCount Value="20"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit0>
<Unit1>
<Filename Value="Unit1.pas"/>
<IsPartOfProject Value="True"/>
<HasResources Value="True"/>
<UnitName Value="Unit1"/>
<EditorIndex Value="1"/>
<WindowIndex Value="0"/>
<TopLine Value="37"/>
<CursorPos X="1" Y="1"/>
<UsageCount Value="20"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit1>
<Unit2>
<Filename Value="..\..\FWZipConsts.pas"/>
<UnitName Value="FWZipConsts"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit2>
<Unit3>
<Filename Value="..\..\FWZipCrc32.pas"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit3>
<Unit4>
<Filename Value="..\..\FWZipCrypt.pas"/>
<UnitName Value="FWZipCrypt"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit4>
<Unit5>
<Filename Value="..\..\FWZipReader.pas"/>
<UnitName Value="FWZipReader"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit5>
<Unit6>
<Filename Value="..\..\FWZipStream.pas"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit6>
<Unit7>
<Filename Value="..\..\FWZipWriter.pas"/>
<UnitName Value="FWZipWriter"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="2"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit7>
</Units>
<General>
<ActiveWindowIndexAtStart Value="0"/>
</General>
<JumpHistory Count="0" HistoryIndex="-1"/>
</ProjectSession>
<SkipCheckLCLInterfaces Value="True"/>
<Debugging>
<BreakPoints Count="1">
<Item1>
<Kind Value="bpkSource"/>
<WatchScope Value="wpsLocal"/>
<WatchKind Value="wpkWrite"/>
<Source Value="Unit1.pas"/>
<Line Value="1"/>
</Item1>
</BreakPoints>
</Debugging>
<EditorMacros Count="0"/>
</CONFIG>

View File

@ -0,0 +1,103 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectSession>
<PathDelim Value="\"/>
<Version Value="9"/>
<BuildModes Active="Default"/>
<Units Count="8">
<Unit0>
<Filename Value="FWZipPerfomance.lpr"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="0"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="31" Y="5"/>
<UsageCount Value="20"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit0>
<Unit1>
<Filename Value="Unit1.pas"/>
<IsPartOfProject Value="True"/>
<HasResources Value="True"/>
<UnitName Value="Unit1"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="1"/>
<WindowIndex Value="0"/>
<TopLine Value="18"/>
<CursorPos X="3" Y="35"/>
<UsageCount Value="20"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit1>
<Unit2>
<Filename Value="..\..\FWZipConsts.pas"/>
<UnitName Value="FWZipConsts"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit2>
<Unit3>
<Filename Value="..\..\FWZipCrc32.pas"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit3>
<Unit4>
<Filename Value="..\..\FWZipCrypt.pas"/>
<UnitName Value="FWZipCrypt"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit4>
<Unit5>
<Filename Value="..\..\FWZipReader.pas"/>
<UnitName Value="FWZipReader"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit5>
<Unit6>
<Filename Value="..\..\FWZipStream.pas"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit6>
<Unit7>
<Filename Value="..\..\FWZipWriter.pas"/>
<UnitName Value="FWZipWriter"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="2"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit7>
</Units>
<General>
<ActiveWindowIndexAtStart Value="0"/>
</General>
<JumpHistory Count="1" HistoryIndex="0">
<Position1>
<Filename Value="Unit1.pas"/>
<Caret Line="1" Column="1" TopLine="37"/>
</Position1>
</JumpHistory>
</ProjectSession>
<SkipCheckLCLInterfaces Value="True"/>
<Debugging>
<BreakPoints Count="1">
<Item1>
<Kind Value="bpkSource"/>
<WatchScope Value="wpsLocal"/>
<WatchKind Value="wpkWrite"/>
<Source Value="Unit1.pas"/>
<Line Value="1"/>
</Item1>
</BreakPoints>
</Debugging>
<EditorMacros Count="0"/>
</CONFIG>

View File

@ -0,0 +1,118 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectSession>
<PathDelim Value="\"/>
<Version Value="9"/>
<BuildModes Active="Default"/>
<Units Count="8">
<Unit0>
<Filename Value="FWZipPerfomance.lpr"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="0"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="31" Y="5"/>
<UsageCount Value="20"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit0>
<Unit1>
<Filename Value="Unit1.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="Form1"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="Unit1"/>
<EditorIndex Value="1"/>
<WindowIndex Value="0"/>
<TopLine Value="77"/>
<CursorPos X="1" Y="94"/>
<UsageCount Value="20"/>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit1>
<Unit2>
<Filename Value="..\..\FWZipConsts.pas"/>
<UnitName Value="FWZipConsts"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit2>
<Unit3>
<Filename Value="..\..\FWZipCrc32.pas"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit3>
<Unit4>
<Filename Value="..\..\FWZipCrypt.pas"/>
<UnitName Value="FWZipCrypt"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit4>
<Unit5>
<Filename Value="..\..\FWZipReader.pas"/>
<UnitName Value="FWZipReader"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit5>
<Unit6>
<Filename Value="..\..\FWZipStream.pas"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit6>
<Unit7>
<Filename Value="..\..\FWZipWriter.pas"/>
<UnitName Value="FWZipWriter"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="2"/>
<WindowIndex Value="0"/>
<TopLine Value="1502"/>
<CursorPos X="1" Y="1518"/>
<UsageCount Value="20"/>
<Loaded Value="True"/>
</Unit7>
</Units>
<General>
<ActiveWindowIndexAtStart Value="0"/>
</General>
<JumpHistory Count="4" HistoryIndex="3">
<Position1>
<Filename Value="Unit1.pas"/>
<Caret Line="40" Column="41" TopLine="106"/>
</Position1>
<Position2>
<Filename Value="Unit1.pas"/>
<Caret Line="110" Column="32" TopLine="99"/>
</Position2>
<Position3>
<Filename Value="Unit1.pas"/>
<Caret Line="94" Column="1" TopLine="77"/>
</Position3>
<Position4>
<Filename Value="..\..\FWZipWriter.pas"/>
<Caret Line="1517" Column="56" TopLine="1502"/>
</Position4>
</JumpHistory>
</ProjectSession>
<Debugging>
<BreakPoints Count="1">
<Item1>
<Kind Value="bpkSource"/>
<WatchScope Value="wpsLocal"/>
<WatchKind Value="wpkWrite"/>
<Source Value="Unit1.pas"/>
<Line Value="1"/>
</Item1>
</BreakPoints>
</Debugging>
<EditorMacros Count="0"/>
</CONFIG>

View File

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectSession>
<PathDelim Value="\"/>
<Version Value="9"/>
<BuildModes Active="Default"/>
<Units Count="8">
<Unit0>
<Filename Value="FWZipPerfomance.lpr"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="0"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="31" Y="5"/>
<UsageCount Value="20"/>
<Loaded Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit0>
<Unit1>
<Filename Value="Unit1.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="Form1"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="Unit1"/>
<EditorIndex Value="1"/>
<WindowIndex Value="0"/>
<TopLine Value="77"/>
<CursorPos X="1" Y="94"/>
<UsageCount Value="20"/>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit1>
<Unit2>
<Filename Value="..\..\FWZipConsts.pas"/>
<UnitName Value="FWZipConsts"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit2>
<Unit3>
<Filename Value="..\..\FWZipCrc32.pas"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit3>
<Unit4>
<Filename Value="..\..\FWZipCrypt.pas"/>
<UnitName Value="FWZipCrypt"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit4>
<Unit5>
<Filename Value="..\..\FWZipReader.pas"/>
<UnitName Value="FWZipReader"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="1" Y="1"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit5>
<Unit6>
<Filename Value="..\..\FWZipStream.pas"/>
<UsageCount Value="20"/>
<DefaultSyntaxHighlighter Value="Delphi"/>
</Unit6>
<Unit7>
<Filename Value="..\..\FWZipWriter.pas"/>
<UnitName Value="FWZipWriter"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="2"/>
<WindowIndex Value="0"/>
<TopLine Value="1502"/>
<CursorPos X="1" Y="1518"/>
<UsageCount Value="20"/>
<Loaded Value="True"/>
</Unit7>
</Units>
<General>
<ActiveWindowIndexAtStart Value="0"/>
</General>
<JumpHistory Count="6" HistoryIndex="5">
<Position1>
<Filename Value="Unit1.pas"/>
<Caret Line="40" Column="41" TopLine="106"/>
</Position1>
<Position2>
<Filename Value="Unit1.pas"/>
<Caret Line="110" Column="32" TopLine="99"/>
</Position2>
<Position3>
<Filename Value="Unit1.pas"/>
<Caret Line="94" Column="1" TopLine="77"/>
</Position3>
<Position4>
<Filename Value="..\..\FWZipWriter.pas"/>
<Caret Line="1517" Column="56" TopLine="1502"/>
</Position4>
<Position5>
<Filename Value="..\..\FWZipWriter.pas"/>
<Caret Line="1518" Column="1" TopLine="1502"/>
</Position5>
<Position6>
<Filename Value="Unit1.pas"/>
<Caret Line="94" Column="1" TopLine="77"/>
</Position6>
</JumpHistory>
</ProjectSession>
<Debugging>
<BreakPoints Count="1">
<Item1>
<Kind Value="bpkSource"/>
<WatchScope Value="wpsLocal"/>
<WatchKind Value="wpkWrite"/>
<Source Value="Unit1.pas"/>
<Line Value="1"/>
</Item1>
</BreakPoints>
</Debugging>
<EditorMacros Count="0"/>
</CONFIG>

View File

@ -0,0 +1,244 @@
object Form1: TForm1
Left = 381
Top = 183
Width = 578
Height = 654
Caption = 'Тест производительности FWZip'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
Position = poScreenCenter
PixelsPerInch = 96
object GroupBox1: TGroupBox
Left = 8
Top = 8
Width = 527
Height = 105
Anchors = [akLeft, akTop, akRight]
Caption = 'Настройки сжатия'
TabOrder = 0
object LabeledEdit1: TLabeledEdit
Left = 14
Top = 26
Width = 469
Height = 21
Anchors = [akLeft, akTop, akRight]
EditLabel.Width = 149
EditLabel.Height = 13
EditLabel.Caption = 'Выберите папку для сжатия:'
TabOrder = 0
Text = 'D:\StroyInfo 5'
OnChange = LabeledEdit1Change
end
object Button1: TButton
Left = 489
Top = 24
Width = 26
Height = 25
Hint = 'Обзор...'
Anchors = [akTop, akRight]
Caption = '...'
ParentShowHint = False
ShowHint = True
TabOrder = 1
OnClick = Button1Click
end
object CheckBox1: TCheckBox
Left = 14
Top = 58
Width = 145
Height = 17
Caption = 'Шифровать при сжатии'
TabOrder = 2
OnClick = CheckBox1Click
end
object LabeledEdit2: TLabeledEdit
Left = 262
Top = 56
Width = 172
Height = 21
Anchors = [akLeft, akTop, akRight]
EditLabel.Width = 84
EditLabel.Height = 13
EditLabel.Caption = 'Укажите пароль'
Enabled = False
LabelPosition = lpLeft
TabOrder = 3
end
object Button2: TButton
Left = 440
Top = 55
Width = 75
Height = 25
Anchors = [akTop, akRight]
Caption = 'Сжать'
TabOrder = 4
OnClick = Button2Click
end
end
object GroupBox2: TGroupBox
Left = 8
Top = 128
Width = 527
Height = 137
Anchors = [akLeft, akTop, akRight]
Caption = 'Настройки распаковки'
TabOrder = 1
object LabeledEdit3: TLabeledEdit
Left = 14
Top = 26
Width = 469
Height = 21
Anchors = [akLeft, akTop, akRight]
EditLabel.Width = 171
EditLabel.Height = 13
EditLabel.Caption = 'Выберите архив для распаковки:'
TabOrder = 0
OnChange = LabeledEdit3Change
end
object Button3: TButton
Left = 489
Top = 24
Width = 26
Height = 25
Hint = 'Обзор...'
Anchors = [akTop, akRight]
Caption = '...'
ParentShowHint = False
ShowHint = True
TabOrder = 1
OnClick = Button3Click
end
object CheckBox2: TCheckBox
Left = 14
Top = 58
Width = 145
Height = 17
Caption = 'Архив зашифрован'
TabOrder = 2
OnClick = CheckBox2Click
end
object LabeledEdit4: TLabeledEdit
Left = 262
Top = 56
Width = 167
Height = 21
Anchors = [akLeft, akTop, akRight]
EditLabel.Width = 84
EditLabel.Height = 13
EditLabel.Caption = 'Укажите пароль'
Enabled = False
LabelPosition = lpLeft
TabOrder = 3
end
object Button4: TButton
Left = 440
Top = 54
Width = 75
Height = 25
Anchors = [akTop, akRight]
Caption = 'Распаковать'
TabOrder = 4
OnClick = Button4Click
end
object Button6: TButton
Tag = 1
Left = 440
Top = 85
Width = 75
Height = 25
Anchors = [akTop, akRight]
Caption = 'Проверить'
TabOrder = 5
OnClick = Button4Click
end
end
object GroupBox3: TGroupBox
Left = 8
Top = 271
Width = 527
Height = 178
Anchors = [akLeft, akTop, akRight]
Caption = 'Производительность:'
TabOrder = 2
object Label1: TLabel
Left = 14
Top = 10
Width = 163
Height = 13
Caption = 'Текущий расход памяти: 0 байт'
end
object Label2: TLabel
Left = 14
Top = 29
Width = 163
Height = 13
Caption = 'Пиковый расход памяти: 0 байт'
end
object Label3: TLabel
Left = 14
Top = 48
Width = 166
Height = 13
Caption = 'Общее количество элементов: 0'
end
object Label4: TLabel
Left = 14
Top = 67
Width = 142
Height = 13
Caption = 'Общее размер элементов: 0'
end
object Label5: TLabel
Left = 14
Top = 95
Width = 501
Height = 13
Anchors = [akLeft, akTop, akRight]
AutoSize = False
end
object ProgressBar1: TProgressBar
Left = 14
Top = 114
Width = 498
Height = 17
Anchors = [akLeft, akTop, akRight]
TabOrder = 0
end
object ProgressBar2: TProgressBar
Left = 14
Top = 137
Width = 498
Height = 17
Anchors = [akLeft, akTop, akRight]
TabOrder = 1
end
object Button5: TButton
Left = 437
Top = 83
Width = 75
Height = 25
Anchors = [akTop, akRight]
Caption = 'Остановить'
TabOrder = 2
Visible = False
OnClick = Button5Click
end
end
object Memo1: TMemo
Left = 8
Top = 456
Width = 527
Height = 146
Anchors = [akLeft, akTop, akRight, akBottom]
ScrollBars = ssVertical
TabOrder = 3
end
object OpenDialog1: TOpenDialog
Left = 376
Top = 224
end
end

View File

@ -0,0 +1,298 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip - FWZipPerfomance
// * Purpose : Òåñòèðîâàíèå ïðîèçâîäèòåëüíîñòè FWZip
// * Author : Àëåêñàíäð (Rouse_) Áàãåëü
// * Copyright : © Fangorn Wizards Lab 1998 - 2013.
// * Version : 1.0.10
// * Home Page : http://rouse.drkb.ru
// * Home Blog : http://alexander-bagel.blogspot.ru
// ****************************************************************************
// * Stable Release : http://rouse.drkb.ru/components.php#fwzip
// * Latest Source : https://github.com/AlexanderBagel/FWZip
// ****************************************************************************
//
// Èñïîëüçóåìûå èñòî÷íèêè:
// ftp://ftp.info-zip.org/pub/infozip/doc/appnote-iz-latest.zip
// http://zlib.net/zlib-1.2.5.tar.gz
// http://www.base2ti.com/
//
unit Unit1;
interface
{$WARN SYMBOL_PLATFORM OFF}
{$WARN SYMBOL_DEPRECATED OFF}
{$WARN UNIT_PLATFORM OFF}
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, FileCtrl, ComCtrls,
FWZipWriter, FWZipReader, FWZipConsts, Contnrs;
type
TForm1 = class(TForm)
GroupBox1: TGroupBox;
LabeledEdit1: TLabeledEdit;
Button1: TButton;
CheckBox1: TCheckBox;
LabeledEdit2: TLabeledEdit;
Button2: TButton;
GroupBox2: TGroupBox;
LabeledEdit3: TLabeledEdit;
Button3: TButton;
CheckBox2: TCheckBox;
LabeledEdit4: TLabeledEdit;
Button4: TButton;
OpenDialog1: TOpenDialog;
GroupBox3: TGroupBox;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
ProgressBar1: TProgressBar;
ProgressBar2: TProgressBar;
Label5: TLabel;
Button5: TButton;
Button6: TButton;
Memo1: TMemo;
procedure CheckBox1Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure LabeledEdit1Change(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure CheckBox2Click(Sender: TObject);
procedure LabeledEdit3Change(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
private
InitialHeapSize, MaxHeapSize, AverageHeapSize: Int64;
TotalGetHeapStatusCount: Integer;
StopProcess: Boolean;
procedure OnProgress(Sender: TObject; const FileName: string;
Percent, TotalPercent: Byte; var Cancel: Boolean;
ProgressState: TProgressState);
procedure UpdateMemoryStatus;
procedure SetEnabledState(Value: Boolean);
procedure ClearZipData;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
Dir: string;
begin
if SelectDirectory('Óêàæèòå ïàïêó äëÿ ñæàòèÿ', '', Dir) then
LabeledEdit1.Text := Dir;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
I: Integer;
TotalSize: Int64;
Heap: THeapStatus;
TicCount: DWORD;
Item: TFWZipWriterItem;
Writer: TFWZipWriter;
begin
Writer := TFWZipWriter.Create;
try
DeleteFile(
IncludeTrailingPathDelimiter(LabeledEdit1.Text) + 'FWZipTest.zip');
Writer.AddFolder('', LabeledEdit1.Text, '');
TotalSize := 0;
InitialHeapSize := 0;
for I := 0 to Writer.Count - 1 do
begin
Item := Writer[I];
Inc(TotalSize, Item.Size);
Inc(InitialHeapSize, SizeOf(TCentralDirectoryFileHeaderEx));
if LabeledEdit2.Text <> '' then
begin
Item.Password := LabeledEdit2.Text;
Item.NeedDescriptor := True;
end;
end;
Label3.Caption := 'Îáùåå êîëè÷åñòâî ýëåìåíòîâ: ' + IntToStr(Writer.Count);
Label4.Caption := 'Îáùèé ðàçìåð ýëåìåíòîâ: ' + IntToStr(TotalSize);
Writer.OnProgress := OnProgress;
SetEnabledState(False);
try
Heap := GetHeapStatus;
Inc(InitialHeapSize, Heap.Overhead + Heap.TotalAllocated);
MaxHeapSize := 0;
AverageHeapSize := 0;
TotalGetHeapStatusCount := 0;
StopProcess := False;
TicCount := GetTickCount;
Writer.BuildZip(
IncludeTrailingPathDelimiter(LabeledEdit1.Text) + 'FWZipTest.zip');
if TotalGetHeapStatusCount = 0 then
TotalGetHeapStatusCount := 1;
ShowMessage(Format(
'Ïèêîâûé ðàñõîä ïàìÿòè: %d áàéò' + sLineBreak +
'Ñðåäíèé ðàñõîä ïàìÿòè: %d áàéò' + sLineBreak +
'Îáùåå âðåìÿ ðàáîòû: %d ñåêóíä',
[MaxHeapSize, AverageHeapSize div TotalGetHeapStatusCount,
(GetTickCount - TicCount) div 1000]));
finally
SetEnabledState(True);
end;
finally
Writer.Free;
ClearZipData;
end;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
if OpenDialog1.Execute then
LabeledEdit3.Text := OpenDialog1.FileName;
end;
procedure TForm1.Button4Click(Sender: TObject);
var
I: Integer;
TotalSize: Int64;
Heap: THeapStatus;
TicCount: DWORD;
Path: string;
Reader: TFWZipReader;
begin
SetLength(Path, MAX_PATH);
Path := LabeledEdit3.Text;
Path := ChangeFileExt(Path, '');
Reader := TFWZipReader.Create;
try
Reader.LoadFromFile(LabeledEdit3.Text);
TotalSize := 0;
for I := 0 to Reader.Count - 1 do
Inc(TotalSize, Reader[I].UncompressedSize);
Label3.Caption := 'Îáùåå êîëè÷åñòâî ýëåìåíòîâ: ' + IntToStr(Reader.Count);
Label4.Caption := 'Îáùèé ðàçìåð ýëåìåíòîâ: ' + IntToStr(TotalSize);
Reader.OnProgress := OnProgress;
if LabeledEdit4.Text <> '' then
Reader.PasswordList.Add(LabeledEdit4.Text);
SetEnabledState(False);
try
Heap := GetHeapStatus;
InitialHeapSize := Heap.Overhead + Heap.TotalAllocated;
MaxHeapSize := 0;
AverageHeapSize := 0;
TotalGetHeapStatusCount := 0;
StopProcess := False;
Memo1.Lines.Clear;
TicCount := GetTickCount;
if TButton(Sender).Tag = 0 then
Reader.ExtractAll(Path)
else
Reader.Check;
if TotalGetHeapStatusCount = 0 then
TotalGetHeapStatusCount := 1;
ShowMessage(Format(
'Ïèêîâûé ðàñõîä ïàìÿòè: %d áàéò' + sLineBreak +
'Ñðåäíèé ðàñõîä ïàìÿòè: %d áàéò' + sLineBreak +
'Îáùåå âðåìÿ ðàáîòû: %d ñåêóíä',
[MaxHeapSize, AverageHeapSize div TotalGetHeapStatusCount,
(GetTickCount - TicCount) div 1000]));
finally
SetEnabledState(True);
end;
finally
Reader.Free;
ClearZipData;
end;
end;
procedure TForm1.Button5Click(Sender: TObject);
begin
StopProcess := True;
end;
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
LabeledEdit2.Enabled := CheckBox1.Checked;
end;
procedure TForm1.CheckBox2Click(Sender: TObject);
begin
LabeledEdit4.Enabled := CheckBox2.Checked;
end;
procedure TForm1.ClearZipData;
begin
Label1.Caption := 'Òåêóùèé ðàñõîä ïàìÿòè: 0 áàéò';
Label2.Caption := 'Ïèêîâûé ðàñõîä ïàìÿòè: 0 áàéò';
Label3.Caption := 'Îáùåå êîëè÷åñòâî ýëåìåíòîâ: 0';
Label4.Caption := 'Îáùèé ðàçìåð ýëåìåíòîâ: 0';
Label5.Caption := '';
end;
procedure TForm1.LabeledEdit1Change(Sender: TObject);
begin
Button2.Enabled := DirectoryExists(LabeledEdit1.Text);
end;
procedure TForm1.LabeledEdit3Change(Sender: TObject);
begin
Button4.Enabled := FileExists(LabeledEdit3.Text);
end;
procedure TForm1.OnProgress(Sender: TObject; const FileName: string; Percent,
TotalPercent: Byte; var Cancel: Boolean; ProgressState: TProgressState);
const
p: array [TProgressState] of string = ('psStart', 'psInitialization',
'psInProgress', 'psFinalization', 'psEnd', 'psException');
begin
Cancel := StopProcess;
Label5.Caption := Format('(%d) %s', [Percent, FileName]);
ProgressBar1.Position := Percent;
ProgressBar2.Position := TotalPercent;
Memo1.Lines.Add(Format('%s - %s percent %d total %d',
[FileName, P[ProgressState], Percent, TotalPercent]));
UpdateMemoryStatus;
end;
procedure TForm1.SetEnabledState(Value: Boolean);
begin
Button1.Enabled := Value;
Button2.Enabled := Value;
Button3.Enabled := Value;
Button4.Enabled := Value;
Button5.Visible := not Value;
Button6.Enabled := Value;
LabeledEdit1.Enabled := Value;
LabeledEdit2.Enabled := Value;
LabeledEdit3.Enabled := Value;
LabeledEdit4.Enabled := Value;
CheckBox1.Enabled := Value;
CheckBox2.Enabled := Value;
end;
procedure TForm1.UpdateMemoryStatus;
var
HeapStatus: THeapStatus;
HeapSize: Int64;
begin
HeapStatus := GetHeapStatus;
HeapSize := HeapStatus.Overhead + HeapStatus.TotalAllocated;
Dec(HeapSize, InitialHeapSize);
if HeapSize > MaxHeapSize then
MaxHeapSize := HeapSize;
Inc(TotalGetHeapStatusCount);
Inc(AverageHeapSize, HeapSize);
Label1.Caption := 'Òåêóùèé ðàñõîä ïàìÿòè: ' + IntToStr(HeapSize) + ' áàéò';
Label2.Caption := 'Ïèêîâûé ðàñõîä ïàìÿòè: ' + IntToStr(MaxHeapSize) + ' áàéò';
Application.ProcessMessages;
Application.ProcessMessages;
end;
end.

View File

@ -0,0 +1,299 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip - FWZipPerfomance
// * Purpose : Тестирование производительности FWZip
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2013.
// * Version : 1.0.10
// * Home Page : http://rouse.drkb.ru
// * Home Blog : http://alexander-bagel.blogspot.ru
// ****************************************************************************
// * Stable Release : http://rouse.drkb.ru/components.php#fwzip
// * Latest Source : https://github.com/AlexanderBagel/FWZip
// ****************************************************************************
//
// Используемые источники:
// ftp://ftp.info-zip.org/pub/infozip/doc/appnote-iz-latest.zip
// http://zlib.net/zlib-1.2.5.tar.gz
// http://www.base2ti.com/
//
unit Unit1;
{$MODE Delphi}
interface
{$WARN SYMBOL_PLATFORM OFF}
{$WARN SYMBOL_DEPRECATED OFF}
{$WARN UNIT_PLATFORM OFF}
uses
LCLIntf, LCLType, LMessages, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, FileCtrl, ComCtrls, FileUtil,
FWZipWriter, FWZipReader, FWZipConsts, Contnrs;
type
TForm1 = class(TForm)
GroupBox1: TGroupBox;
LabeledEdit1: TLabeledEdit;
Button1: TButton;
CheckBox1: TCheckBox;
LabeledEdit2: TLabeledEdit;
Button2: TButton;
GroupBox2: TGroupBox;
LabeledEdit3: TLabeledEdit;
Button3: TButton;
CheckBox2: TCheckBox;
LabeledEdit4: TLabeledEdit;
Button4: TButton;
OpenDialog1: TOpenDialog;
GroupBox3: TGroupBox;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
ProgressBar1: TProgressBar;
ProgressBar2: TProgressBar;
Label5: TLabel;
Button5: TButton;
Button6: TButton;
Memo1: TMemo;
procedure CheckBox1Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure LabeledEdit1Change(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure CheckBox2Click(Sender: TObject);
procedure LabeledEdit3Change(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
private
InitialHeapSize, MaxHeapSize, AverageHeapSize: Int64;
TotalGetHeapStatusCount: Integer;
StopProcess: Boolean;
procedure OnProgress(Sender: TObject; const FileName: string;
Percent, TotalPercent: Byte; var Cancel: Boolean;
ProgressState: TProgressState);
procedure UpdateMemoryStatus;
procedure SetEnabledState(Value: Boolean);
procedure ClearZipData;
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
procedure TForm1.Button1Click(Sender: TObject);
var
Dir: string;
begin
if SelectDirectory('Укажите папку для сжатия', '', Dir) then
LabeledEdit1.Text := Dir;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
I: Integer;
TotalSize: Int64;
Heap: THeapStatus;
TicCount: DWORD;
Item: TFWZipWriterItem;
Writer: TFWZipWriter;
begin
Writer := TFWZipWriter.Create;
try
DeleteFileUTF8(IncludeTrailingPathDelimiter(LabeledEdit1.Text) + 'FWZipTest.zip'); { *Converted from DeleteFile* }
Writer.AddFolder('', LabeledEdit1.Text, '');
TotalSize := 0;
InitialHeapSize := 0;
for I := 0 to Writer.Count - 1 do
begin
Item := Writer[I];
Inc(TotalSize, Item.Size);
Inc(InitialHeapSize, SizeOf(TCentralDirectoryFileHeaderEx));
if LabeledEdit2.Text <> '' then
begin
Item.Password := LabeledEdit2.Text;
Item.NeedDescriptor := True;
end;
end;
Label3.Caption := 'Общее количество элементов: ' + IntToStr(Writer.Count);
Label4.Caption := 'Общий размер элементов: ' + IntToStr(TotalSize);
Writer.OnProgress := OnProgress;
SetEnabledState(False);
try
Heap := GetHeapStatus;
Inc(InitialHeapSize, Heap.Overhead + Heap.TotalAllocated);
MaxHeapSize := 0;
AverageHeapSize := 0;
TotalGetHeapStatusCount := 0;
StopProcess := False;
TicCount := GetTickCount;
Writer.BuildZip(
IncludeTrailingPathDelimiter(LabeledEdit1.Text) + 'FWZipTest.zip');
if TotalGetHeapStatusCount = 0 then
TotalGetHeapStatusCount := 1;
ShowMessage(Format(
'Пиковый расход памяти: %d байт' + sLineBreak +
'Средний расход памяти: %d байт' + sLineBreak +
'Общее время работы: %d секунд',
[MaxHeapSize, AverageHeapSize div TotalGetHeapStatusCount,
(GetTickCount - TicCount) div 1000]));
finally
SetEnabledState(True);
end;
finally
Writer.Free;
ClearZipData;
end;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
if OpenDialog1.Execute then
LabeledEdit3.Text := OpenDialog1.FileName;
end;
procedure TForm1.Button4Click(Sender: TObject);
var
I: Integer;
TotalSize: Int64;
Heap: THeapStatus;
TicCount: DWORD;
Path: string;
Reader: TFWZipReader;
begin
SetLength(Path, MAX_PATH);
Path := LabeledEdit3.Text;
Path := ChangeFileExt(Path, '');
Reader := TFWZipReader.Create;
try
Reader.LoadFromFile(LabeledEdit3.Text);
TotalSize := 0;
for I := 0 to Reader.Count - 1 do
Inc(TotalSize, Reader[I].UncompressedSize);
Label3.Caption := 'Общее количество элементов: ' + IntToStr(Reader.Count);
Label4.Caption := 'Общий размер элементов: ' + IntToStr(TotalSize);
Reader.OnProgress := OnProgress;
if LabeledEdit4.Text <> '' then
Reader.PasswordList.Add(LabeledEdit4.Text);
SetEnabledState(False);
try
Heap := GetHeapStatus;
InitialHeapSize := Heap.Overhead + Heap.TotalAllocated;
MaxHeapSize := 0;
AverageHeapSize := 0;
TotalGetHeapStatusCount := 0;
StopProcess := False;
Memo1.Lines.Clear;
TicCount := GetTickCount;
if TButton(Sender).Tag = 0 then
Reader.ExtractAll(Path)
else
Reader.Check;
if TotalGetHeapStatusCount = 0 then
TotalGetHeapStatusCount := 1;
ShowMessage(Format(
'Пиковый расход памяти: %d байт' + sLineBreak +
'Средний расход памяти: %d байт' + sLineBreak +
'Общее время работы: %d секунд',
[MaxHeapSize, AverageHeapSize div TotalGetHeapStatusCount,
(GetTickCount - TicCount) div 1000]));
finally
SetEnabledState(True);
end;
finally
Reader.Free;
ClearZipData;
end;
end;
procedure TForm1.Button5Click(Sender: TObject);
begin
StopProcess := True;
end;
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
LabeledEdit2.Enabled := CheckBox1.Checked;
end;
procedure TForm1.CheckBox2Click(Sender: TObject);
begin
LabeledEdit4.Enabled := CheckBox2.Checked;
end;
procedure TForm1.ClearZipData;
begin
Label1.Caption := 'Текущий расход памяти: 0 байт';
Label2.Caption := 'Пиковый расход памяти: 0 байт';
Label3.Caption := 'Общее количество элементов: 0';
Label4.Caption := 'Общий размер элементов: 0';
Label5.Caption := '';
end;
procedure TForm1.LabeledEdit1Change(Sender: TObject);
begin
Button2.Enabled := DirectoryExistsUTF8(LabeledEdit1.Text); { *Converted from DirectoryExists* }
end;
procedure TForm1.LabeledEdit3Change(Sender: TObject);
begin
Button4.Enabled := FileExistsUTF8(LabeledEdit3.Text); { *Converted from FileExists* }
end;
procedure TForm1.OnProgress(Sender: TObject; const FileName: string; Percent,
TotalPercent: Byte; var Cancel: Boolean; ProgressState: TProgressState);
const
p: array [TProgressState] of string = ('psStart', 'psInitialization',
'psInProgress', 'psFinalization', 'psEnd', 'psException');
begin
Cancel := StopProcess;
Label5.Caption := Format('(%d) %s', [Percent, FileName]);
ProgressBar1.Position := Percent;
ProgressBar2.Position := TotalPercent;
Memo1.Lines.Add(Format('%s - %s percent %d total %d',
[FileName, P[ProgressState], Percent, TotalPercent]));
UpdateMemoryStatus;
end;
procedure TForm1.SetEnabledState(Value: Boolean);
begin
Button1.Enabled := Value;
Button2.Enabled := Value;
Button3.Enabled := Value;
Button4.Enabled := Value;
Button5.Visible := not Value;
Button6.Enabled := Value;
LabeledEdit1.Enabled := Value;
LabeledEdit2.Enabled := Value;
LabeledEdit3.Enabled := Value;
LabeledEdit4.Enabled := Value;
CheckBox1.Enabled := Value;
CheckBox2.Enabled := Value;
end;
procedure TForm1.UpdateMemoryStatus;
var
HeapStatus: THeapStatus;
HeapSize: Int64;
begin
HeapStatus := GetHeapStatus;
HeapSize := HeapStatus.Overhead + HeapStatus.TotalAllocated;
Dec(HeapSize, InitialHeapSize);
if HeapSize > MaxHeapSize then
MaxHeapSize := HeapSize;
Inc(TotalGetHeapStatusCount);
Inc(AverageHeapSize, HeapSize);
Label1.Caption := 'Текущий расход памяти: ' + IntToStr(HeapSize) + ' байт';
Label2.Caption := 'Пиковый расход памяти: ' + IntToStr(MaxHeapSize) + ' байт';
Application.ProcessMessages;
Application.ProcessMessages;
end;
end.

View File

@ -0,0 +1,333 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : BuildWithException
// * Purpose : Äåìîíñòðàöèÿ ðàáîòû ñ èñêëþ÷åíèÿìè
// * : ïðè ñîçäàíèè è ðàñïàêîâêå àðõèâà
// * Author : Àëåêñàíäð (Rouse_) Áàãåëü
// * Copyright : © Fangorn Wizards Lab 1998 - 2013.
// * Version : 1.0.10
// * Home Page : http://rouse.drkb.ru
// * Home Blog : http://alexander-bagel.blogspot.ru
// ****************************************************************************
// * Stable Release : http://rouse.drkb.ru/components.php#fwzip
// * Latest Source : https://github.com/AlexanderBagel/FWZip
// ****************************************************************************
//
// Èñïîëüçóåìûå èñòî÷íèêè:
// ftp://ftp.info-zip.org/pub/infozip/doc/appnote-iz-latest.zip
// http://zlib.net/zlib-1.2.5.tar.gz
// http://www.base2ti.com/
//
// Äàííûé ïðèìåð ïîêàçûâàåò ðàáîòó ñ ðàçëè÷íûìè îøèáêàìè ìîãóùèìè âîçíèêíóòü
// â ïðîöåññå ñîçäàíèÿ è ðàñïàêîâêè àðõèâà, à òàê-æå ñïîñîáû èõ îáðàáîòêè.
program BuildWithException;
{$APPTYPE CONSOLE}
uses
Windows,
Classes,
SysUtils,
TypInfo,
FWZipConsts,
FWZipWriter,
FWZipReader;
var
Writer: TFWZipWriter;
Reader: TFWZipReader;
Method: TMethod;
hOFStruct: TOFStruct;
hFile: THandle;
//
// Ïðîöåäóðà âûâîäèò ðåçóëüòàò ðàáîòû ôóíêöèè BuildZip
// =============================================================================
procedure ShowBuildResult(Value: TBuildZipResult);
begin
Writeln(GetEnumName(TypeInfo(TBuildZipResult), Integer(Value)));
end;
//
// Ïðîöåäóðà âûâîäèò ðåçóëüòàò ðàáîòû ôóíêöèè Extract
// =============================================================================
procedure ShowManualExtractResult(const ElementName: string;
Value: TExtractResult);
begin
Writeln(Format('%s -> %s', [ElementName,
GetEnumName(TypeInfo(TExtractResult), Integer(Value))]));
end;
//
// ñìîòðè îïèñàíèå îáðàáîò÷èêà íèæå
// =============================================================================
procedure OnException1(Self, Sender: TObject; E: Exception;
const ItemIndex: Integer; var Action: TExceptionAction;
var NewFilePath: string; NewFileData: TMemoryStream);
var
CurrentFilePath: string;
Src: THandleStream;
Dst: TFileStream;
hOFStruct: TOFStruct;
hFile: THandle;
begin
CurrentFilePath := string(TFWZipWriter(Sender)[ItemIndex].FilePath);
NewFilePath := ChangeFileExt(CurrentFilePath, '.tmp');
hFile := OpenFile(PAnsiChar(AnsiString(CurrentFilePath)),
hOFStruct, OF_READ);
try
Src := THandleStream.Create(hFile);
try
Dst := TFileStream.Create(NewFilePath, fmCreate);
try
Dst.CopyFrom(Src, 0);
finally
Dst.Free;
end;
finally
Src.Free;
end;
finally
CloseHandle(hFile);
end;
Action := eaUseNewFilePathAndDel;
end;
//
// ñìîòðè îïèñàíèå îáðàáîò÷èêà íèæå
// =============================================================================
procedure OnException2(Self, Sender: TObject; E: Exception;
const ItemIndex: Integer; var Action: TExceptionAction;
var NewFilePath: string; NewFileData: TMemoryStream);
begin
CloseHandle(hFile);
hFile := INVALID_HANDLE_VALUE;
Action := eaRetry;
end;
//
// ñìîòðè îïèñàíèå îáðàáîò÷èêà íèæå
// =============================================================================
procedure OnException3(Self, Sender: TObject; E: Exception;
const ItemIndex: Integer; var Action: TExceptionAction;
var NewFilePath: string; NewFileData: TMemoryStream);
var
Src: THandleStream;
hOFStruct: TOFStruct;
hFile: THandle;
begin
hFile := OpenFile(
PAnsiChar(AnsiString(TFWZipWriter(Sender)[ItemIndex].FilePath)),
hOFStruct, OF_READ);
try
Src := THandleStream.Create(hFile);
try
NewFileData.CopyFrom(Src, 0);
finally
Src.Free;
end;
finally
CloseHandle(hFile);
end;
Action := eaUseNewFileData;
end;
//
// ñìîòðè îïèñàíèå îáðàáîò÷èêà íèæå
// =============================================================================
procedure OnDuplicate(Self, Sender: TObject;
var Path: string; var Action: TDuplicateAction);
begin
Path := MakeUniqueName(Path);
Action := daUseNewFilePath;
end;
var
I: Integer;
begin
SetCurrentDir(ExtractFilePath(ParamStr(0)));
try
// Ñàìàÿ áàíàëüíàÿ îøèáêà ïðè ñîçäàíèè àðõèâà - ýòî îòñóòñòâèå äîñòóïà
// ê äîáàâëÿåìîìó â àðõèâ ôàéëó.
// Íàïðèìåð âîò òàêîé êîä ïûòàåòñÿ çààðõèâèðîâàòü ñîäåðæèìîå êîðíåâîé
// ïàïêè â êîòîðîé èñêóññòâåííî çàëî÷åí îäèí èç ýëåìåíòîâ
//  ýòîì ñëó÷àå âîçíèêíåò îøèáêà äîñòóïà ê çàëî÷åíîìó ôàéëó.
// Åñëè íå íàçíà÷åíû îáðàáîò÷èêè èñêëþ÷åíèé, òî òàêîé ôàéë áóäåò ïðîïóùåí
// (äåéñòâèå ïî óìîë÷àíèþ eaSkip) è ôóíêöèÿ BuildZip
// âåðíåò ñëåäóþùèå êîäû îøèáîê:
// brFailed - â ñëó÷àå åñëè â ïàïêå íåáûëî äðóãèõ ôàéëîâ
// êðîìå çàëî÷åííîãî (ò.å. â àðõèâ äîáàâëÿòü íå÷åãî)
// brPartialBuild - â ñëó÷àå åñëè â àðõèâ âñå-æå áûëè äîáàâëåíû êàêèå-ëèáî ôàéëû,
// íî íåêîòîðûå èç íèõ áûëè ïðîïóùåíû
Writer := TFWZipWriter.Create;
try
Writer.AddFolder('', '..\..\', '*.pas', False);
ForceDirectories('..\DemoResults\');
// ëî÷èì îäèí èç ôàéëîâ äëÿ äåìîíñòðàöèè
hFile := OpenFile(PAnsiChar(AnsiString('..\..\' + Writer[0].FileName)),
hOFStruct, OF_WRITE);
try
Write('BuildWithException1.zip -> ');
ShowBuildResult(Writer.BuildZip('..\DemoResults\BuildWithException1.zip'));
finally
CloseHandle(hFile);
end;
finally
Writer.Free;
end;
// óçíàòü êàêèå ôàéëû áûëè ïðîïóùåíû è ïîïûòàòüñÿ èñïðàâèòü äàííóþ ñèòóàöèþ
// ìîæíî ïåðåêðûòèåì ñîáûòèÿ OnException
// Â ñëåäóþùåì ïðèìåðå áóäåò ïîêàçàíî êàê âñå-æå îáðàáîòàòü òàêóþ îøèáêó
// è äîáàâèòü ïðîáëåìíûé ôàéë â àðõèâ
Writer := TFWZipWriter.Create;
try
Writer.AddFolder('', '..\..\', '*.pas', False);
ForceDirectories('..\DemoResults\');
// ëî÷èì îäèí èç ôàéëîâ äëÿ äåìîíñòðàöèè
hFile := OpenFile(PAnsiChar(AnsiString('..\..\' + Writer[0].FileName)),
hOFStruct, OF_WRITE);
try
// Íàçíà÷àåì îáðàáîò÷èê ÷åðåç êîòîðûé ìû áóäåì îáðàáàòûâàòü îøèáêó
//  îáðàáîò÷èêå OnException1 áóäåò ñîçäàâàòüñÿ êîïèÿ ôàéëà
// ïîñëå ÷åãî ìû óêàæåì â ïàðàìåòðå NewFilePath íîâûé ïóòü ê ôàéëó,
// à ñâîéñòâî Action âûñòàâèì eaUseNewFilePathAndDel
// Òàêèì îáðàçîì ìû óâåäîìëÿåì FWZip ÷òî íóæíî ïîâòîðèòü ïîïûòêó
// àðõèâàöèè ôàéëà, ïðè ýòîì íåîáõîäèìî èñïîëüçîâàòü íîâûé ïóòü ê ôàéëó,
// ïîñëå ÷åãî äàííûé ôàéë ñëåäóåò óäàëèòü.
Method.Code := @OnException1;
Method.Data := Writer;
Writer.OnException := TZipBuildExceptionEvent(Method);
Write('BuildWithException2.zip -> ');
ShowBuildResult(Writer.BuildZip('..\DemoResults\BuildWithException2.zip'));
// âòîðîé âàðèàíò, îáðàáîòêè ïîêàçàí â îáðàáîò÷èêå OnException2
// â íåì ìû ñíèìàåì èññêóñòâåííóþ áëîêèðîâêó ôàéëà è âûñòàâëÿåì
// ñâîéñòâî Action â eaRetry.
// Òàêèì îáðàçîì ìû óâåäîìëÿåì FWZip ÷òî íóæíî ïîâòîðèòü ïîïûòêó
// àðõèâàöèè ôàéëà
Method.Code := @OnException2;
Method.Data := Writer;
Writer.OnException := TZipBuildExceptionEvent(Method);
Write('BuildWithException3.zip -> ');
ShowBuildResult(Writer.BuildZip('..\DemoResults\BuildWithException3.zip'));
// äëÿ äåìîíñòðàöèè âîçâðàùàåì áëîêèðîâêó íà ìåñòî
if hFile = INVALID_HANDLE_VALUE then
hFile := OpenFile(PAnsiChar(AnsiString('..\..\' + Writer[0].FileName)),
hOFStruct, OF_WRITE);
// òðåòèé âàðèàíò, îáðàáîòêè ïîêàçàí â îáðàáîò÷èêå OnException3
// â íåì ìû çàãðóæàåì ëþáûì ñïîñîáîì äàííûå ôàéëà â ñòðèì è
// âûñòàâëÿåì ñâîéñòâî Action â eaUseNewFileData
// Òàêèì îáðàçîì äàííûå áóäóò áðàòüñÿ íåïîñðåäñòâåííî èç ñòðèìà
// NewFileData
Method.Code := @OnException3;
Method.Data := Writer;
Writer.OnException := TZipBuildExceptionEvent(Method);
Write('BuildWithException4.zip -> ');
ShowBuildResult(Writer.BuildZip('..\DemoResults\BuildWithException4.zip'));
// îðèåíòèðóÿñü íà òèï èñêëþ÷åíèÿ ìîæíî ðåàëèçîâûâàòü ðàçíóëþ ëîãèêó îáðàáîò÷èêà.
// åñëè âû íå çíàåòå êàê îáðàáîòàòü òî èëè èíîå èñêëþ÷åíèå,
// ñëåäóåò âûñòàâèòü ñâîéñòâî Action â eaSkip (âûñòàâëåíî ïî óìîë÷àíèþ)
// äëÿ òîãî ÷òîáû ïðîïóñòèòü ïðîáëåìíûé ôàéë, èëè eaAbort,
// ïðåðâàâ òàêèì îáðàçîì ñîçäàíèå àðõèâà.
finally
if hFile <> INVALID_HANDLE_VALUE then
CloseHandle(hFile);
end;
finally
Writer.Free;
end;
// Ïðè ðàñïàêîâêå ÷àñòîé îøèáî÷íîé ñèòóàöèåé ÿâëÿåòñÿ ïîïûòêà
// ïåðåçàïèñè óæå ñóùåñòâóþùåãî íà äèñêå ôàéëà, ëèáî îøèáêà
// ðàñïàêîâêè àðõèâà, ñîçäàííîãî ñòîðîííèì àðõèâàòîðîì.
// Îáðàáîòêà îøèáêè ðàñïàêîâêè ðåøàåòñÿ èñïîëüçîâàíèåì áîëåå
// íîâîé âåðñèè ZLib (ñì. Readme.txt ïóíêò 9)
// Âîçíèêíîâåíèå îøèáêè ïî äðóãèì ïðè÷èíàì ïðèâåäåò ê âîçíèêíîâåíèþ
// ñîáûòèÿ OnException. Åñëè äàííîå ñîáûòèå íå ïåðåêðûòî,
// òî â ñëó÷àå âûçîâà ìåòîäà TFWZipReader.ExtractAll
// ðàñïàêîâêà àðõèâà áóäåò îñòàíîâëåíà.
//  ñëó÷àå, åñëè äàííîå ñîáûòèå ïåðåêðûòî, òî ðåøåíèå
// î îñòàíîâêå ðàñïàêîâêè äîëæåí ïðèíèìàòü ïðîãðàììèñò,
// âûñòàâëåíèåì ôëàãà Handled:
// (Handled = True, èñêëþ÷åíèå îáðàáîòàíî, ìîæíî ïðîäîëæèòü ðàñïàêîâêó)
// äëÿ äåìîíñòðàöèè ïðîýìóëèðóåì îøèáêó ïåðåçàïèñè,
// äëÿ ýòîãî íóæíî äâàæäû ðàñïàêîâàòü îäèí è òîò-æå àðõèâ
// â îäíó è òó-æå ïàïêó
Reader := TFWZipReader.Create;
try
Reader.LoadFromFile('..\DemoResults\BuildWithException1.zip');
ForceDirectories('..\DemoResults\BuildWithExceptionUnpack\');
// ðàñïàêîâûâàåì ïåðâûé ðàç
Reader.ExtractAll('..\DemoResults\BuildWithExceptionUnpack\');
// òåïåðü ïðîáóåì ðàñïàêîâàòü ïîâòîðíî.
// èñêëþ÷åíèÿ â äàííîì ñëó÷àå íå ïðîèçîéäåò, íî âñå ýëåìåíòû áóäóò ïðîïóùåíû
Reader.ExtractAll('..\DemoResults\BuildWithExceptionUnpack\');
// ïðîïóñê ýëåìåíòîâ ìîæíî óâèäåòü è ïðè ðó÷íîé ðàñïàêîâêå.
// ò.ê. âûçîâ Reader[I].Extract â îòëè÷èå îò Reader.ExtractAll
// âîçâðàùàåò ðåçóëüòàò
Writeln('Manual extract:');
for I := 0 to Reader.Count - 1 do
ShowManualExtractResult(
string(Reader[I].FileName),
Reader[I].Extract('..\DemoResults\BuildWithExceptionUnpack\', ''));
// êàê ìîæíî çàìåòèòü, âñå ýëåìåíòû äåéñòâèòåëüíî áûëè ïðîïóùåíû
// (Reader[I].Extract âåðíóë erSkiped äëÿ êàæäîãî ýëåìåíòà)
// Äëÿ îáðàáîòêè äàííîé ñèòóàöèè â ðåæèìå àâòîìàòè÷åñêîé ðàñïàêîâêè (ExtractAll)
// íåîáõîäèìî ïåðåêðûòü ñîáûòèå OnDuplicate ó êëàññà TFWZipReader.
//  ñëó÷àå ðó÷íîé ðàñïàêîâêè, ïåðåêðûâàòü ñîáûòèå OnDuplicate òðåáóåòñÿ
// ó êàæäîãî ýëåìåíòà (Reader.Items[èíäåêñ ýëåìåíòà].OnDuplicate)
Method.Code := @OnDuplicate;
Method.Data := Reader;
Reader.OnDuplicate := TZipDuplicateEvent(Method);
// òåïåðü ïîïðîáóåì ïîâòîðíî ðàñïàêîâàòü.
// ïðè âîçíèêíîâåíèè ñîáûòèÿ OnDuplicate â îáðàáîò÷èêå ýëåìåíòó áóäåò
// íàçíà÷åíî íîâîå èìÿ è ïàðàìåòð Action áóäåò âûñòàâëåí â daUseNewFilePath.
// Òàêèì îáðàçîì ìû óêàæåì TFWZipReader-ó ÷òî íåîáõîäèìî ðàñïàêîâàòü
// ôàéë ñ íîâûì èìåíåì...
// (ò.å. ïîëó÷èì àíàëîã ñîçäàíèÿ ôàéëîâ â ïðîâîäíèêå Windows, íàïðèìåð:
// New folder -> New folder (2) -> New folder (3) è ò.ä.)
Reader.ExtractAll('..\DemoResults\BuildWithExceptionUnpack\');
finally
Reader.Free;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.

View File

@ -0,0 +1,619 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{D336C006-9204-4B8B-A8C2-88CAB9F2693C}</ProjectGuid>
<MainSource>BuildWithException.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Console</AppType>
<FrameworkType>None</FrameworkType>
<ProjectVersion>14.6</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_S>false</DCC_S>
<DCC_K>false</DCC_K>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;UIDeviceFamily=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;UISupportedInterfaceOrientations=;CFBundleExecutable=;CFBundleResourceSpecification=;LSRequiresIPhoneOS=;CFBundleInfoDictionaryVersion=;CFBundleDevelopmentRegion=</VerInfo_Keys>
<DCC_F>false</DCC_F>
<VerInfo_Locale>1049</VerInfo_Locale>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace)</DCC_Namespace>
<DCC_ImageBase>00400000</DCC_ImageBase>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<DCC_Namespace>System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_DebugInformation>false</DCC_DebugInformation>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">BuildWithException.dpr</Source>
</Source>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
<VersionInfoKeys Name="CFBundleName"/>
<VersionInfoKeys Name="CFBundleDisplayName"/>
<VersionInfoKeys Name="UIDeviceFamily"/>
<VersionInfoKeys Name="CFBundleIdentifier"/>
<VersionInfoKeys Name="CFBundleVersion"/>
<VersionInfoKeys Name="CFBundlePackageType"/>
<VersionInfoKeys Name="CFBundleSignature"/>
<VersionInfoKeys Name="CFBundleAllowMixedLocalizations"/>
<VersionInfoKeys Name="UISupportedInterfaceOrientations"/>
<VersionInfoKeys Name="CFBundleExecutable"/>
<VersionInfoKeys Name="CFBundleResourceSpecification"/>
<VersionInfoKeys Name="LSRequiresIPhoneOS"/>
<VersionInfoKeys Name="CFBundleInfoDictionaryVersion"/>
<VersionInfoKeys Name="CFBundleDevelopmentRegion"/>
</VersionInfoKeys>
</Delphi.Personality>
<Platforms>
<Platform value="OSX32">False</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>
<!-- EurekaLog First Line
[Exception Log]
EurekaLog Version=6104
Activate=0
Activate Handle=1
Save Log File=1
Foreground Tab=0
Freeze Activate=0
Freeze Timeout=0
SMTP From=eurekalog@email.com
SMTP Host=
SMTP Port=25
SMTP UserID=
SMTP Password=
Append to Log=0
TerminateBtn Operation=2
Errors Number=32
Errors Terminate=3
Email Address=
Email Object=
Email Send Options=0
Output Path=
Encrypt Password=
AutoCloseDialogSecs=0
WebSendMode=0
SupportULR=
HTMLLayout Count=15
HTMLLine0="%U003Chtml%U003E"
HTMLLine1=" %U003Chead%U003E"
HTMLLine2=" %U003C/head%U003E"
HTMLLine3=" %U003Cbody TopMargin=10 LeftMargin=10%U003E"
HTMLLine4=" %U003Ctable width="100%%" border="0"%U003E"
HTMLLine5=" %U003Ctr%U003E"
HTMLLine6=" %U003Ctd nowrap%U003E"
HTMLLine7=" %U003Cfont face="Lucida Console, Courier" size="2"%U003E"
HTMLLine8=" %U003C%%HTML_TAG%%%U003E"
HTMLLine9=" %U003C/font%U003E"
HTMLLine10=" %U003C/td%U003E"
HTMLLine11=" %U003C/tr%U003E"
HTMLLine12=" %U003C/table%U003E"
HTMLLine13=" %U003C/body%U003E"
HTMLLine14="%U003C/html%U003E"
AutoCrashOperation=2
AutoCrashNumber=10
AutoCrashMinutes=1
WebURL=
WebUserID=
WebPassword=
WebPort=0
AttachedFiles=
ProxyURL=
ProxyUser=
ProxyPassword=
ProxyPort=8080
TrakerUser=
TrakerPassword=
TrakerAssignTo=
TrakerProject=
TrakerCategory=
TrakerTrialID=
ZipPassword=
PreBuildEvent=
PostSuccessfulBuildEvent=
PostFailureBuildEvent=
ExceptionDialogType=2
Count=0
EMail Message Line Count=0
loNoDuplicateErrors=0
loAppendReproduceText=0
loDeleteLogAtVersionChange=0
loAddComputerNameInLogFileName=0
loSaveModulesAndProcessesSections=1
loSaveAssemblerAndCPUSections=1
soAppStartDate=1
soAppName=1
soAppVersionNumber=1
soAppParameters=1
soAppCompilationDate=1
soAppUpTime=1
soExcDate=1
soExcAddress=1
soExcModuleName=1
soExcModuleVersion=1
soExcType=1
soExcMessage=1
soExcID=1
soExcCount=1
soExcStatus=1
soExcNote=1
soUserID=1
soUserName=1
soUserEmail=1
soUserPrivileges=1
soUserCompany=1
soActCtlsFormClass=1
soActCtlsFormText=1
soActCtlsControlClass=1
soActCtlsControlText=1
soCmpName=1
soCmpTotalMemory=1
soCmpFreeMemory=1
soCmpTotalDisk=1
soCmpFreeDisk=1
soCmpSysUpTime=1
soCmpProcessor=1
soCmpDisplayMode=1
soCmpDisplayDPI=1
soCmpVideoCard=1
soCmpPrinter=1
soOSType=1
soOSBuildN=1
soOSUpdate=1
soOSLanguage=1
soOSCharset=1
soNetIP=1
soNetSubmask=1
soNetGateway=1
soNetDNS1=1
soNetDNS2=1
soNetDHCP=1
soCustomData=1
sndShowSendDialog=1
sndShowSuccessFailureMsg=0
sndSendEntireLog=0
sndSendXMLLogCopy=0
sndSendScreenshot=1
sndUseOnlyActiveWindow=0
sndSendLastHTMLPage=1
sndSendInSeparatedThread=0
sndAddDateInFileName=0
sndAddComputerNameInFileName=0
edoSendErrorReportChecked=1
edoAttachScreenshotChecked=1
edoShowCopyToClipOption=1
edoShowDetailsButton=1
edoShowInDetailedMode=0
edoShowInTopMostMode=0
edoUseEurekaLogLookAndFeel=0
edoShowSendErrorReportOption=1
edoShowAttachScreenshotOption=1
edoShowCustomButton=0
csoShowDLLs=1
csoShowBPLs=1
csoShowBorlandThreads=1
csoShowWindowsThreads=1
csoDoNotStoreProcNames=0
boPauseBorlandThreads=0
boDoNotPauseMainThread=0
boPauseWindowsThreads=0
boUseMainModuleOptions=1
boCopyLogInCaseOfError=1
boSaveCompressedCopyInCaseOfError=0
boHandleSafeCallExceptions=1
boCallRTLExceptionEvent=0
boCatchHandledExceptions=0
loCatchLeaks=0
loGroupsSonLeaks=1
loHideBorlandLeaks=1
loFreeAllLeaks=1
loCatchLeaksExceptions=1
cfoReduceFileSize=1
cfoCheckFileCorruption=0
cfoUseEL7=0
Count mtInformationMsgCaption=1
mtInformationMsgCaption0="Information."
Count mtQuestionMsgCaption=1
mtQuestionMsgCaption0="Question."
Count mtErrorMsgCaption=1
mtErrorMsgCaption0="Error."
Count mtDialog_Caption=1
mtDialog_Caption0="Error occurred"
Count mtDialog_ErrorMsgCaption=2
mtDialog_ErrorMsgCaption0="An error has occurred during program execution."
mtDialog_ErrorMsgCaption1="Please read the following information for further details."
Count mtDialog_GeneralCaption=1
mtDialog_GeneralCaption0="General"
Count mtDialog_GeneralHeader=1
mtDialog_GeneralHeader0="General Information"
Count mtDialog_CallStackCaption=1
mtDialog_CallStackCaption0="Call Stack"
Count mtDialog_CallStackHeader=1
mtDialog_CallStackHeader0="Call Stack Information"
Count mtDialog_ModulesCaption=1
mtDialog_ModulesCaption0="Modules"
Count mtDialog_ModulesHeader=1
mtDialog_ModulesHeader0="Modules Information"
Count mtDialog_ProcessesCaption=1
mtDialog_ProcessesCaption0="Processes"
Count mtDialog_ProcessesHeader=1
mtDialog_ProcessesHeader0="Processes Information"
Count mtDialog_AsmCaption=1
mtDialog_AsmCaption0="Assembler"
Count mtDialog_AsmHeader=1
mtDialog_AsmHeader0="Assembler Information"
Count mtDialog_CPUCaption=1
mtDialog_CPUCaption0="CPU"
Count mtDialog_CPUHeader=1
mtDialog_CPUHeader0="CPU Information"
Count mtDialog_OKButtonCaption=1
mtDialog_OKButtonCaption0="%U0026OK"
Count mtDialog_TerminateButtonCaption=1
mtDialog_TerminateButtonCaption0="%U0026Terminate"
Count mtDialog_RestartButtonCaption=1
mtDialog_RestartButtonCaption0="%U0026Restart"
Count mtDialog_DetailsButtonCaption=1
mtDialog_DetailsButtonCaption0="%U0026Details"
Count mtDialog_CustomButtonCaption=1
mtDialog_CustomButtonCaption0="%U0026Help"
Count mtDialog_SendMessage=1
mtDialog_SendMessage0="%U0026Send this error via Internet"
Count mtDialog_ScreenshotMessage=1
mtDialog_ScreenshotMessage0="%U0026Attach a Screenshot image"
Count mtDialog_CopyMessage=1
mtDialog_CopyMessage0="%U0026Copy to Clipboard"
Count mtDialog_SupportMessage=1
mtDialog_SupportMessage0="Go to the Support Page"
Count mtMSDialog_ErrorMsgCaption=1
mtMSDialog_ErrorMsgCaption0="The application has encountered a problem. We are sorry for the inconvenience."
Count mtMSDialog_RestartCaption=1
mtMSDialog_RestartCaption0="Restart application."
Count mtMSDialog_TerminateCaption=1
mtMSDialog_TerminateCaption0="Terminate application."
Count mtMSDialog_PleaseCaption=1
mtMSDialog_PleaseCaption0="Please tell us about this problem."
Count mtMSDialog_DescriptionCaption=1
mtMSDialog_DescriptionCaption0="We have created an error report that you can send to us. We will treat this report as confidential and anonymous."
Count mtMSDialog_SeeDetailsCaption=1
mtMSDialog_SeeDetailsCaption0="To see what data the error report contains,"
Count mtMSDialog_SeeClickCaption=1
mtMSDialog_SeeClickCaption0="click here."
Count mtMSDialog_HowToReproduceCaption=1
mtMSDialog_HowToReproduceCaption0="What were you doing when the problem happened (optional)?"
Count mtMSDialog_EmailCaption=1
mtMSDialog_EmailCaption0="Email address (optional):"
Count mtMSDialog_SendButtonCaption=1
mtMSDialog_SendButtonCaption0="%U0026Send Error Report"
Count mtMSDialog_NoSendButtonCaption=1
mtMSDialog_NoSendButtonCaption0="%U0026Don't Send"
Count mtLog_AppHeader=1
mtLog_AppHeader0="Application"
Count mtLog_AppStartDate=1
mtLog_AppStartDate0="Start Date"
Count mtLog_AppName=1
mtLog_AppName0="Name/Description"
Count mtLog_AppVersionNumber=1
mtLog_AppVersionNumber0="Version Number"
Count mtLog_AppParameters=1
mtLog_AppParameters0="Parameters"
Count mtLog_AppCompilationDate=1
mtLog_AppCompilationDate0="Compilation Date"
Count mtLog_AppUpTime=1
mtLog_AppUpTime0="Up Time"
Count mtLog_ExcHeader=1
mtLog_ExcHeader0="Exception"
Count mtLog_ExcDate=1
mtLog_ExcDate0="Date"
Count mtLog_ExcAddress=1
mtLog_ExcAddress0="Address"
Count mtLog_ExcModuleName=1
mtLog_ExcModuleName0="Module Name"
Count mtLog_ExcModuleVersion=1
mtLog_ExcModuleVersion0="Module Version"
Count mtLog_ExcType=1
mtLog_ExcType0="Type"
Count mtLog_ExcMessage=1
mtLog_ExcMessage0="Message"
Count mtLog_ExcID=1
mtLog_ExcID0="ID"
Count mtLog_ExcCount=1
mtLog_ExcCount0="Count"
Count mtLog_ExcStatus=1
mtLog_ExcStatus0="Status"
Count mtLog_ExcNote=1
mtLog_ExcNote0="Note"
Count mtLog_UserHeader=1
mtLog_UserHeader0="User"
Count mtLog_UserID=1
mtLog_UserID0="ID"
Count mtLog_UserName=1
mtLog_UserName0="Name"
Count mtLog_UserEmail=1
mtLog_UserEmail0="Email"
Count mtLog_UserCompany=1
mtLog_UserCompany0="Company"
Count mtLog_UserPrivileges=1
mtLog_UserPrivileges0="Privileges"
Count mtLog_ActCtrlsHeader=1
mtLog_ActCtrlsHeader0="Active Controls"
Count mtLog_ActCtrlsFormClass=1
mtLog_ActCtrlsFormClass0="Form Class"
Count mtLog_ActCtrlsFormText=1
mtLog_ActCtrlsFormText0="Form Text"
Count mtLog_ActCtrlsControlClass=1
mtLog_ActCtrlsControlClass0="Control Class"
Count mtLog_ActCtrlsControlText=1
mtLog_ActCtrlsControlText0="Control Text"
Count mtLog_CmpHeader=1
mtLog_CmpHeader0="Computer"
Count mtLog_CmpName=1
mtLog_CmpName0="Name"
Count mtLog_CmpTotalMemory=1
mtLog_CmpTotalMemory0="Total Memory"
Count mtLog_CmpFreeMemory=1
mtLog_CmpFreeMemory0="Free Memory"
Count mtLog_CmpTotalDisk=1
mtLog_CmpTotalDisk0="Total Disk"
Count mtLog_CmpFreeDisk=1
mtLog_CmpFreeDisk0="Free Disk"
Count mtLog_CmpSystemUpTime=1
mtLog_CmpSystemUpTime0="System Up Time"
Count mtLog_CmpProcessor=1
mtLog_CmpProcessor0="Processor"
Count mtLog_CmpDisplayMode=1
mtLog_CmpDisplayMode0="Display Mode"
Count mtLog_CmpDisplayDPI=1
mtLog_CmpDisplayDPI0="Display DPI"
Count mtLog_CmpVideoCard=1
mtLog_CmpVideoCard0="Video Card"
Count mtLog_CmpPrinter=1
mtLog_CmpPrinter0="Printer"
Count mtLog_OSHeader=1
mtLog_OSHeader0="Operating System"
Count mtLog_OSType=1
mtLog_OSType0="Type"
Count mtLog_OSBuildN=1
mtLog_OSBuildN0="Build #"
Count mtLog_OSUpdate=1
mtLog_OSUpdate0="Update"
Count mtLog_OSLanguage=1
mtLog_OSLanguage0="Language"
Count mtLog_OSCharset=1
mtLog_OSCharset0="Charset"
Count mtLog_NetHeader=1
mtLog_NetHeader0="Network"
Count mtLog_NetIP=1
mtLog_NetIP0="IP Address"
Count mtLog_NetSubmask=1
mtLog_NetSubmask0="Submask"
Count mtLog_NetGateway=1
mtLog_NetGateway0="Gateway"
Count mtLog_NetDNS1=1
mtLog_NetDNS10="DNS 1"
Count mtLog_NetDNS2=1
mtLog_NetDNS20="DNS 2"
Count mtLog_NetDHCP=1
mtLog_NetDHCP0="DHCP"
Count mtLog_CustInfoHeader=1
mtLog_CustInfoHeader0="Custom Information"
Count mtCallStack_Address=1
mtCallStack_Address0="Address"
Count mtCallStack_Name=1
mtCallStack_Name0="Module"
Count mtCallStack_Unit=1
mtCallStack_Unit0="Unit"
Count mtCallStack_Class=1
mtCallStack_Class0="Class"
Count mtCallStack_Procedure=1
mtCallStack_Procedure0="Procedure/Method"
Count mtCallStack_Line=1
mtCallStack_Line0="Line"
Count mtCallStack_MainThread=1
mtCallStack_MainThread0="Main"
Count mtCallStack_ExceptionThread=1
mtCallStack_ExceptionThread0="Exception Thread"
Count mtCallStack_RunningThread=1
mtCallStack_RunningThread0="Running Thread"
Count mtCallStack_CallingThread=1
mtCallStack_CallingThread0="Calling Thread"
Count mtCallStack_ThreadID=1
mtCallStack_ThreadID0="ID"
Count mtCallStack_ThreadPriority=1
mtCallStack_ThreadPriority0="Priority"
Count mtCallStack_ThreadClass=1
mtCallStack_ThreadClass0="Class"
Count mtCallStack_LeakCaption=1
mtCallStack_LeakCaption0="Memory Leak"
Count mtCallStack_LeakData=1
mtCallStack_LeakData0="Data"
Count mtCallStack_LeakType=1
mtCallStack_LeakType0="Type"
Count mtCallStack_LeakSize=1
mtCallStack_LeakSize0="Total size"
Count mtCallStack_LeakCount=1
mtCallStack_LeakCount0="Count"
Count mtSendDialog_Caption=1
mtSendDialog_Caption0="Send."
Count mtSendDialog_Message=1
mtSendDialog_Message0="Message"
Count mtSendDialog_Resolving=1
mtSendDialog_Resolving0="Resolving DNS..."
Count mtSendDialog_Login=1
mtSendDialog_Login0="Login..."
Count mtSendDialog_Connecting=1
mtSendDialog_Connecting0="Connecting with server..."
Count mtSendDialog_Connected=1
mtSendDialog_Connected0="Connected with server."
Count mtSendDialog_Sending=1
mtSendDialog_Sending0="Sending message..."
Count mtSendDialog_Sent=1
mtSendDialog_Sent0="Message sent."
Count mtSendDialog_SelectProject=1
mtSendDialog_SelectProject0="Select project..."
Count mtSendDialog_Searching=1
mtSendDialog_Searching0="Searching..."
Count mtSendDialog_Modifying=1
mtSendDialog_Modifying0="Modifying..."
Count mtSendDialog_Disconnecting=1
mtSendDialog_Disconnecting0="Disconnecting..."
Count mtSendDialog_Disconnected=1
mtSendDialog_Disconnected0="Disconnected."
Count mtReproduceDialog_Caption=1
mtReproduceDialog_Caption0="Request"
Count mtReproduceDialog_Request=1
mtReproduceDialog_Request0="Please describe the steps to reproduce the error:"
Count mtReproduceDialog_OKButtonCaption=1
mtReproduceDialog_OKButtonCaption0="%U0026OK"
Count mtModules_Handle=1
mtModules_Handle0="Handle"
Count mtModules_Name=1
mtModules_Name0="Name"
Count mtModules_Description=1
mtModules_Description0="Description"
Count mtModules_Version=1
mtModules_Version0="Version"
Count mtModules_Size=1
mtModules_Size0="Size"
Count mtModules_LastModified=1
mtModules_LastModified0="Modified"
Count mtModules_Path=1
mtModules_Path0="Path"
Count mtProcesses_ID=1
mtProcesses_ID0="ID"
Count mtProcesses_Name=1
mtProcesses_Name0="Name"
Count mtProcesses_Description=1
mtProcesses_Description0="Description"
Count mtProcesses_Version=1
mtProcesses_Version0="Version"
Count mtProcesses_Memory=1
mtProcesses_Memory0="Memory"
Count mtProcesses_Priority=1
mtProcesses_Priority0="Priority"
Count mtProcesses_Threads=1
mtProcesses_Threads0="Threads"
Count mtProcesses_Path=1
mtProcesses_Path0="Path"
Count mtCPU_Registers=1
mtCPU_Registers0="Registers"
Count mtCPU_Stack=1
mtCPU_Stack0="Stack"
Count mtCPU_MemoryDump=1
mtCPU_MemoryDump0="Memory Dump"
Count mtSend_SuccessMsg=1
mtSend_SuccessMsg0="The message was sent successfully."
Count mtSend_FailureMsg=1
mtSend_FailureMsg0="Sorry, sending the message didn't work."
Count mtSend_BugClosedMsg=2
mtSend_BugClosedMsg0="These BUG is just closed."
mtSend_BugClosedMsg1="Contact the program support to obtain an update."
Count mtSend_UnknownErrorMsg=1
mtSend_UnknownErrorMsg0="Unknown error."
Count mtSend_InvalidLoginMsg=1
mtSend_InvalidLoginMsg0="Invalid login request."
Count mtSend_InvalidSearchMsg=1
mtSend_InvalidSearchMsg0="Invalid search request."
Count mtSend_InvalidSelectionMsg=1
mtSend_InvalidSelectionMsg0="Invalid selection request."
Count mtSend_InvalidInsertMsg=1
mtSend_InvalidInsertMsg0="Invalid insert request."
Count mtSend_InvalidModifyMsg=1
mtSend_InvalidModifyMsg0="Invalid modify request."
Count mtFileCrackedMsg=2
mtFileCrackedMsg0="This file is cracked."
mtFileCrackedMsg1="The application will be closed."
Count mtException_LeakMultiFree=1
mtException_LeakMultiFree0="Multi Free memory leak."
Count mtException_LeakMemoryOverrun=1
mtException_LeakMemoryOverrun0="Memory Overrun leak."
Count mtException_AntiFreeze=1
mtException_AntiFreeze0="The application seems to be frozen."
Count mtInvalidEmailMsg=1
mtInvalidEmailMsg0="Invalid email."
TextsCollection=English
EurekaLog Last Line -->

View File

@ -0,0 +1,218 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : UseExDataBlob
// * Purpose : Äåìîíñòðàöèÿ ðàáîòû ñ áëîêàìè ExData
// * Author : Àëåêñàíäð (Rouse_) Áàãåëü
// * Copyright : © Fangorn Wizards Lab 1998 - 2013.
// * Version : 1.0.10
// * Home Page : http://rouse.drkb.ru
// * Home Blog : http://alexander-bagel.blogspot.ru
// ****************************************************************************
// * Stable Release : http://rouse.drkb.ru/components.php#fwzip
// * Latest Source : https://github.com/AlexanderBagel/FWZip
// ****************************************************************************
//
// Èñïîëüçóåìûå èñòî÷íèêè:
// ftp://ftp.info-zip.org/pub/infozip/doc/appnote-iz-latest.zip
// http://zlib.net/zlib-1.2.5.tar.gz
// http://www.base2ti.com/
//
// Äàííûé ïðèìåð ïîêàçûâàåò ðàáîòó ñ áëîêàìè ExData.
// Èõ äîáàâëåíèå ïðè ñîçäàíèè àðõèâà è èçâëå÷åíèå.
// Äàííûå áëîêè ìîãóò ñîäåðæàòü ëþáûå äîïîëíèòåëüíûå ïàðàìåòðû ñâÿçàííûå
// ñ ýëåìåíòîì àðõèâà. Ñïèñîê çàðåçåðâèðîâàííûõ áëîêîâ ñì. â êîìåíòàðèè
// îáðàáîò÷èêà OnSaveExData.
program UseExDataBlob;
{$APPTYPE CONSOLE}
uses
SysUtils,
Classes,
FWZipWriter,
FWZipReader,
FWZipConsts;
const
TestExDataBlob: Cardinal = $DEADBEEF;
var
Writer: TFWZipWriter;
Reader: TFWZipReader;
Method: TMethod;
//
// Îáðàáîò÷èê ïðè ïîìîùè êîòîðîãî ìû äîáàâëÿåì áëîê ðàñøèðåííûõ äàííûõ ExData
// ê êàæäîìó ýëåìåíòó ìàññèâà
// =============================================================================
procedure OnSaveExData(Self, Sender: TObject; ItemIndex: Integer;
UserExDataBlockCount: Integer; var Tag: Word; Data: TStream);
var
RandomValue: Cardinal;
begin
// Ïðè äîáàâëåíèè áëîêà ðàñøèðåííûõ äàííûõ ñëåäóåò óêàçàòü åãî Òýã è
// çàïèñàòü ñàìè äàííûå â ñòðèì Data, ïðè ýòîì ðàçìåð Data íå ìîæåò
// ïðåâûñèòü çíà÷åíèå MAXWORD à çíà÷åíèå Òýã äîëæíî áûòü îòëè÷íî îò íóëÿ.
// Äàííûé îáðàáîò÷èê áóäåò âûçûâàòüñÿ äî òåõ ïîð, ïîêà âû íå óêàæåòå
// ÷òî áîëåå áëîêîâ äàííûõ íåò. Äëÿ ýòîãî íóæíî íå çàïîëíÿòü ñòðèì Data.
// Êîëè÷åñòâî âûçîâîâ îáðàáîò÷èêà äëÿ òåêóùåãî ýëåìåíòà ìîæíî óçíàòü ïî
// ïåðåìåííîé UserExDataBlockCount
// Îáðàòèòå âíèìàíèå, ñëåäóþùèå çíà÷åíèÿ òýãîâ çàðåçåðâèðîâàíû:
{
The current Header ID mappings defined by PKWARE are:
0x0001 ZIP64 extended information extra field
0x0007 AV Info
0x0008 Reserved for future Unicode file name data (PFS)
0x0009 OS/2 extended attributes (also Info-ZIP)
0x000a NTFS (Win9x/WinNT FileTimes)
0x000c OpenVMS (also Info-ZIP)
0x000d Unix
0x000e Reserved for file stream and fork descriptors
0x000f Patch Descriptor
0x0014 PKCS#7 Store for X.509 Certificates
0x0015 X.509 Certificate ID and Signature for
individual file
0x0016 X.509 Certificate ID for Central Directory
0x0017 Strong Encryption Header
0x0018 Record Management Controls
0x0019 PKCS#7 Encryption Recipient Certificate List
0x0065 IBM S/390 (Z390), AS/400 (I400) attributes
- uncompressed
0x0066 Reserved for IBM S/390 (Z390), AS/400 (I400)
attributes - compressed
The Header ID mappings defined by Info-ZIP and third parties are:
0x07c8 Info-ZIP Macintosh (old, J. Lee)
0x2605 ZipIt Macintosh (first version)
0x2705 ZipIt Macintosh v 1.3.5 and newer (w/o full filename)
0x2805 ZipIt Macintosh 1.3.5+
0x334d Info-ZIP Macintosh (new, D. Haase's 'Mac3' field)
0x4154 Tandem NSK
0x4341 Acorn/SparkFS (David Pilling)
0x4453 Windows NT security descriptor (binary ACL)
0x4704 VM/CMS
0x470f MVS
0x4854 Theos, old inofficial port
0x4b46 FWKCS MD5 (see below)
0x4c41 OS/2 access control list (text ACL)
0x4d49 Info-ZIP OpenVMS (obsolete)
0x4d63 Macintosh SmartZIP, by Macro Bambini
0x4f4c Xceed original location extra field
0x5356 AOS/VS (binary ACL)
0x5455 extended timestamp
0x554e Xceed unicode extra field
0x5855 Info-ZIP Unix (original; also OS/2, NT, etc.)
0x6542 BeOS (BeBox, PowerMac, etc.)
0x6854 Theos
0x7441 AtheOS (AtheOS/Syllable attributes)
0x756e ASi Unix
0x7855 Info-ZIP Unix (new)
0xfb4a SMS/QDOS
}
// Äëÿ ïðèìåðà ìû çàïîëíèì òðè áëîêà äàííûõ:
case UserExDataBlockCount of
0:
begin
// Âûáèðàåì íåçàðåçåðâèðîâàííîå çíà÷åíèå òýãà (íàïðèìåð $FFFA)
Tag := $FFFA;
// è ïèøåì ñàìè äàííûå
Data.WriteBuffer(TestExDataBlob, 4);
end;
1..2:
begin
// Âûáèðàåì äðóãîå íåçàðåçåðâèðîâàííîå çíà÷åíèå òýãà
Tag := $FFFB + UserExDataBlockCount;
// äàííûå ðàíäîìíûå - ïðîñòî äëÿ äåìîíñòðàöèè çàïèñè äâóõ è áîëåå ïîëåé
Randomize;
RandomValue := Random(MaxInt);
Data.WriteBuffer(RandomValue, 4);
end;
end;
end;
//
// Îáðàáîò÷èê ïðè ïîìîùè êîòîðîãî ìû ïîëó÷àåì áëîê ðàñøèðåííûõ äàííûõ ExData
// êîòîðûé íå ñìîã îáðàáîòàòü TFWZipReader.
// Îáðàáîò÷èê âûçûâàåòñÿ äëÿ êàæäîãî íåðàñïîçíàííîãî ýëåìåíòà ExData,
// êîëè÷åñòâî êîòîðûõ íå îãðàíè÷åíî.
// Äàííûé îáðàáîò÷èê âûçûâàåòñÿ ïðè âûçîâå ìåòîäà TFWZipReader.LoadFromFile
// Sender â äàííîì îáðàáîò÷èêå ÿâëÿåòñÿ TFWZipReaderItem,
// ò.å. ýëåìåíòîì ïðè ÷òåíèè êîòîðîãî íå ðàñïîçíàëñÿ òýã ExData.
// =============================================================================
procedure OnLoadExData(Self, Sender: TObject; ItemIndex: Integer;
Tag: Word; Data: TStream);
var
Value: Cardinal;
begin
// òàê êàê ìû çíàåì êàê íóæíî îáðàáàòûâàòü òîëüêî áëîê äàííûõ ñ òýãîì $FFFA
// òî îñòàëüíûå íåîáõîäèìî ïðîïóñòèòü
if Tag = $FFFA then
begin
// Äëÿ äåìîíñòðàöèè ïðîñòî ïðîâåðÿåì ñîâïàäàåò ëè çíà÷åíèå â áëîêå ñ íàøèì
if Data.Size <> 4 then
raise Exception.Create('Íåâåðíûé ðàçìåð áëîêà ExData');
Data.ReadBuffer(Value, Data.Size);
if Value <> TestExDataBlob then
raise Exception.Create('Íåâåðíîå çíà÷åíèå áëîêà ExData');
// ñâÿçàòü äàííûå ñ ýëåìåíòîì ìàññèâà ìîæíî íàïðèìåð èñïîëüçóÿ ïîëå Tag
TFWZipReaderItem(Sender).Tag := Integer(Value);
// âîò òàêîé âûçîâ äåëàòü íåëüçÿ, ò.ê. â äàííûé ìîìåíò Sender
// íàõîäèòñÿ â êîíñòðóêòîðå è íå äîáàâëåí â ñïèñîê ýëåìåíòîâ
// ãëàâíîãî êëàññà
// Reader[ItemIndex].Tag := Integer(Value); - îøèáî÷íûé êîä
end;
end;
begin
SetCurrentDir(ExtractFilePath(ParamStr(0)));
try
Writer := TFWZipWriter.Create;
try
// Äëÿ íà÷àëà äîáàâèì â êîðåíü àðõèâà ôàéëû èç êîðíåâîé äèðåêòîðèè
Writer.AddFolder('', '..\..\', '*.*', False);
// Íàçíà÷àåì îáðàáîò÷èê ÷åðåç êîòîðûé ìû áóäåì äîáàâëÿòü áëîê ðàñøèðåííûõ äàííûõ
Method.Code := @OnSaveExData;
Method.Data := Writer;
Writer.OnSaveExData := TZipSaveExDataEvent(Method);
// Ñîõðàíÿåì ðåçóëüòàò
ForceDirectories('..\DemoResults\');
Writer.BuildZip('..\DemoResults\UseExDataBlob.zip');
finally
Writer.Free;
end;
Reader := TFWZipReader.Create;
try
// Òåïåðü íàøà çàäà÷à ïîëó÷èòü ðàñøèðåííûå áëîêè äàííûõ.
// Äëÿ ýòîãî íåîáõîäèìî íàçíà÷èòü îáðàáîò÷èê OnLoadExData
// è îòêðûòü ñàì àðõèâ.
Method.Code := @OnLoadExData;
Method.Data := Reader;
Reader.OnLoadExData := TZipLoadExDataEvent(Method);
Reader.LoadFromFile('..\DemoResults\UseExDataBlob.zip');
finally
Reader.Free;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.

View File

@ -0,0 +1,619 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{02A43576-9D18-4FA2-9764-51DAB3B92B77}</ProjectGuid>
<MainSource>UseExDataBlob.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Console</AppType>
<FrameworkType>None</FrameworkType>
<ProjectVersion>14.6</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_S>false</DCC_S>
<DCC_K>false</DCC_K>
<DCC_E>false</DCC_E>
<DCC_N>false</DCC_N>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;UIDeviceFamily=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;UISupportedInterfaceOrientations=;CFBundleExecutable=;CFBundleResourceSpecification=;LSRequiresIPhoneOS=;CFBundleInfoDictionaryVersion=;CFBundleDevelopmentRegion=</VerInfo_Keys>
<DCC_F>false</DCC_F>
<VerInfo_Locale>1049</VerInfo_Locale>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
<DCC_ImageBase>00400000</DCC_ImageBase>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Locale>1033</VerInfo_Locale>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_DebugInformation>false</DCC_DebugInformation>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">UseExDataBlob.dpr</Source>
</Source>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
<VersionInfoKeys Name="CFBundleName"/>
<VersionInfoKeys Name="CFBundleDisplayName"/>
<VersionInfoKeys Name="UIDeviceFamily"/>
<VersionInfoKeys Name="CFBundleIdentifier"/>
<VersionInfoKeys Name="CFBundleVersion"/>
<VersionInfoKeys Name="CFBundlePackageType"/>
<VersionInfoKeys Name="CFBundleSignature"/>
<VersionInfoKeys Name="CFBundleAllowMixedLocalizations"/>
<VersionInfoKeys Name="UISupportedInterfaceOrientations"/>
<VersionInfoKeys Name="CFBundleExecutable"/>
<VersionInfoKeys Name="CFBundleResourceSpecification"/>
<VersionInfoKeys Name="LSRequiresIPhoneOS"/>
<VersionInfoKeys Name="CFBundleInfoDictionaryVersion"/>
<VersionInfoKeys Name="CFBundleDevelopmentRegion"/>
</VersionInfoKeys>
</Delphi.Personality>
<Platforms>
<Platform value="OSX32">False</Platform>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>
<!-- EurekaLog First Line
[Exception Log]
EurekaLog Version=6104
Activate=0
Activate Handle=1
Save Log File=1
Foreground Tab=0
Freeze Activate=0
Freeze Timeout=0
SMTP From=eurekalog@email.com
SMTP Host=
SMTP Port=25
SMTP UserID=
SMTP Password=
Append to Log=0
TerminateBtn Operation=2
Errors Number=32
Errors Terminate=3
Email Address=
Email Object=
Email Send Options=0
Output Path=
Encrypt Password=
AutoCloseDialogSecs=0
WebSendMode=0
SupportULR=
HTMLLayout Count=15
HTMLLine0="%U003Chtml%U003E"
HTMLLine1=" %U003Chead%U003E"
HTMLLine2=" %U003C/head%U003E"
HTMLLine3=" %U003Cbody TopMargin=10 LeftMargin=10%U003E"
HTMLLine4=" %U003Ctable width="100%%" border="0"%U003E"
HTMLLine5=" %U003Ctr%U003E"
HTMLLine6=" %U003Ctd nowrap%U003E"
HTMLLine7=" %U003Cfont face="Lucida Console, Courier" size="2"%U003E"
HTMLLine8=" %U003C%%HTML_TAG%%%U003E"
HTMLLine9=" %U003C/font%U003E"
HTMLLine10=" %U003C/td%U003E"
HTMLLine11=" %U003C/tr%U003E"
HTMLLine12=" %U003C/table%U003E"
HTMLLine13=" %U003C/body%U003E"
HTMLLine14="%U003C/html%U003E"
AutoCrashOperation=2
AutoCrashNumber=10
AutoCrashMinutes=1
WebURL=
WebUserID=
WebPassword=
WebPort=0
AttachedFiles=
ProxyURL=
ProxyUser=
ProxyPassword=
ProxyPort=8080
TrakerUser=
TrakerPassword=
TrakerAssignTo=
TrakerProject=
TrakerCategory=
TrakerTrialID=
ZipPassword=
PreBuildEvent=
PostSuccessfulBuildEvent=
PostFailureBuildEvent=
ExceptionDialogType=2
Count=0
EMail Message Line Count=0
loNoDuplicateErrors=0
loAppendReproduceText=0
loDeleteLogAtVersionChange=0
loAddComputerNameInLogFileName=0
loSaveModulesAndProcessesSections=1
loSaveAssemblerAndCPUSections=1
soAppStartDate=1
soAppName=1
soAppVersionNumber=1
soAppParameters=1
soAppCompilationDate=1
soAppUpTime=1
soExcDate=1
soExcAddress=1
soExcModuleName=1
soExcModuleVersion=1
soExcType=1
soExcMessage=1
soExcID=1
soExcCount=1
soExcStatus=1
soExcNote=1
soUserID=1
soUserName=1
soUserEmail=1
soUserPrivileges=1
soUserCompany=1
soActCtlsFormClass=1
soActCtlsFormText=1
soActCtlsControlClass=1
soActCtlsControlText=1
soCmpName=1
soCmpTotalMemory=1
soCmpFreeMemory=1
soCmpTotalDisk=1
soCmpFreeDisk=1
soCmpSysUpTime=1
soCmpProcessor=1
soCmpDisplayMode=1
soCmpDisplayDPI=1
soCmpVideoCard=1
soCmpPrinter=1
soOSType=1
soOSBuildN=1
soOSUpdate=1
soOSLanguage=1
soOSCharset=1
soNetIP=1
soNetSubmask=1
soNetGateway=1
soNetDNS1=1
soNetDNS2=1
soNetDHCP=1
soCustomData=1
sndShowSendDialog=1
sndShowSuccessFailureMsg=0
sndSendEntireLog=0
sndSendXMLLogCopy=0
sndSendScreenshot=1
sndUseOnlyActiveWindow=0
sndSendLastHTMLPage=1
sndSendInSeparatedThread=0
sndAddDateInFileName=0
sndAddComputerNameInFileName=0
edoSendErrorReportChecked=1
edoAttachScreenshotChecked=1
edoShowCopyToClipOption=1
edoShowDetailsButton=1
edoShowInDetailedMode=0
edoShowInTopMostMode=0
edoUseEurekaLogLookAndFeel=0
edoShowSendErrorReportOption=1
edoShowAttachScreenshotOption=1
edoShowCustomButton=0
csoShowDLLs=1
csoShowBPLs=1
csoShowBorlandThreads=1
csoShowWindowsThreads=1
csoDoNotStoreProcNames=0
boPauseBorlandThreads=0
boDoNotPauseMainThread=0
boPauseWindowsThreads=0
boUseMainModuleOptions=1
boCopyLogInCaseOfError=1
boSaveCompressedCopyInCaseOfError=0
boHandleSafeCallExceptions=1
boCallRTLExceptionEvent=0
boCatchHandledExceptions=0
loCatchLeaks=0
loGroupsSonLeaks=1
loHideBorlandLeaks=1
loFreeAllLeaks=1
loCatchLeaksExceptions=1
cfoReduceFileSize=1
cfoCheckFileCorruption=0
cfoUseEL7=0
Count mtInformationMsgCaption=1
mtInformationMsgCaption0="Information."
Count mtQuestionMsgCaption=1
mtQuestionMsgCaption0="Question."
Count mtErrorMsgCaption=1
mtErrorMsgCaption0="Error."
Count mtDialog_Caption=1
mtDialog_Caption0="Error occurred"
Count mtDialog_ErrorMsgCaption=2
mtDialog_ErrorMsgCaption0="An error has occurred during program execution."
mtDialog_ErrorMsgCaption1="Please read the following information for further details."
Count mtDialog_GeneralCaption=1
mtDialog_GeneralCaption0="General"
Count mtDialog_GeneralHeader=1
mtDialog_GeneralHeader0="General Information"
Count mtDialog_CallStackCaption=1
mtDialog_CallStackCaption0="Call Stack"
Count mtDialog_CallStackHeader=1
mtDialog_CallStackHeader0="Call Stack Information"
Count mtDialog_ModulesCaption=1
mtDialog_ModulesCaption0="Modules"
Count mtDialog_ModulesHeader=1
mtDialog_ModulesHeader0="Modules Information"
Count mtDialog_ProcessesCaption=1
mtDialog_ProcessesCaption0="Processes"
Count mtDialog_ProcessesHeader=1
mtDialog_ProcessesHeader0="Processes Information"
Count mtDialog_AsmCaption=1
mtDialog_AsmCaption0="Assembler"
Count mtDialog_AsmHeader=1
mtDialog_AsmHeader0="Assembler Information"
Count mtDialog_CPUCaption=1
mtDialog_CPUCaption0="CPU"
Count mtDialog_CPUHeader=1
mtDialog_CPUHeader0="CPU Information"
Count mtDialog_OKButtonCaption=1
mtDialog_OKButtonCaption0="%U0026OK"
Count mtDialog_TerminateButtonCaption=1
mtDialog_TerminateButtonCaption0="%U0026Terminate"
Count mtDialog_RestartButtonCaption=1
mtDialog_RestartButtonCaption0="%U0026Restart"
Count mtDialog_DetailsButtonCaption=1
mtDialog_DetailsButtonCaption0="%U0026Details"
Count mtDialog_CustomButtonCaption=1
mtDialog_CustomButtonCaption0="%U0026Help"
Count mtDialog_SendMessage=1
mtDialog_SendMessage0="%U0026Send this error via Internet"
Count mtDialog_ScreenshotMessage=1
mtDialog_ScreenshotMessage0="%U0026Attach a Screenshot image"
Count mtDialog_CopyMessage=1
mtDialog_CopyMessage0="%U0026Copy to Clipboard"
Count mtDialog_SupportMessage=1
mtDialog_SupportMessage0="Go to the Support Page"
Count mtMSDialog_ErrorMsgCaption=1
mtMSDialog_ErrorMsgCaption0="The application has encountered a problem. We are sorry for the inconvenience."
Count mtMSDialog_RestartCaption=1
mtMSDialog_RestartCaption0="Restart application."
Count mtMSDialog_TerminateCaption=1
mtMSDialog_TerminateCaption0="Terminate application."
Count mtMSDialog_PleaseCaption=1
mtMSDialog_PleaseCaption0="Please tell us about this problem."
Count mtMSDialog_DescriptionCaption=1
mtMSDialog_DescriptionCaption0="We have created an error report that you can send to us. We will treat this report as confidential and anonymous."
Count mtMSDialog_SeeDetailsCaption=1
mtMSDialog_SeeDetailsCaption0="To see what data the error report contains,"
Count mtMSDialog_SeeClickCaption=1
mtMSDialog_SeeClickCaption0="click here."
Count mtMSDialog_HowToReproduceCaption=1
mtMSDialog_HowToReproduceCaption0="What were you doing when the problem happened (optional)?"
Count mtMSDialog_EmailCaption=1
mtMSDialog_EmailCaption0="Email address (optional):"
Count mtMSDialog_SendButtonCaption=1
mtMSDialog_SendButtonCaption0="%U0026Send Error Report"
Count mtMSDialog_NoSendButtonCaption=1
mtMSDialog_NoSendButtonCaption0="%U0026Don't Send"
Count mtLog_AppHeader=1
mtLog_AppHeader0="Application"
Count mtLog_AppStartDate=1
mtLog_AppStartDate0="Start Date"
Count mtLog_AppName=1
mtLog_AppName0="Name/Description"
Count mtLog_AppVersionNumber=1
mtLog_AppVersionNumber0="Version Number"
Count mtLog_AppParameters=1
mtLog_AppParameters0="Parameters"
Count mtLog_AppCompilationDate=1
mtLog_AppCompilationDate0="Compilation Date"
Count mtLog_AppUpTime=1
mtLog_AppUpTime0="Up Time"
Count mtLog_ExcHeader=1
mtLog_ExcHeader0="Exception"
Count mtLog_ExcDate=1
mtLog_ExcDate0="Date"
Count mtLog_ExcAddress=1
mtLog_ExcAddress0="Address"
Count mtLog_ExcModuleName=1
mtLog_ExcModuleName0="Module Name"
Count mtLog_ExcModuleVersion=1
mtLog_ExcModuleVersion0="Module Version"
Count mtLog_ExcType=1
mtLog_ExcType0="Type"
Count mtLog_ExcMessage=1
mtLog_ExcMessage0="Message"
Count mtLog_ExcID=1
mtLog_ExcID0="ID"
Count mtLog_ExcCount=1
mtLog_ExcCount0="Count"
Count mtLog_ExcStatus=1
mtLog_ExcStatus0="Status"
Count mtLog_ExcNote=1
mtLog_ExcNote0="Note"
Count mtLog_UserHeader=1
mtLog_UserHeader0="User"
Count mtLog_UserID=1
mtLog_UserID0="ID"
Count mtLog_UserName=1
mtLog_UserName0="Name"
Count mtLog_UserEmail=1
mtLog_UserEmail0="Email"
Count mtLog_UserCompany=1
mtLog_UserCompany0="Company"
Count mtLog_UserPrivileges=1
mtLog_UserPrivileges0="Privileges"
Count mtLog_ActCtrlsHeader=1
mtLog_ActCtrlsHeader0="Active Controls"
Count mtLog_ActCtrlsFormClass=1
mtLog_ActCtrlsFormClass0="Form Class"
Count mtLog_ActCtrlsFormText=1
mtLog_ActCtrlsFormText0="Form Text"
Count mtLog_ActCtrlsControlClass=1
mtLog_ActCtrlsControlClass0="Control Class"
Count mtLog_ActCtrlsControlText=1
mtLog_ActCtrlsControlText0="Control Text"
Count mtLog_CmpHeader=1
mtLog_CmpHeader0="Computer"
Count mtLog_CmpName=1
mtLog_CmpName0="Name"
Count mtLog_CmpTotalMemory=1
mtLog_CmpTotalMemory0="Total Memory"
Count mtLog_CmpFreeMemory=1
mtLog_CmpFreeMemory0="Free Memory"
Count mtLog_CmpTotalDisk=1
mtLog_CmpTotalDisk0="Total Disk"
Count mtLog_CmpFreeDisk=1
mtLog_CmpFreeDisk0="Free Disk"
Count mtLog_CmpSystemUpTime=1
mtLog_CmpSystemUpTime0="System Up Time"
Count mtLog_CmpProcessor=1
mtLog_CmpProcessor0="Processor"
Count mtLog_CmpDisplayMode=1
mtLog_CmpDisplayMode0="Display Mode"
Count mtLog_CmpDisplayDPI=1
mtLog_CmpDisplayDPI0="Display DPI"
Count mtLog_CmpVideoCard=1
mtLog_CmpVideoCard0="Video Card"
Count mtLog_CmpPrinter=1
mtLog_CmpPrinter0="Printer"
Count mtLog_OSHeader=1
mtLog_OSHeader0="Operating System"
Count mtLog_OSType=1
mtLog_OSType0="Type"
Count mtLog_OSBuildN=1
mtLog_OSBuildN0="Build #"
Count mtLog_OSUpdate=1
mtLog_OSUpdate0="Update"
Count mtLog_OSLanguage=1
mtLog_OSLanguage0="Language"
Count mtLog_OSCharset=1
mtLog_OSCharset0="Charset"
Count mtLog_NetHeader=1
mtLog_NetHeader0="Network"
Count mtLog_NetIP=1
mtLog_NetIP0="IP Address"
Count mtLog_NetSubmask=1
mtLog_NetSubmask0="Submask"
Count mtLog_NetGateway=1
mtLog_NetGateway0="Gateway"
Count mtLog_NetDNS1=1
mtLog_NetDNS10="DNS 1"
Count mtLog_NetDNS2=1
mtLog_NetDNS20="DNS 2"
Count mtLog_NetDHCP=1
mtLog_NetDHCP0="DHCP"
Count mtLog_CustInfoHeader=1
mtLog_CustInfoHeader0="Custom Information"
Count mtCallStack_Address=1
mtCallStack_Address0="Address"
Count mtCallStack_Name=1
mtCallStack_Name0="Module"
Count mtCallStack_Unit=1
mtCallStack_Unit0="Unit"
Count mtCallStack_Class=1
mtCallStack_Class0="Class"
Count mtCallStack_Procedure=1
mtCallStack_Procedure0="Procedure/Method"
Count mtCallStack_Line=1
mtCallStack_Line0="Line"
Count mtCallStack_MainThread=1
mtCallStack_MainThread0="Main"
Count mtCallStack_ExceptionThread=1
mtCallStack_ExceptionThread0="Exception Thread"
Count mtCallStack_RunningThread=1
mtCallStack_RunningThread0="Running Thread"
Count mtCallStack_CallingThread=1
mtCallStack_CallingThread0="Calling Thread"
Count mtCallStack_ThreadID=1
mtCallStack_ThreadID0="ID"
Count mtCallStack_ThreadPriority=1
mtCallStack_ThreadPriority0="Priority"
Count mtCallStack_ThreadClass=1
mtCallStack_ThreadClass0="Class"
Count mtCallStack_LeakCaption=1
mtCallStack_LeakCaption0="Memory Leak"
Count mtCallStack_LeakData=1
mtCallStack_LeakData0="Data"
Count mtCallStack_LeakType=1
mtCallStack_LeakType0="Type"
Count mtCallStack_LeakSize=1
mtCallStack_LeakSize0="Total size"
Count mtCallStack_LeakCount=1
mtCallStack_LeakCount0="Count"
Count mtSendDialog_Caption=1
mtSendDialog_Caption0="Send."
Count mtSendDialog_Message=1
mtSendDialog_Message0="Message"
Count mtSendDialog_Resolving=1
mtSendDialog_Resolving0="Resolving DNS..."
Count mtSendDialog_Login=1
mtSendDialog_Login0="Login..."
Count mtSendDialog_Connecting=1
mtSendDialog_Connecting0="Connecting with server..."
Count mtSendDialog_Connected=1
mtSendDialog_Connected0="Connected with server."
Count mtSendDialog_Sending=1
mtSendDialog_Sending0="Sending message..."
Count mtSendDialog_Sent=1
mtSendDialog_Sent0="Message sent."
Count mtSendDialog_SelectProject=1
mtSendDialog_SelectProject0="Select project..."
Count mtSendDialog_Searching=1
mtSendDialog_Searching0="Searching..."
Count mtSendDialog_Modifying=1
mtSendDialog_Modifying0="Modifying..."
Count mtSendDialog_Disconnecting=1
mtSendDialog_Disconnecting0="Disconnecting..."
Count mtSendDialog_Disconnected=1
mtSendDialog_Disconnected0="Disconnected."
Count mtReproduceDialog_Caption=1
mtReproduceDialog_Caption0="Request"
Count mtReproduceDialog_Request=1
mtReproduceDialog_Request0="Please describe the steps to reproduce the error:"
Count mtReproduceDialog_OKButtonCaption=1
mtReproduceDialog_OKButtonCaption0="%U0026OK"
Count mtModules_Handle=1
mtModules_Handle0="Handle"
Count mtModules_Name=1
mtModules_Name0="Name"
Count mtModules_Description=1
mtModules_Description0="Description"
Count mtModules_Version=1
mtModules_Version0="Version"
Count mtModules_Size=1
mtModules_Size0="Size"
Count mtModules_LastModified=1
mtModules_LastModified0="Modified"
Count mtModules_Path=1
mtModules_Path0="Path"
Count mtProcesses_ID=1
mtProcesses_ID0="ID"
Count mtProcesses_Name=1
mtProcesses_Name0="Name"
Count mtProcesses_Description=1
mtProcesses_Description0="Description"
Count mtProcesses_Version=1
mtProcesses_Version0="Version"
Count mtProcesses_Memory=1
mtProcesses_Memory0="Memory"
Count mtProcesses_Priority=1
mtProcesses_Priority0="Priority"
Count mtProcesses_Threads=1
mtProcesses_Threads0="Threads"
Count mtProcesses_Path=1
mtProcesses_Path0="Path"
Count mtCPU_Registers=1
mtCPU_Registers0="Registers"
Count mtCPU_Stack=1
mtCPU_Stack0="Stack"
Count mtCPU_MemoryDump=1
mtCPU_MemoryDump0="Memory Dump"
Count mtSend_SuccessMsg=1
mtSend_SuccessMsg0="The message was sent successfully."
Count mtSend_FailureMsg=1
mtSend_FailureMsg0="Sorry, sending the message didn't work."
Count mtSend_BugClosedMsg=2
mtSend_BugClosedMsg0="These BUG is just closed."
mtSend_BugClosedMsg1="Contact the program support to obtain an update."
Count mtSend_UnknownErrorMsg=1
mtSend_UnknownErrorMsg0="Unknown error."
Count mtSend_InvalidLoginMsg=1
mtSend_InvalidLoginMsg0="Invalid login request."
Count mtSend_InvalidSearchMsg=1
mtSend_InvalidSearchMsg0="Invalid search request."
Count mtSend_InvalidSelectionMsg=1
mtSend_InvalidSelectionMsg0="Invalid selection request."
Count mtSend_InvalidInsertMsg=1
mtSend_InvalidInsertMsg0="Invalid insert request."
Count mtSend_InvalidModifyMsg=1
mtSend_InvalidModifyMsg0="Invalid modify request."
Count mtFileCrackedMsg=2
mtFileCrackedMsg0="This file is cracked."
mtFileCrackedMsg1="The application will be closed."
Count mtException_LeakMultiFree=1
mtException_LeakMultiFree0="Multi Free memory leak."
Count mtException_LeakMemoryOverrun=1
mtException_LeakMemoryOverrun0="Memory Overrun leak."
Count mtException_AntiFreeze=1
mtException_AntiFreeze0="The application seems to be frozen."
Count mtInvalidEmailMsg=1
mtInvalidEmailMsg0="Invalid email."
TextsCollection=English
EurekaLog Last Line -->

View File

@ -0,0 +1,13 @@
program ZipAnalizer;
uses
Forms,
uZipAnalizer in 'uZipAnalizer.pas' {dlgZipAnalizer};
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TdlgZipAnalizer, dlgZipAnalizer);
Application.Run;
end.

View File

@ -0,0 +1,148 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{48B210D8-1C88-400C-8596-80BA4942AF52}</ProjectGuid>
<MainSource>ZipAnalizer.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Application</AppType>
<FrameworkType>VCL</FrameworkType>
<ProjectVersion>14.6</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
<Base_Win64>true</Base_Win64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_N>false</DCC_N>
<DCC_ImageBase>00400000</DCC_ImageBase>
<DCC_E>false</DCC_E>
<VerInfo_Locale>1049</VerInfo_Locale>
<DCC_Namespace>Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace)</DCC_Namespace>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;UIDeviceFamily=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;UISupportedInterfaceOrientations=;CFBundleExecutable=;CFBundleResourceSpecification=;LSRequiresIPhoneOS=;CFBundleInfoDictionaryVersion=;CFBundleDevelopmentRegion=</VerInfo_Keys>
<DCC_S>false</DCC_S>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Locale>1033</VerInfo_Locale>
<Icon_MainIcon>ZipAnalizer_Icon.ico</Icon_MainIcon>
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
<Icon_MainIcon>ZipAnalizer_Icon.ico</Icon_MainIcon>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_DebugInformation>false</DCC_DebugInformation>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="uZipAnalizer.pas">
<Form>dlgZipAnalizer</Form>
</DCCReference>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">ZipAnalizer.dpr</Source>
</Source>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
<VersionInfoKeys Name="CFBundleName"/>
<VersionInfoKeys Name="CFBundleDisplayName"/>
<VersionInfoKeys Name="UIDeviceFamily"/>
<VersionInfoKeys Name="CFBundleIdentifier"/>
<VersionInfoKeys Name="CFBundleVersion"/>
<VersionInfoKeys Name="CFBundlePackageType"/>
<VersionInfoKeys Name="CFBundleSignature"/>
<VersionInfoKeys Name="CFBundleAllowMixedLocalizations"/>
<VersionInfoKeys Name="UISupportedInterfaceOrientations"/>
<VersionInfoKeys Name="CFBundleExecutable"/>
<VersionInfoKeys Name="CFBundleResourceSpecification"/>
<VersionInfoKeys Name="LSRequiresIPhoneOS"/>
<VersionInfoKeys Name="CFBundleInfoDictionaryVersion"/>
<VersionInfoKeys Name="CFBundleDevelopmentRegion"/>
</VersionInfoKeys>
</Delphi.Personality>
<Platforms>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

View File

@ -0,0 +1,104 @@
object dlgZipAnalizer: TdlgZipAnalizer
Left = 301
Top = 184
Caption = #1042#1099#1074#1086#1076' '#1087#1072#1088#1072#1084#1077#1090#1088#1086#1074' ZIP '#1072#1088#1093#1080#1074#1072
ClientHeight = 300
ClientWidth = 685
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
Position = poScreenCenter
OnCreate = FormCreate
OnDestroy = FormDestroy
DesignSize = (
685
300)
PixelsPerInch = 96
TextHeight = 13
object edPath: TLabeledEdit
Left = 8
Top = 24
Width = 550
Height = 21
Anchors = [akLeft, akTop, akRight]
EditLabel.Width = 124
EditLabel.Height = 13
EditLabel.Caption = #1059#1082#1072#1078#1080#1090#1077' '#1087#1091#1090#1100' '#1082' '#1072#1088#1093#1080#1074#1091':'
TabOrder = 0
OnChange = edPathChange
end
object btnBrowse: TButton
Left = 560
Top = 22
Width = 25
Height = 25
Anchors = [akTop, akRight]
Caption = '...'
TabOrder = 1
OnClick = btnBrowseClick
end
object btnAnalize: TButton
Left = 591
Top = 22
Width = 75
Height = 25
Anchors = [akTop, akRight]
Caption = #1057#1090#1072#1088#1090
Enabled = False
TabOrder = 2
OnClick = btnAnalizeClick
end
object GroupBox: TGroupBox
Left = 8
Top = 56
Width = 669
Height = 233
Anchors = [akLeft, akTop, akRight, akBottom]
Caption = #1055#1072#1088#1072#1084#1077#1090#1088#1099' '#1072#1088#1093#1080#1074#1072':'
TabOrder = 3
object edReport: TRichEdit
Left = 2
Top = 15
Width = 665
Height = 216
Align = alClient
Font.Charset = RUSSIAN_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
PopupMenu = PopupMenu
ReadOnly = True
ScrollBars = ssBoth
TabOrder = 0
end
end
object OpenDialog: TOpenDialog
DefaultExt = 'zip'
Filter = 'ZIP '#1072#1088#1093#1080#1074#1099' (*.zip)|*.zip|'#1042#1089#1077' '#1092#1072#1081#1083#1099' (*.*)|*.*'
Options = [ofHideReadOnly, ofFileMustExist, ofEnableSizing]
Left = 48
Top = 88
end
object PopupMenu: TPopupMenu
OnPopup = PopupMenuPopup
Left = 120
Top = 88
object mnuSave: TMenuItem
Caption = #1057#1086#1093#1088#1072#1085#1080#1090#1100'...'
ShortCut = 16467
OnClick = mnuSaveClick
end
end
object SaveDialog: TSaveDialog
DefaultExt = 'txt'
Filter = #1058#1077#1082#1089#1090#1086#1074#1099#1077' '#1092#1072#1081#1083#1099' (*.txt)|*.txt|'#1042#1089#1077' '#1092#1072#1081#1083#1099' (*.*)|*.*'
Left = 208
Top = 88
end
end

View File

@ -0,0 +1,351 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip - ZipAnalizer
// * Unit Name : uZipAnalizer
// * Purpose : Âûâîä ïàðàìåòðîâ àðõèâà èñïîëüçóÿ âîçìîæíîñòè FWZipReader
// * Author : Àëåêñàíäð (Rouse_) Áàãåëü
// * Copyright : © Fangorn Wizards Lab 1998 - 2013.
// * Version : 1.0.10
// * Home Page : http://rouse.drkb.ru
// * Home Blog : http://alexander-bagel.blogspot.ru
// ****************************************************************************
// * Stable Release : http://rouse.drkb.ru/components.php#fwzip
// * Latest Source : https://github.com/AlexanderBagel/FWZip
// ****************************************************************************
//
// Èñïîëüçóåìûå èñòî÷íèêè:
// ftp://ftp.info-zip.org/pub/infozip/doc/appnote-iz-latest.zip
// http://zlib.net/zlib-1.2.5.tar.gz
// http://www.base2ti.com/
//
unit uZipAnalizer;
interface
uses
Windows, Messages, SysUtils, Classes, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, ExtCtrls, Menus,
FWZipReader, FWZipConsts;
type
TFWZipReaderFriendly = class(TFWZipReader);
TFWZipReaderItemFriendly = class(TFWZipReaderItem);
TExDataRecord = record
Index: Integer;
Tag: Word;
Stream: TMemoryStream;
end;
TExDataRecords = array of TExDataRecord;
TdlgZipAnalizer = class(TForm)
edPath: TLabeledEdit;
btnBrowse: TButton;
btnAnalize: TButton;
GroupBox: TGroupBox;
edReport: TRichEdit;
OpenDialog: TOpenDialog;
PopupMenu: TPopupMenu;
mnuSave: TMenuItem;
SaveDialog: TSaveDialog;
procedure btnBrowseClick(Sender: TObject);
procedure edPathChange(Sender: TObject);
procedure btnAnalizeClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure mnuSaveClick(Sender: TObject);
procedure PopupMenuPopup(Sender: TObject);
private
ExDataRecords: TExDataRecords;
Zip: TFWZipReaderFriendly;
procedure OnLoadExData(Sender: TObject; ItemIndex: Integer;
Tag: Word; Data: TStream);
private
procedure ClearExData;
procedure Log(const Value: string);
procedure ShowEndOfCentralDir;
procedure ShowZip64EOFCentralDirectoryLocator;
procedure ShowZip64EOFCentralDirectoryRecord;
procedure ShowItemData(Index: Integer);
end;
var
dlgZipAnalizer: TdlgZipAnalizer;
implementation
const
Delim = '===================================================================';
{$R *.dfm}
procedure TdlgZipAnalizer.btnAnalizeClick(Sender: TObject);
var
I: Integer;
begin
edReport.Lines.BeginUpdate;
try
edReport.Clear;
Log(edPath.Text);
Log(Delim);
ClearExData;
Zip.Clear;
Zip.LoadFromFile(edPath.Text);
ShowEndOfCentralDir;
ShowZip64EOFCentralDirectoryLocator;
ShowZip64EOFCentralDirectoryRecord;
for I := 0 to Zip.Count - 1 do
ShowItemData(I);
Log('DONE');
finally
edReport.Lines.EndUpdate;
end;
end;
procedure TdlgZipAnalizer.btnBrowseClick(Sender: TObject);
begin
if OpenDialog.Execute then
begin
edPath.Text := OpenDialog.FileName;
edReport.Clear;
end;
end;
procedure TdlgZipAnalizer.ClearExData;
var
I: Integer;
begin
for I := 0 to Length(ExDataRecords) - 1 do
ExDataRecords[I].Stream.Free;
SetLength(ExDataRecords, 0);;
end;
procedure TdlgZipAnalizer.edPathChange(Sender: TObject);
begin
btnAnalize.Enabled := FileExists(edPath.Text);
end;
procedure TdlgZipAnalizer.FormCreate(Sender: TObject);
begin
Zip := TFWZipReaderFriendly.Create;
Zip.OnLoadExData := OnLoadExData;
edReport.PlainText := True;
end;
procedure TdlgZipAnalizer.FormDestroy(Sender: TObject);
begin
ClearExData;
Zip.Free;
end;
procedure TdlgZipAnalizer.Log(const Value: string);
begin
edReport.Lines.Add(Value);
end;
procedure TdlgZipAnalizer.mnuSaveClick(Sender: TObject);
begin
if SaveDialog.Execute then
edReport.Lines.SaveToFile(SaveDialog.FileName);
end;
procedure TdlgZipAnalizer.OnLoadExData(Sender: TObject; ItemIndex: Integer;
Tag: Word; Data: TStream);
var
Count: Integer;
begin
Count := Length(ExDataRecords);
SetLength(ExDataRecords, Count + 1);
ExDataRecords[Count].Index := ItemIndex;
ExDataRecords[Count].Tag := Tag;
ExDataRecords[Count].Stream := TMemoryStream.Create;
ExDataRecords[Count].Stream.CopyFrom(Data, 0);
end;
procedure TdlgZipAnalizer.PopupMenuPopup(Sender: TObject);
begin
mnuSave.Enabled := edReport.Lines.Count > 1;
end;
procedure TdlgZipAnalizer.ShowEndOfCentralDir;
begin
Log('END_OF_CENTRAL_DIR_SIGNATURE found');
with Zip.EndOfCentralDir do
begin
Log(Format('NumberOfThisDisk: %d', [NumberOfThisDisk]));
Log(Format('NumberOfTheDiskWithTheStart: %d', [NumberOfTheDiskWithTheStart]));
Log(Format('TotalNumberOfEntriesOnThisDisk: %d', [TotalNumberOfEntriesOnThisDisk]));
Log(Format('TotalNumberOfEntries: %d', [TotalNumberOfEntries]));
Log(Format('SizeOfTheCentralDirectory: %d', [SizeOfTheCentralDirectory]));
Log(Format('OffsetOfStartOfCentralDirectory: %d', [OffsetOfStartOfCentralDirectory]));
Log(Format('ZipfileCommentLength: %d', [ZipfileCommentLength]));
if ZipfileCommentLength > 0 then
Log(Format('Comment: %s', [Zip.Comment]));
end;
Log(Delim);
end;
procedure TdlgZipAnalizer.ShowItemData(Index: Integer);
function ByteToStr(Bytes: PByte; Size: Integer): string;
const
BytesHex: array[0..15] of char =
('0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
var
I: integer;
begin
SetLength(Result, Size shl 1);
for I := 0 to Size - 1 do
begin
Result[I * 2 + 1] := BytesHex[Bytes^ shr 4];
Result[I * 2 + 2] := BytesHex[Bytes^ and $0F];
Inc(Bytes);
end;
end;
function GPBFToStr(Value: Word): string;
procedure AddValue(const S: string);
begin
if Result = '' then
Result := S
else
Result := Result + ', ' + S;
end;
begin
if Value = 0 then
begin
Result := 'EMPTY';
Exit;
end;
if PBF_CRYPTED and Value <> 0 then
AddValue('PBF_CRYPTED');
if PBF_DESCRIPTOR and Value <> 0 then
AddValue('PBF_DESCRIPTOR');
if PBF_UTF8 and Value <> 0 then
AddValue('PBF_UTF8');
if PBF_STRONG_CRYPT and Value <> 0 then
AddValue('PBF_STRONG_CRYPT');
end;
var
I: Integer;
Item: TFWZipReaderItemFriendly;
begin
Log('CENTRAL_FILE_HEADER_SIGNATURE found');
Item := TFWZipReaderItemFriendly(Zip.Item[Index]);
with Item.CentralDirFileHeader do
begin
Log(Format('VersionMadeBy: %d', [VersionMadeBy]));
Log(Format('VersionNeededToExtract: %d', [VersionNeededToExtract]));
Log(Format('GeneralPurposeBitFlag: %d (%s)', [GeneralPurposeBitFlag,
GPBFToStr(GeneralPurposeBitFlag)]));
Log(Format('CompressionMethod: %d', [CompressionMethod]));
Log(Format('LastModFileTimeTime: %d', [LastModFileTimeTime]));
Log(Format('LastModFileTimeDate: %d', [LastModFileTimeDate]));
Log(Format('Crc32: %d', [Crc32]));
Log(Format('CompressedSize: %d', [CompressedSize]));
Log(Format('UncompressedSize: %d', [UncompressedSize]));
Log(Format('FilenameLength: %d', [FilenameLength]));
if FilenameLength > 0 then
Log('>>> FileName: ' + Item.FileName);
Log(Format('ExtraFieldLength: %d', [ExtraFieldLength]));
Log(Format('FileCommentLength: %d', [FileCommentLength]));
if FileCommentLength > 0 then
Log('>>> FileComment: ' + Item.Comment);
Log(Format('DiskNumberStart: %d', [DiskNumberStart]));
Log(Format('InternalFileAttributes: %d', [InternalFileAttributes]));
Log(Format('ExternalFileAttributes: %d', [ExternalFileAttributes]));
Log(Format('RelativeOffsetOfLocalHeader: %d', [RelativeOffsetOfLocalHeader]));
end;
Log('');
Item.LoadLocalFileHeader;
Log('LOCAL_FILE_HEADER_SIGNATURE found');
with Item.LocalFileHeader do
begin
Log(Format('VersionNeededToExtract: %d', [VersionNeededToExtract]));
Log(Format('GeneralPurposeBitFlag: %d (%s)', [GeneralPurposeBitFlag,
GPBFToStr(GeneralPurposeBitFlag)]));
Log(Format('CompressionMethod: %d', [CompressionMethod]));
Log(Format('LastModFileTimeTime: %d', [LastModFileTimeTime]));
Log(Format('LastModFileTimeDate: %d', [LastModFileTimeDate]));
Log(Format('Crc32: %d', [Crc32]));
Log(Format('CompressedSize: %d', [CompressedSize]));
Log(Format('UncompressedSize: %d', [UncompressedSize]));
Log(Format('FilenameLength: %d', [FilenameLength]));
Log(Format('ExtraFieldLength: %d', [ExtraFieldLength]));
end;
if ssZIP64 in Item.PresentStreams then
begin
Log('');
Log('SUPPORTED_EXDATA_ZIP64 found');
with Item do
begin
Log(Format('UncompressedSize: %d', [UncompressedSize]));
Log(Format('CompressedSize: %d', [CompressedSize]));
Log(Format('RelativeOffsetOfLocalHeader: %d', [RelativeOffsetOfLocalHeader]));
Log(Format('DiskNumberStart: %d', [DiskNumberStart]));
end;
end;
if ssNTFS in Item.PresentStreams then
begin
Log('');
Log('SUPPORTED_EXDATA_NTFSTIME found');
end;
for I := 0 to Length(ExDataRecords) - 1 do
if ExDataRecords[I].Index = Index then
begin
Log('');
Log(Format('UNKNOWN TAG (%d) found', [ExDataRecords[I].Tag]));
Log(Format('ExData size %d', [ExDataRecords[I].Stream.Size]));
Log('ExData dump:');
Log(ByteToStr(ExDataRecords[I].Stream.Memory, ExDataRecords[I].Stream.Size));
end;
Log(Delim);
end;
procedure TdlgZipAnalizer.ShowZip64EOFCentralDirectoryLocator;
begin
with Zip.Zip64EOFCentralDirectoryLocator do
begin
if Signature <> ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE then Exit;
Log('ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE found');
Log(Format('NumberOfTheDisk: %d', [NumberOfTheDisk]));
Log(Format('RelativeOffset: %d', [RelativeOffset]));
Log(Format('TotalNumberOfDisks: %d', [TotalNumberOfDisks]));
end;
Log(Delim);
end;
procedure TdlgZipAnalizer.ShowZip64EOFCentralDirectoryRecord;
begin
with Zip.Zip64EOFCentralDirectoryRecord do
begin
if Zip64EndOfCentralDirSignature <> ZIP64_END_OF_CENTRAL_DIR_SIGNATURE then Exit;
Log('ZIP64_END_OF_CENTRAL_DIR_SIGNATURE found');
Log(Format('SizeOfZip64EOFCentralDirectoryRecord: %d', [SizeOfZip64EOFCentralDirectoryRecord]));
Log(Format('VersionMadeBy: %d', [VersionMadeBy]));
Log(Format('VersionNeededToExtract: %d', [VersionNeededToExtract]));
Log(Format('number of this disk: %d', [Number1]));
Log(Format('number of the disk with the start of the central directory: %d', [Number2]));
Log(Format('total number of entries in the central directory on this disk: %d', [TotalNumber1]));
Log(Format('total number of entries in the central directory: %d', [TotalNumber2]));
Log(Format('size of the central directory: %d', [Size]));
Log(Format('offset of start of central directory with respect to the starting disk number: %d', [Offset]));
end;
Log(Delim);
end;
end.

View File

@ -0,0 +1,13 @@
program ZipAnalizer2;
uses
Forms,
uZipAnalizer2 in 'uZipAnalizer2.pas' {dlgZipAnalizer};
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TdlgZipAnalizer, dlgZipAnalizer);
Application.Run;
end.

View File

@ -0,0 +1,148 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{59E61B6B-6187-41F8-947A-693BE9101356}</ProjectGuid>
<MainSource>ZipAnalizer2.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Application</AppType>
<FrameworkType>VCL</FrameworkType>
<ProjectVersion>14.6</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
<Base_Win64>true</Base_Win64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_N>false</DCC_N>
<DCC_ImageBase>00400000</DCC_ImageBase>
<DCC_E>false</DCC_E>
<VerInfo_Locale>1049</VerInfo_Locale>
<DCC_Namespace>Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace)</DCC_Namespace>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;UIDeviceFamily=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;UISupportedInterfaceOrientations=;CFBundleExecutable=;CFBundleResourceSpecification=;LSRequiresIPhoneOS=;CFBundleInfoDictionaryVersion=;CFBundleDevelopmentRegion=</VerInfo_Keys>
<DCC_S>false</DCC_S>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_Locale>1033</VerInfo_Locale>
<Icon_MainIcon>ZipAnalizer_Icon.ico</Icon_MainIcon>
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
<Icon_MainIcon>ZipAnalizer_Icon.ico</Icon_MainIcon>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_DebugInformation>false</DCC_DebugInformation>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="uZipAnalizer2.pas">
<Form>dlgZipAnalizer</Form>
</DCCReference>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">ZipAnalizer2.dpr</Source>
</Source>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
<VersionInfoKeys Name="CFBundleName"/>
<VersionInfoKeys Name="CFBundleDisplayName"/>
<VersionInfoKeys Name="UIDeviceFamily"/>
<VersionInfoKeys Name="CFBundleIdentifier"/>
<VersionInfoKeys Name="CFBundleVersion"/>
<VersionInfoKeys Name="CFBundlePackageType"/>
<VersionInfoKeys Name="CFBundleSignature"/>
<VersionInfoKeys Name="CFBundleAllowMixedLocalizations"/>
<VersionInfoKeys Name="UISupportedInterfaceOrientations"/>
<VersionInfoKeys Name="CFBundleExecutable"/>
<VersionInfoKeys Name="CFBundleResourceSpecification"/>
<VersionInfoKeys Name="LSRequiresIPhoneOS"/>
<VersionInfoKeys Name="CFBundleInfoDictionaryVersion"/>
<VersionInfoKeys Name="CFBundleDevelopmentRegion"/>
</VersionInfoKeys>
</Delphi.Personality>
<Platforms>
<Platform value="Win32">True</Platform>
<Platform value="Win64">False</Platform>
</Platforms>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

View File

@ -0,0 +1,103 @@
object dlgZipAnalizer: TdlgZipAnalizer
Left = 301
Top = 184
Caption = #1042#1099#1074#1086#1076' '#1087#1072#1088#1072#1084#1077#1090#1088#1086#1074' ZIP '#1072#1088#1093#1080#1074#1072
ClientHeight = 300
ClientWidth = 685
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
Position = poScreenCenter
OnCreate = FormCreate
DesignSize = (
685
300)
PixelsPerInch = 96
TextHeight = 13
object edPath: TLabeledEdit
Left = 8
Top = 24
Width = 550
Height = 21
Anchors = [akLeft, akTop, akRight]
EditLabel.Width = 124
EditLabel.Height = 13
EditLabel.Caption = #1059#1082#1072#1078#1080#1090#1077' '#1087#1091#1090#1100' '#1082' '#1072#1088#1093#1080#1074#1091':'
TabOrder = 0
OnChange = edPathChange
end
object btnBrowse: TButton
Left = 560
Top = 22
Width = 25
Height = 25
Anchors = [akTop, akRight]
Caption = '...'
TabOrder = 1
OnClick = btnBrowseClick
end
object btnAnalize: TButton
Left = 591
Top = 22
Width = 75
Height = 25
Anchors = [akTop, akRight]
Caption = #1057#1090#1072#1088#1090
Enabled = False
TabOrder = 2
OnClick = btnAnalizeClick
end
object GroupBox: TGroupBox
Left = 8
Top = 56
Width = 669
Height = 233
Anchors = [akLeft, akTop, akRight, akBottom]
Caption = #1055#1072#1088#1072#1084#1077#1090#1088#1099' '#1072#1088#1093#1080#1074#1072':'
TabOrder = 3
object edReport: TRichEdit
Left = 2
Top = 15
Width = 665
Height = 216
Align = alClient
Font.Charset = RUSSIAN_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
PopupMenu = PopupMenu
ReadOnly = True
ScrollBars = ssBoth
TabOrder = 0
end
end
object OpenDialog: TOpenDialog
DefaultExt = 'zip'
Filter = 'ZIP '#1072#1088#1093#1080#1074#1099' (*.zip)|*.zip|'#1042#1089#1077' '#1092#1072#1081#1083#1099' (*.*)|*.*'
Options = [ofHideReadOnly, ofFileMustExist, ofEnableSizing]
Left = 48
Top = 88
end
object PopupMenu: TPopupMenu
OnPopup = PopupMenuPopup
Left = 120
Top = 88
object mnuSave: TMenuItem
Caption = #1057#1086#1093#1088#1072#1085#1080#1090#1100'...'
ShortCut = 16467
OnClick = mnuSaveClick
end
end
object SaveDialog: TSaveDialog
DefaultExt = 'txt'
Filter = #1058#1077#1082#1089#1090#1086#1074#1099#1077' '#1092#1072#1081#1083#1099' (*.txt)|*.txt|'#1042#1089#1077' '#1092#1072#1081#1083#1099' (*.*)|*.*'
Left = 208
Top = 88
end
end

View File

@ -0,0 +1,555 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip - ZipAnalizer2
// * Unit Name : uZipAnalizer2
// * Purpose : Âûâîä ïàðàìåòðîâ àðõèâà ïðè ïîìîùè ïîèñêà ñèãíàòóð
// * Author : Àëåêñàíäð (Rouse_) Áàãåëü
// * Copyright : © Fangorn Wizards Lab 1998 - 2013.
// * Version : 1.0.10
// * Home Page : http://rouse.drkb.ru
// * Home Blog : http://alexander-bagel.blogspot.ru
// ****************************************************************************
// * Stable Release : http://rouse.drkb.ru/components.php#fwzip
// * Latest Source : https://github.com/AlexanderBagel/FWZip
// ****************************************************************************
//
// Èñïîëüçóåìûå èñòî÷íèêè:
// ftp://ftp.info-zip.org/pub/infozip/doc/appnote-iz-latest.zip
// http://zlib.net/zlib-1.2.5.tar.gz
// http://www.base2ti.com/
//
unit uZipAnalizer2;
interface
uses
Windows, Messages, SysUtils, Classes, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, ExtCtrls, Menus,
FWZipConsts;
type
TdlgZipAnalizer = class(TForm)
edPath: TLabeledEdit;
btnBrowse: TButton;
btnAnalize: TButton;
GroupBox: TGroupBox;
edReport: TRichEdit;
OpenDialog: TOpenDialog;
PopupMenu: TPopupMenu;
mnuSave: TMenuItem;
SaveDialog: TSaveDialog;
procedure btnBrowseClick(Sender: TObject);
procedure edPathChange(Sender: TObject);
procedure btnAnalizeClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure mnuSaveClick(Sender: TObject);
procedure PopupMenuPopup(Sender: TObject);
private
procedure Log(const Value: string);
procedure Scan(const Value: string);
function FindSing(Stream: TStream): DWORD;
procedure ShowLocalFileHeader(Stream: TStream);
procedure ShowDataDescryptor(Stream: TStream);
procedure ShowCentralFileHeader(Stream: TStream);
procedure ShowExtraFields(Stream: TStream; Size: Integer;
FileHeader: TCentralDirectoryFileHeader);
procedure ShowZip64(Stream: TStream);
procedure ShowZip64Locator(Stream: TStream);
procedure ShowEndOfCentralDir(Stream: TStream);
procedure LoadStringValue(Stream: TStream; var Value: string;
nSize: Cardinal; UTF: Boolean);
end;
var
dlgZipAnalizer: TdlgZipAnalizer;
implementation
const
Delim = '===================================================================';
{$R *.dfm}
function GPBFToStr(Value: Word): string;
procedure AddValue(const S: string);
begin
if Result = '' then
Result := S
else
Result := Result + ', ' + S;
end;
begin
if Value = 0 then
begin
Result := 'EMPTY';
Exit;
end;
if PBF_CRYPTED and Value <> 0 then
AddValue('PBF_CRYPTED');
if PBF_DESCRIPTOR and Value <> 0 then
AddValue('PBF_DESCRIPTOR');
if PBF_UTF8 and Value <> 0 then
AddValue('PBF_UTF8');
if PBF_STRONG_CRYPT and Value <> 0 then
AddValue('PBF_STRONG_CRYPT');
end;
procedure TdlgZipAnalizer.btnAnalizeClick(Sender: TObject);
begin
edReport.Lines.BeginUpdate;
try
edReport.Clear;
Log(edPath.Text);
Log(Delim);
Scan(edPath.Text);
Log('DONE');
finally
edReport.Lines.EndUpdate;
end;
end;
procedure TdlgZipAnalizer.btnBrowseClick(Sender: TObject);
begin
if OpenDialog.Execute then
begin
edPath.Text := OpenDialog.FileName;
edReport.Clear;
end;
end;
procedure TdlgZipAnalizer.edPathChange(Sender: TObject);
begin
btnAnalize.Enabled := FileExists(edPath.Text);
end;
function TdlgZipAnalizer.FindSing(Stream: TStream): DWORD;
const
KnownSigns: array [0..5] of DWORD = (
LOCAL_FILE_HEADER_SIGNATURE,
DATA_DESCRIPTOR_SIGNATURE,
CENTRAL_FILE_HEADER_SIGNATURE,
ZIP64_END_OF_CENTRAL_DIR_SIGNATURE,
ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE,
END_OF_CENTRAL_DIR_SIGNATURE
);
function CalcLen: Integer;
begin
Result := Stream.Size - Stream.Position;
if Result > 1024 then
Result := 1024;
end;
var
pBuff, pCursor: PByte;
I, A, Len: Integer;
OldPosition: Int64;
begin
Result := 0;
GetMem(pBuff, 1024);
try
Len := CalcLen;
while (Result = 0) and (Len > 4) do
begin
OldPosition := Stream.Position;
Stream.ReadBuffer(pBuff^, Len);
pCursor := pBuff;
for I := 0 to Len - 4 do
begin
for A := 0 to 5 do
if PDWORD(pCursor)^ = KnownSigns[A] then
begin
Result := KnownSigns[A];
Break;
end;
if Result = 0 then
Inc(pCursor)
else
begin
Stream.Position := OldPosition + I;
Break;
end;
end;
if Result = 0 then
begin
Len := CalcLen;
if Len > 0 then
Stream.Position := Stream.Position - 4;
end;
end;
finally
FreeMem(pBuff);
end;
end;
procedure TdlgZipAnalizer.FormCreate(Sender: TObject);
begin
edReport.PlainText := True;
end;
procedure TdlgZipAnalizer.LoadStringValue(Stream: TStream;
var Value: string; nSize: Cardinal; UTF: Boolean);
var
aString: AnsiString;
begin
if Integer(nSize) > 0 then
begin
SetLength(aString, nSize);
Stream.ReadBuffer(aString[1], nSize);
if UTF then
begin
{$IFDEF UNICODE}
Value := string(UTF8ToUnicodeString(aString))
{$ELSE}
Value := string(UTF8Decode(aString));
Value := StringReplace(Value, '?', '_', [rfReplaceAll]);
{$ENDIF}
end
else
begin
OemToAnsi(@aString[1], @aString[1]);
Value := string(aString);
end;
end;
end;
procedure TdlgZipAnalizer.Log(const Value: string);
begin
edReport.Lines.Add(Value);
end;
procedure TdlgZipAnalizer.mnuSaveClick(Sender: TObject);
begin
if SaveDialog.Execute then
edReport.Lines.SaveToFile(SaveDialog.FileName);
end;
procedure TdlgZipAnalizer.PopupMenuPopup(Sender: TObject);
begin
mnuSave.Enabled := edReport.Lines.Count > 1;
end;
procedure TdlgZipAnalizer.Scan(const Value: string);
var
F: TFileStream;
Sign: DWORD;
begin
F := TFileStream.Create(Value, fmOpenRead or fmShareDenyWrite);
try
Sign := FindSing(F);
while Sign <> 0 do
begin
case Sign of
LOCAL_FILE_HEADER_SIGNATURE: ShowLocalFileHeader(F);
DATA_DESCRIPTOR_SIGNATURE: ShowDataDescryptor(F);
CENTRAL_FILE_HEADER_SIGNATURE: ShowCentralFileHeader(F);
ZIP64_END_OF_CENTRAL_DIR_SIGNATURE: ShowZip64(F);
ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE: ShowZip64Locator(F);
END_OF_CENTRAL_DIR_SIGNATURE: ShowEndOfCentralDir(F);
end;
Sign := FindSing(F);
end;
finally
F.Free;
end;
end;
procedure TdlgZipAnalizer.ShowCentralFileHeader(Stream: TStream);
var
Data: TCentralDirectoryFileHeader;
FileName, Comment: string;
begin
Log('CENTRAL_FILE_HEADER_SIGNATURE found at offset: ' + IntToStr(Stream.Position));
Stream.ReadBuffer(Data, SizeOf(TCentralDirectoryFileHeader));
with Data do
begin
if CentralFileHeaderSignature <> CENTRAL_FILE_HEADER_SIGNATURE then
Log('INVALID SIGNATURE!!!!');
Log(Format('VersionMadeBy: %d', [VersionMadeBy]));
Log(Format('VersionNeededToExtract: %d', [VersionNeededToExtract]));
Log(Format('GeneralPurposeBitFlag: %d (%s)', [GeneralPurposeBitFlag,
GPBFToStr(GeneralPurposeBitFlag)]));
Log(Format('CompressionMethod: %d', [CompressionMethod]));
Log(Format('LastModFileTimeTime: %d', [LastModFileTimeTime]));
Log(Format('LastModFileTimeDate: %d', [LastModFileTimeDate]));
Log(Format('Crc32: %d', [Crc32]));
Log(Format('CompressedSize: %d', [CompressedSize]));
Log(Format('UncompressedSize: %d', [UncompressedSize]));
Log(Format('FilenameLength: %d', [FilenameLength]));
Log(Format('ExtraFieldLength: %d', [ExtraFieldLength]));
Log(Format('FileCommentLength: %d', [FileCommentLength]));
Log(Format('DiskNumberStart: %d', [DiskNumberStart]));
Log(Format('InternalFileAttributes: %d', [InternalFileAttributes]));
Log(Format('ExternalFileAttributes: %d', [ExternalFileAttributes]));
Log(Format('RelativeOffsetOfLocalHeader: %d', [RelativeOffsetOfLocalHeader]));
LoadStringValue(Stream, FileName, FilenameLength,
GeneralPurposeBitFlag and PBF_UTF8 <> 0);
Log('>>> FileName: ' + FileName);
Log(Delim);
ShowExtraFields(Stream, ExtraFieldLength, Data);
if FileCommentLength > 0 then
begin
LoadStringValue(Stream, Comment, FileCommentLength,
GeneralPurposeBitFlag and PBF_UTF8 <> 0);
Log('>>> FileComment: ' + Comment);
Log(Delim);
end;
end;
end;
procedure TdlgZipAnalizer.ShowDataDescryptor(Stream: TStream);
var
Data: TDataDescriptor;
begin
Log('DATA_DESCRIPTOR_SIGNATURE found at offset: ' + IntToStr(Stream.Position));
Stream.ReadBuffer(Data, SizeOf(TDataDescriptor));
with Data do
begin
if DescriptorSignature <> DATA_DESCRIPTOR_SIGNATURE then
Log('INVALID SIGNATURE!!!!');
Log(Format('Crc32: %d', [Crc32]));
Log(Format('CompressedSize: %d', [CompressedSize]));
Log(Format('UncompressedSize: %d', [UncompressedSize]));
end;
Log(Delim);
end;
procedure TdlgZipAnalizer.ShowEndOfCentralDir(Stream: TStream);
var
Data: TEndOfCentralDir;
Comment: string;
begin
Log('END_OF_CENTRAL_DIR_SIGNATURE found at offset: ' + IntToStr(Stream.Position));
Stream.ReadBuffer(Data, SizeOf(TEndOfCentralDir));
with Data do
begin
if EndOfCentralDirSignature <> END_OF_CENTRAL_DIR_SIGNATURE then
Log('INVALID SIGNATURE!!!!');
Log(Format('NumberOfThisDisk: %d', [NumberOfThisDisk]));
Log(Format('NumberOfTheDiskWithTheStart: %d', [NumberOfTheDiskWithTheStart]));
Log(Format('TotalNumberOfEntriesOnThisDisk: %d', [TotalNumberOfEntriesOnThisDisk]));
Log(Format('TotalNumberOfEntries: %d', [TotalNumberOfEntries]));
Log(Format('SizeOfTheCentralDirectory: %d', [SizeOfTheCentralDirectory]));
Log(Format('OffsetOfStartOfCentralDirectory: %d', [OffsetOfStartOfCentralDirectory]));
Log(Format('ZipfileCommentLength: %d', [ZipfileCommentLength]));
if ZipfileCommentLength > 0 then
begin
LoadStringValue(Stream, Comment, ZipfileCommentLength, False);
Log(Format('>>> Comment: %s', [Comment]));
end;
end;
Log(Delim);
end;
procedure TdlgZipAnalizer.ShowExtraFields(Stream: TStream; Size: Integer;
FileHeader: TCentralDirectoryFileHeader);
var
Buff, EOFBuff: Pointer;
BuffCount: Integer;
HeaderID, BlockSize: Word;
function GetOffset(Value: Integer): Pointer;
begin
Result := Pointer(Integer(EOFBuff) - Value);
end;
function ByteToStr(Bytes: PByte; Size: Integer): string;
const
BytesHex: array[0..15] of char =
('0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
var
I: integer;
begin
SetLength(Result, Size shl 1);
for I := 0 to Size - 1 do
begin
Result[I * 2 + 1] := BytesHex[Bytes^ shr 4];
Result[I * 2 + 2] := BytesHex[Bytes^ and $0F];
Inc(Bytes);
end;
end;
var
ExDataStream: TMemoryStream;
StartPos: Int64;
begin
if Size = 0 then Exit;
StartPos := Stream.Position;
Log('EXDATA found at offset: ' + IntToStr(StartPos));
Log(Delim);
GetMem(Buff, Size);
try
BuffCount := Size;
Stream.ReadBuffer(Buff^, BuffCount);
EOFBuff := Pointer(Integer(Buff) + BuffCount);
while BuffCount > 0 do
begin
HeaderID := PWord(GetOffset(BuffCount))^;
Dec(BuffCount, 2);
BlockSize := PWord(GetOffset(BuffCount))^;
Dec(BuffCount, 2);
case HeaderID of
SUPPORTED_EXDATA_ZIP64:
begin
Log('SUPPORTED_EXDATA_ZIP64 found at offset: ' +
IntToStr(StartPos + Size - BuffCount - 4));
if FileHeader.UncompressedSize = MAXDWORD then
begin
if BuffCount < 8 then Break;
Log('UncompressedSize: ' + IntToStr(PInt64(GetOffset(BuffCount))^));
Dec(BuffCount, 8);
Dec(BlockSize, 8);
end;
if FileHeader.CompressedSize = MAXDWORD then
begin
if BuffCount < 8 then Break;
Log('CompressedSize: ' + IntToStr(PInt64(GetOffset(BuffCount))^));
Dec(BuffCount, 8);
Dec(BlockSize, 8);
end;
if FileHeader.RelativeOffsetOfLocalHeader = MAXDWORD then
begin
if BuffCount < 8 then Break;
Log('RelativeOffsetOfLocalHeader: ' + IntToStr(PInt64(GetOffset(BuffCount))^));
Dec(BuffCount, 8);
Dec(BlockSize, 8);
end;
if FileHeader.DiskNumberStart = MAXWORD then
begin
if BuffCount < 4 then Break;
Log('DiskNumberStart: ' + IntToStr(PInt64(GetOffset(BuffCount))^));
Dec(BuffCount, 4);
Dec(BlockSize, 4);
end;
Dec(BuffCount, BlockSize);
Log(Delim);
end;
SUPPORTED_EXDATA_NTFSTIME:
begin
if BuffCount < 32 then Break;
if BlockSize <> 32 then
begin
Dec(BuffCount, BlockSize);
Continue;
end;
Dec(BuffCount, 4);
if PWord(GetOffset(BuffCount))^ <> 1 then
begin
Dec(BuffCount, BlockSize);
Continue;
end;
Dec(BuffCount, 2);
if PWord(GetOffset(BuffCount))^ <> SizeOf(TNTFSFileTime) then
begin
Dec(BuffCount, BlockSize);
Continue;
end;
Dec(BuffCount, 2);
Log('SUPPORTED_EXDATA_NTFSTIME found at offset: ' +
IntToStr(StartPos + Size - BuffCount - 12));
Log(Delim);
end;
else
Log(Format('UNKNOWN EXDATA TAG %d found at offset: %d',
[HeaderID, StartPos + Size - BuffCount - 8]));
ExDataStream := TMemoryStream.Create;
try
ExDataStream.WriteBuffer(GetOffset(BuffCount)^, BlockSize);
ExDataStream.Position := 0;
Log(ByteToStr(ExDataStream.Memory, ExDataStream.Size));
finally
ExDataStream.Free;
end;
Log(Delim);
end;
Dec(BuffCount, BlockSize);
end;
finally
FreeMem(Buff);
end;
end;
procedure TdlgZipAnalizer.ShowLocalFileHeader(Stream: TStream);
var
Data: TLocalFileHeader;
FileName: string;
begin
Log('LOCAL_FILE_HEADER_SIGNATURE found at offset: ' + IntToStr(Stream.Position));
Stream.ReadBuffer(Data, SizeOf(TLocalFileHeader));
with Data do
begin
if LocalFileHeaderSignature <> LOCAL_FILE_HEADER_SIGNATURE then
Log('INVALID SIGNATURE!!!!');
Log(Format('VersionNeededToExtract: %d', [VersionNeededToExtract]));
Log(Format('GeneralPurposeBitFlag: %d (%s)', [GeneralPurposeBitFlag,
GPBFToStr(GeneralPurposeBitFlag)]));
Log(Format('CompressionMethod: %d', [CompressionMethod]));
Log(Format('LastModFileTimeTime: %d', [LastModFileTimeTime]));
Log(Format('LastModFileTimeDate: %d', [LastModFileTimeDate]));
Log(Format('Crc32: %d', [Crc32]));
Log(Format('CompressedSize: %d', [CompressedSize]));
Log(Format('UncompressedSize: %d', [UncompressedSize]));
Log(Format('FilenameLength: %d', [FilenameLength]));
Log(Format('ExtraFieldLength: %d', [ExtraFieldLength]));
LoadStringValue(Stream, FileName, FilenameLength,
GeneralPurposeBitFlag and PBF_UTF8 <> 0);
Log('>>> FileName: ' + FileName);
//Stream.Position := Stream.Position + CompressedSize;
end;
Log(Delim);
end;
procedure TdlgZipAnalizer.ShowZip64(Stream: TStream);
var
Data: TZip64EOFCentralDirectoryRecord;
begin
Log('ZIP64_END_OF_CENTRAL_DIR_SIGNATURE found at offset: ' + IntToStr(Stream.Position));
Stream.ReadBuffer(Data, SizeOf(TZip64EOFCentralDirectoryRecord));
with Data do
begin
if Zip64EndOfCentralDirSignature <> ZIP64_END_OF_CENTRAL_DIR_SIGNATURE then
Log('INVALID SIGNATURE!!!!');
Log(Format('SizeOfZip64EOFCentralDirectoryRecord: %d', [SizeOfZip64EOFCentralDirectoryRecord]));
Log(Format('VersionMadeBy: %d', [VersionMadeBy]));
Log(Format('VersionNeededToExtract: %d', [VersionNeededToExtract]));
Log(Format('number of this disk: %d', [Number1]));
Log(Format('number of the disk with the start of the central directory: %d', [Number2]));
Log(Format('total number of entries in the central directory on this disk: %d', [TotalNumber1]));
Log(Format('total number of entries in the central directory: %d', [TotalNumber2]));
Log(Format('size of the central directory: %d', [Size]));
Log(Format('offset of start of central directory with respect to the starting disk number: %d', [Offset]));
end;
Log(Delim);
end;
procedure TdlgZipAnalizer.ShowZip64Locator(Stream: TStream);
var
Data: TZip64EOFCentralDirectoryLocator;
begin
Log('ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE found at offset: ' + IntToStr(Stream.Position));
Stream.ReadBuffer(Data, SizeOf(TZip64EOFCentralDirectoryLocator));
with Data do
begin
if Signature <> ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE then
Log('INVALID SIGNATURE!!!!');
Log(Format('NumberOfTheDisk: %d', [NumberOfTheDisk]));
Log(Format('RelativeOffset: %d', [RelativeOffset]));
Log(Format('TotalNumberOfDisks: %d', [TotalNumberOfDisks]));
end;
Log(Delim);
end;
end.

View File

@ -0,0 +1,619 @@
Network Working Group P. Deutsch
Request for Comments: 1950 Aladdin Enterprises
Category: Informational J-L. Gailly
Info-ZIP
May 1996
ZLIB Compressed Data Format Specification version 3.3
Status of This Memo
This memo provides information for the Internet community. This memo
does not specify an Internet standard of any kind. Distribution of
this memo is unlimited.
IESG Note:
The IESG takes no position on the validity of any Intellectual
Property Rights statements contained in this document.
Notices
Copyright (c) 1996 L. Peter Deutsch and Jean-Loup Gailly
Permission is granted to copy and distribute this document for any
purpose and without charge, including translations into other
languages and incorporation into compilations, provided that the
copyright notice and this notice are preserved, and that any
substantive changes or deletions from the original are clearly
marked.
A pointer to the latest version of this and related documentation in
HTML format can be found at the URL
<ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
Abstract
This specification defines a lossless compressed data format. The
data can be produced or consumed, even for an arbitrarily long
sequentially presented input data stream, using only an a priori
bounded amount of intermediate storage. The format presently uses
the DEFLATE compression method but can be easily extended to use
other compression methods. It can be implemented readily in a manner
not covered by patents. This specification also defines the ADLER-32
checksum (an extension and improvement of the Fletcher checksum),
used for detection of data corruption, and provides an algorithm for
computing it.
Deutsch & Gailly Informational [Page 1]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
Table of Contents
1. Introduction ................................................... 2
1.1. Purpose ................................................... 2
1.2. Intended audience ......................................... 3
1.3. Scope ..................................................... 3
1.4. Compliance ................................................ 3
1.5. Definitions of terms and conventions used ................ 3
1.6. Changes from previous versions ............................ 3
2. Detailed specification ......................................... 3
2.1. Overall conventions ....................................... 3
2.2. Data format ............................................... 4
2.3. Compliance ................................................ 7
3. References ..................................................... 7
4. Source code .................................................... 8
5. Security Considerations ........................................ 8
6. Acknowledgements ............................................... 8
7. Authors' Addresses ............................................. 8
8. Appendix: Rationale ............................................ 9
9. Appendix: Sample code ..........................................10
1. Introduction
1.1. Purpose
The purpose of this specification is to define a lossless
compressed data format that:
* Is independent of CPU type, operating system, file system,
and character set, and hence can be used for interchange;
* Can be produced or consumed, even for an arbitrarily long
sequentially presented input data stream, using only an a
priori bounded amount of intermediate storage, and hence can
be used in data communications or similar structures such as
Unix filters;
* Can use a number of different compression methods;
* Can be implemented readily in a manner not covered by
patents, and hence can be practiced freely.
The data format defined by this specification does not attempt to
allow random access to compressed data.
Deutsch & Gailly Informational [Page 2]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
1.2. Intended audience
This specification is intended for use by implementors of software
to compress data into zlib format and/or decompress data from zlib
format.
The text of the specification assumes a basic background in
programming at the level of bits and other primitive data
representations.
1.3. Scope
The specification specifies a compressed data format that can be
used for in-memory compression of a sequence of arbitrary bytes.
1.4. Compliance
Unless otherwise indicated below, a compliant decompressor must be
able to accept and decompress any data set that conforms to all
the specifications presented here; a compliant compressor must
produce data sets that conform to all the specifications presented
here.
1.5. Definitions of terms and conventions used
byte: 8 bits stored or transmitted as a unit (same as an octet).
(For this specification, a byte is exactly 8 bits, even on
machines which store a character on a number of bits different
from 8.) See below, for the numbering of bits within a byte.
1.6. Changes from previous versions
Version 3.1 was the first public release of this specification.
In version 3.2, some terminology was changed and the Adler-32
sample code was rewritten for clarity. In version 3.3, the
support for a preset dictionary was introduced, and the
specification was converted to RFC style.
2. Detailed specification
2.1. Overall conventions
In the diagrams below, a box like this:
+---+
| | <-- the vertical bars might be missing
+---+
Deutsch & Gailly Informational [Page 3]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
represents one byte; a box like this:
+==============+
| |
+==============+
represents a variable number of bytes.
Bytes stored within a computer do not have a "bit order", since
they are always treated as a unit. However, a byte considered as
an integer between 0 and 255 does have a most- and least-
significant bit, and since we write numbers with the most-
significant digit on the left, we also write bytes with the most-
significant bit on the left. In the diagrams below, we number the
bits of a byte so that bit 0 is the least-significant bit, i.e.,
the bits are numbered:
+--------+
|76543210|
+--------+
Within a computer, a number may occupy multiple bytes. All
multi-byte numbers in the format described here are stored with
the MOST-significant byte first (at the lower memory address).
For example, the decimal number 520 is stored as:
0 1
+--------+--------+
|00000010|00001000|
+--------+--------+
^ ^
| |
| + less significant byte = 8
+ more significant byte = 2 x 256
2.2. Data format
A zlib stream has the following structure:
0 1
+---+---+
|CMF|FLG| (more-->)
+---+---+
Deutsch & Gailly Informational [Page 4]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
(if FLG.FDICT set)
0 1 2 3
+---+---+---+---+
| DICTID | (more-->)
+---+---+---+---+
+=====================+---+---+---+---+
|...compressed data...| ADLER32 |
+=====================+---+---+---+---+
Any data which may appear after ADLER32 are not part of the zlib
stream.
CMF (Compression Method and flags)
This byte is divided into a 4-bit compression method and a 4-
bit information field depending on the compression method.
bits 0 to 3 CM Compression method
bits 4 to 7 CINFO Compression info
CM (Compression method)
This identifies the compression method used in the file. CM = 8
denotes the "deflate" compression method with a window size up
to 32K. This is the method used by gzip and PNG (see
references [1] and [2] in Chapter 3, below, for the reference
documents). CM = 15 is reserved. It might be used in a future
version of this specification to indicate the presence of an
extra field before the compressed data.
CINFO (Compression info)
For CM = 8, CINFO is the base-2 logarithm of the LZ77 window
size, minus eight (CINFO=7 indicates a 32K window size). Values
of CINFO above 7 are not allowed in this version of the
specification. CINFO is not defined in this specification for
CM not equal to 8.
FLG (FLaGs)
This flag byte is divided as follows:
bits 0 to 4 FCHECK (check bits for CMF and FLG)
bit 5 FDICT (preset dictionary)
bits 6 to 7 FLEVEL (compression level)
The FCHECK value must be such that CMF and FLG, when viewed as
a 16-bit unsigned integer stored in MSB order (CMF*256 + FLG),
is a multiple of 31.
Deutsch & Gailly Informational [Page 5]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
FDICT (Preset dictionary)
If FDICT is set, a DICT dictionary identifier is present
immediately after the FLG byte. The dictionary is a sequence of
bytes which are initially fed to the compressor without
producing any compressed output. DICT is the Adler-32 checksum
of this sequence of bytes (see the definition of ADLER32
below). The decompressor can use this identifier to determine
which dictionary has been used by the compressor.
FLEVEL (Compression level)
These flags are available for use by specific compression
methods. The "deflate" method (CM = 8) sets these flags as
follows:
0 - compressor used fastest algorithm
1 - compressor used fast algorithm
2 - compressor used default algorithm
3 - compressor used maximum compression, slowest algorithm
The information in FLEVEL is not needed for decompression; it
is there to indicate if recompression might be worthwhile.
compressed data
For compression method 8, the compressed data is stored in the
deflate compressed data format as described in the document
"DEFLATE Compressed Data Format Specification" by L. Peter
Deutsch. (See reference [3] in Chapter 3, below)
Other compressed data formats are not specified in this version
of the zlib specification.
ADLER32 (Adler-32 checksum)
This contains a checksum value of the uncompressed data
(excluding any dictionary data) computed according to Adler-32
algorithm. This algorithm is a 32-bit extension and improvement
of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073
standard. See references [4] and [5] in Chapter 3, below)
Adler-32 is composed of two sums accumulated per byte: s1 is
the sum of all bytes, s2 is the sum of all s1 values. Both sums
are done modulo 65521. s1 is initialized to 1, s2 to zero. The
Adler-32 checksum is stored as s2*65536 + s1 in most-
significant-byte first (network) order.
Deutsch & Gailly Informational [Page 6]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
2.3. Compliance
A compliant compressor must produce streams with correct CMF, FLG
and ADLER32, but need not support preset dictionaries. When the
zlib data format is used as part of another standard data format,
the compressor may use only preset dictionaries that are specified
by this other data format. If this other format does not use the
preset dictionary feature, the compressor must not set the FDICT
flag.
A compliant decompressor must check CMF, FLG, and ADLER32, and
provide an error indication if any of these have incorrect values.
A compliant decompressor must give an error indication if CM is
not one of the values defined in this specification (only the
value 8 is permitted in this version), since another value could
indicate the presence of new features that would cause subsequent
data to be interpreted incorrectly. A compliant decompressor must
give an error indication if FDICT is set and DICTID is not the
identifier of a known preset dictionary. A decompressor may
ignore FLEVEL and still be compliant. When the zlib data format
is being used as a part of another standard format, a compliant
decompressor must support all the preset dictionaries specified by
the other format. When the other format does not use the preset
dictionary feature, a compliant decompressor must reject any
stream in which the FDICT flag is set.
3. References
[1] Deutsch, L.P.,"GZIP Compressed Data Format Specification",
available in ftp://ftp.uu.net/pub/archiving/zip/doc/
[2] Thomas Boutell, "PNG (Portable Network Graphics) specification",
available in ftp://ftp.uu.net/graphics/png/documents/
[3] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification",
available in ftp://ftp.uu.net/pub/archiving/zip/doc/
[4] Fletcher, J. G., "An Arithmetic Checksum for Serial
Transmissions," IEEE Transactions on Communications, Vol. COM-30,
No. 1, January 1982, pp. 247-252.
[5] ITU-T Recommendation X.224, Annex D, "Checksum Algorithms,"
November, 1993, pp. 144, 145. (Available from
gopher://info.itu.ch). ITU-T X.244 is also the same as ISO 8073.
Deutsch & Gailly Informational [Page 7]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
4. Source code
Source code for a C language implementation of a "zlib" compliant
library is available at ftp://ftp.uu.net/pub/archiving/zip/zlib/.
5. Security Considerations
A decoder that fails to check the ADLER32 checksum value may be
subject to undetected data corruption.
6. Acknowledgements
Trademarks cited in this document are the property of their
respective owners.
Jean-Loup Gailly and Mark Adler designed the zlib format and wrote
the related software described in this specification. Glenn
Randers-Pehrson converted this document to RFC and HTML format.
7. Authors' Addresses
L. Peter Deutsch
Aladdin Enterprises
203 Santa Margarita Ave.
Menlo Park, CA 94025
Phone: (415) 322-0103 (AM only)
FAX: (415) 322-1734
EMail: <ghost@aladdin.com>
Jean-Loup Gailly
EMail: <gzip@prep.ai.mit.edu>
Questions about the technical content of this specification can be
sent by email to
Jean-Loup Gailly <gzip@prep.ai.mit.edu> and
Mark Adler <madler@alumni.caltech.edu>
Editorial comments on this specification can be sent by email to
L. Peter Deutsch <ghost@aladdin.com> and
Glenn Randers-Pehrson <randeg@alumni.rpi.edu>
Deutsch & Gailly Informational [Page 8]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
8. Appendix: Rationale
8.1. Preset dictionaries
A preset dictionary is specially useful to compress short input
sequences. The compressor can take advantage of the dictionary
context to encode the input in a more compact manner. The
decompressor can be initialized with the appropriate context by
virtually decompressing a compressed version of the dictionary
without producing any output. However for certain compression
algorithms such as the deflate algorithm this operation can be
achieved without actually performing any decompression.
The compressor and the decompressor must use exactly the same
dictionary. The dictionary may be fixed or may be chosen among a
certain number of predefined dictionaries, according to the kind
of input data. The decompressor can determine which dictionary has
been chosen by the compressor by checking the dictionary
identifier. This document does not specify the contents of
predefined dictionaries, since the optimal dictionaries are
application specific. Standard data formats using this feature of
the zlib specification must precisely define the allowed
dictionaries.
8.2. The Adler-32 algorithm
The Adler-32 algorithm is much faster than the CRC32 algorithm yet
still provides an extremely low probability of undetected errors.
The modulo on unsigned long accumulators can be delayed for 5552
bytes, so the modulo operation time is negligible. If the bytes
are a, b, c, the second sum is 3a + 2b + c + 3, and so is position
and order sensitive, unlike the first sum, which is just a
checksum. That 65521 is prime is important to avoid a possible
large class of two-byte errors that leave the check unchanged.
(The Fletcher checksum uses 255, which is not prime and which also
makes the Fletcher check insensitive to single byte changes 0 <->
255.)
The sum s1 is initialized to 1 instead of zero to make the length
of the sequence part of s2, so that the length does not have to be
checked separately. (Any sequence of zeroes has a Fletcher
checksum of zero.)
Deutsch & Gailly Informational [Page 9]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
9. Appendix: Sample code
The following C code computes the Adler-32 checksum of a data buffer.
It is written for clarity, not for speed. The sample code is in the
ANSI C programming language. Non C users may find it easier to read
with these hints:
& Bitwise AND operator.
>> Bitwise right shift operator. When applied to an
unsigned quantity, as here, right shift inserts zero bit(s)
at the left.
<< Bitwise left shift operator. Left shift inserts zero
bit(s) at the right.
++ "n++" increments the variable n.
% modulo operator: a % b is the remainder of a divided by b.
#define BASE 65521 /* largest prime smaller than 65536 */
/*
Update a running Adler-32 checksum with the bytes buf[0..len-1]
and return the updated checksum. The Adler-32 checksum should be
initialized to 1.
Usage example:
unsigned long adler = 1L;
while (read_buffer(buffer, length) != EOF) {
adler = update_adler32(adler, buffer, length);
}
if (adler != original_adler) error();
*/
unsigned long update_adler32(unsigned long adler,
unsigned char *buf, int len)
{
unsigned long s1 = adler & 0xffff;
unsigned long s2 = (adler >> 16) & 0xffff;
int n;
for (n = 0; n < len; n++) {
s1 = (s1 + buf[n]) % BASE;
s2 = (s2 + s1) % BASE;
}
return (s2 << 16) + s1;
}
/* Return the adler32 of the bytes buf[0..len-1] */
Deutsch & Gailly Informational [Page 10]
RFC 1950 ZLIB Compressed Data Format Specification May 1996
unsigned long adler32(unsigned char *buf, int len)
{
return update_adler32(1L, buf, len);
}
Deutsch & Gailly Informational [Page 11]

View File

@ -0,0 +1,955 @@
Network Working Group P. Deutsch
Request for Comments: 1951 Aladdin Enterprises
Category: Informational May 1996
DEFLATE Compressed Data Format Specification version 1.3
Status of This Memo
This memo provides information for the Internet community. This memo
does not specify an Internet standard of any kind. Distribution of
this memo is unlimited.
IESG Note:
The IESG takes no position on the validity of any Intellectual
Property Rights statements contained in this document.
Notices
Copyright (c) 1996 L. Peter Deutsch
Permission is granted to copy and distribute this document for any
purpose and without charge, including translations into other
languages and incorporation into compilations, provided that the
copyright notice and this notice are preserved, and that any
substantive changes or deletions from the original are clearly
marked.
A pointer to the latest version of this and related documentation in
HTML format can be found at the URL
<ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
Abstract
This specification defines a lossless compressed data format that
compresses data using a combination of the LZ77 algorithm and Huffman
coding, with efficiency comparable to the best currently available
general-purpose compression methods. The data can be produced or
consumed, even for an arbitrarily long sequentially presented input
data stream, using only an a priori bounded amount of intermediate
storage. The format can be implemented readily in a manner not
covered by patents.
Deutsch Informational [Page 1]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
Table of Contents
1. Introduction ................................................... 2
1.1. Purpose ................................................... 2
1.2. Intended audience ......................................... 3
1.3. Scope ..................................................... 3
1.4. Compliance ................................................ 3
1.5. Definitions of terms and conventions used ................ 3
1.6. Changes from previous versions ............................ 4
2. Compressed representation overview ............................. 4
3. Detailed specification ......................................... 5
3.1. Overall conventions ....................................... 5
3.1.1. Packing into bytes .................................. 5
3.2. Compressed block format ................................... 6
3.2.1. Synopsis of prefix and Huffman coding ............... 6
3.2.2. Use of Huffman coding in the "deflate" format ....... 7
3.2.3. Details of block format ............................. 9
3.2.4. Non-compressed blocks (BTYPE=00) ................... 11
3.2.5. Compressed blocks (length and distance codes) ...... 11
3.2.6. Compression with fixed Huffman codes (BTYPE=01) .... 12
3.2.7. Compression with dynamic Huffman codes (BTYPE=10) .. 13
3.3. Compliance ............................................... 14
4. Compression algorithm details ................................. 14
5. References .................................................... 16
6. Security Considerations ....................................... 16
7. Source code ................................................... 16
8. Acknowledgements .............................................. 16
9. Author's Address .............................................. 17
1. Introduction
1.1. Purpose
The purpose of this specification is to define a lossless
compressed data format that:
* Is independent of CPU type, operating system, file system,
and character set, and hence can be used for interchange;
* Can be produced or consumed, even for an arbitrarily long
sequentially presented input data stream, using only an a
priori bounded amount of intermediate storage, and hence
can be used in data communications or similar structures
such as Unix filters;
* Compresses data with efficiency comparable to the best
currently available general-purpose compression methods,
and in particular considerably better than the "compress"
program;
* Can be implemented readily in a manner not covered by
patents, and hence can be practiced freely;
Deutsch Informational [Page 2]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
* Is compatible with the file format produced by the current
widely used gzip utility, in that conforming decompressors
will be able to read data produced by the existing gzip
compressor.
The data format defined by this specification does not attempt to:
* Allow random access to compressed data;
* Compress specialized data (e.g., raster graphics) as well
as the best currently available specialized algorithms.
A simple counting argument shows that no lossless compression
algorithm can compress every possible input data set. For the
format defined here, the worst case expansion is 5 bytes per 32K-
byte block, i.e., a size increase of 0.015% for large data sets.
English text usually compresses by a factor of 2.5 to 3;
executable files usually compress somewhat less; graphical data
such as raster images may compress much more.
1.2. Intended audience
This specification is intended for use by implementors of software
to compress data into "deflate" format and/or decompress data from
"deflate" format.
The text of the specification assumes a basic background in
programming at the level of bits and other primitive data
representations. Familiarity with the technique of Huffman coding
is helpful but not required.
1.3. Scope
The specification specifies a method for representing a sequence
of bytes as a (usually shorter) sequence of bits, and a method for
packing the latter bit sequence into bytes.
1.4. Compliance
Unless otherwise indicated below, a compliant decompressor must be
able to accept and decompress any data set that conforms to all
the specifications presented here; a compliant compressor must
produce data sets that conform to all the specifications presented
here.
1.5. Definitions of terms and conventions used
Byte: 8 bits stored or transmitted as a unit (same as an octet).
For this specification, a byte is exactly 8 bits, even on machines
Deutsch Informational [Page 3]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
which store a character on a number of bits different from eight.
See below, for the numbering of bits within a byte.
String: a sequence of arbitrary bytes.
1.6. Changes from previous versions
There have been no technical changes to the deflate format since
version 1.1 of this specification. In version 1.2, some
terminology was changed. Version 1.3 is a conversion of the
specification to RFC style.
2. Compressed representation overview
A compressed data set consists of a series of blocks, corresponding
to successive blocks of input data. The block sizes are arbitrary,
except that non-compressible blocks are limited to 65,535 bytes.
Each block is compressed using a combination of the LZ77 algorithm
and Huffman coding. The Huffman trees for each block are independent
of those for previous or subsequent blocks; the LZ77 algorithm may
use a reference to a duplicated string occurring in a previous block,
up to 32K input bytes before.
Each block consists of two parts: a pair of Huffman code trees that
describe the representation of the compressed data part, and a
compressed data part. (The Huffman trees themselves are compressed
using Huffman encoding.) The compressed data consists of a series of
elements of two types: literal bytes (of strings that have not been
detected as duplicated within the previous 32K input bytes), and
pointers to duplicated strings, where a pointer is represented as a
pair <length, backward distance>. The representation used in the
"deflate" format limits distances to 32K bytes and lengths to 258
bytes, but does not limit the size of a block, except for
uncompressible blocks, which are limited as noted above.
Each type of value (literals, distances, and lengths) in the
compressed data is represented using a Huffman code, using one code
tree for literals and lengths and a separate code tree for distances.
The code trees for each block appear in a compact form just before
the compressed data for that block.
Deutsch Informational [Page 4]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
3. Detailed specification
3.1. Overall conventions In the diagrams below, a box like this:
+---+
| | <-- the vertical bars might be missing
+---+
represents one byte; a box like this:
+==============+
| |
+==============+
represents a variable number of bytes.
Bytes stored within a computer do not have a "bit order", since
they are always treated as a unit. However, a byte considered as
an integer between 0 and 255 does have a most- and least-
significant bit, and since we write numbers with the most-
significant digit on the left, we also write bytes with the most-
significant bit on the left. In the diagrams below, we number the
bits of a byte so that bit 0 is the least-significant bit, i.e.,
the bits are numbered:
+--------+
|76543210|
+--------+
Within a computer, a number may occupy multiple bytes. All
multi-byte numbers in the format described here are stored with
the least-significant byte first (at the lower memory address).
For example, the decimal number 520 is stored as:
0 1
+--------+--------+
|00001000|00000010|
+--------+--------+
^ ^
| |
| + more significant byte = 2 x 256
+ less significant byte = 8
3.1.1. Packing into bytes
This document does not address the issue of the order in which
bits of a byte are transmitted on a bit-sequential medium,
since the final data format described here is byte- rather than
Deutsch Informational [Page 5]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
bit-oriented. However, we describe the compressed block format
in below, as a sequence of data elements of various bit
lengths, not a sequence of bytes. We must therefore specify
how to pack these data elements into bytes to form the final
compressed byte sequence:
* Data elements are packed into bytes in order of
increasing bit number within the byte, i.e., starting
with the least-significant bit of the byte.
* Data elements other than Huffman codes are packed
starting with the least-significant bit of the data
element.
* Huffman codes are packed starting with the most-
significant bit of the code.
In other words, if one were to print out the compressed data as
a sequence of bytes, starting with the first byte at the
*right* margin and proceeding to the *left*, with the most-
significant bit of each byte on the left as usual, one would be
able to parse the result from right to left, with fixed-width
elements in the correct MSB-to-LSB order and Huffman codes in
bit-reversed order (i.e., with the first bit of the code in the
relative LSB position).
3.2. Compressed block format
3.2.1. Synopsis of prefix and Huffman coding
Prefix coding represents symbols from an a priori known
alphabet by bit sequences (codes), one code for each symbol, in
a manner such that different symbols may be represented by bit
sequences of different lengths, but a parser can always parse
an encoded string unambiguously symbol-by-symbol.
We define a prefix code in terms of a binary tree in which the
two edges descending from each non-leaf node are labeled 0 and
1 and in which the leaf nodes correspond one-for-one with (are
labeled with) the symbols of the alphabet; then the code for a
symbol is the sequence of 0's and 1's on the edges leading from
the root to the leaf labeled with that symbol. For example:
Deutsch Informational [Page 6]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
/\ Symbol Code
0 1 ------ ----
/ \ A 00
/\ B B 1
0 1 C 011
/ \ D 010
A /\
0 1
/ \
D C
A parser can decode the next symbol from an encoded input
stream by walking down the tree from the root, at each step
choosing the edge corresponding to the next input bit.
Given an alphabet with known symbol frequencies, the Huffman
algorithm allows the construction of an optimal prefix code
(one which represents strings with those symbol frequencies
using the fewest bits of any possible prefix codes for that
alphabet). Such a code is called a Huffman code. (See
reference [1] in Chapter 5, references for additional
information on Huffman codes.)
Note that in the "deflate" format, the Huffman codes for the
various alphabets must not exceed certain maximum code lengths.
This constraint complicates the algorithm for computing code
lengths from symbol frequencies. Again, see Chapter 5,
references for details.
3.2.2. Use of Huffman coding in the "deflate" format
The Huffman codes used for each alphabet in the "deflate"
format have two additional rules:
* All codes of a given bit length have lexicographically
consecutive values, in the same order as the symbols
they represent;
* Shorter codes lexicographically precede longer codes.
Deutsch Informational [Page 7]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
We could recode the example above to follow this rule as
follows, assuming that the order of the alphabet is ABCD:
Symbol Code
------ ----
A 10
B 0
C 110
D 111
I.e., 0 precedes 10 which precedes 11x, and 110 and 111 are
lexicographically consecutive.
Given this rule, we can define the Huffman code for an alphabet
just by giving the bit lengths of the codes for each symbol of
the alphabet in order; this is sufficient to determine the
actual codes. In our example, the code is completely defined
by the sequence of bit lengths (2, 1, 3, 3). The following
algorithm generates the codes as integers, intended to be read
from most- to least-significant bit. The code lengths are
initially in tree[I].Len; the codes are produced in
tree[I].Code.
1) Count the number of codes for each code length. Let
bl_count[N] be the number of codes of length N, N >= 1.
2) Find the numerical value of the smallest code for each
code length:
code = 0;
bl_count[0] = 0;
for (bits = 1; bits <= MAX_BITS; bits++) {
code = (code + bl_count[bits-1]) << 1;
next_code[bits] = code;
}
3) Assign numerical values to all codes, using consecutive
values for all codes of the same length with the base
values determined at step 2. Codes that are never used
(which have a bit length of zero) must not be assigned a
value.
for (n = 0; n <= max_code; n++) {
len = tree[n].Len;
if (len != 0) {
tree[n].Code = next_code[len];
next_code[len]++;
}
Deutsch Informational [Page 8]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
}
Example:
Consider the alphabet ABCDEFGH, with bit lengths (3, 3, 3, 3,
3, 2, 4, 4). After step 1, we have:
N bl_count[N]
- -----------
2 1
3 5
4 2
Step 2 computes the following next_code values:
N next_code[N]
- ------------
1 0
2 0
3 2
4 14
Step 3 produces the following code values:
Symbol Length Code
------ ------ ----
A 3 010
B 3 011
C 3 100
D 3 101
E 3 110
F 2 00
G 4 1110
H 4 1111
3.2.3. Details of block format
Each block of compressed data begins with 3 header bits
containing the following data:
first bit BFINAL
next 2 bits BTYPE
Note that the header bits do not necessarily begin on a byte
boundary, since a block does not necessarily occupy an integral
number of bytes.
Deutsch Informational [Page 9]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
BFINAL is set if and only if this is the last block of the data
set.
BTYPE specifies how the data are compressed, as follows:
00 - no compression
01 - compressed with fixed Huffman codes
10 - compressed with dynamic Huffman codes
11 - reserved (error)
The only difference between the two compressed cases is how the
Huffman codes for the literal/length and distance alphabets are
defined.
In all cases, the decoding algorithm for the actual data is as
follows:
do
read block header from input stream.
if stored with no compression
skip any remaining bits in current partially
processed byte
read LEN and NLEN (see next section)
copy LEN bytes of data to output
otherwise
if compressed with dynamic Huffman codes
read representation of code trees (see
subsection below)
loop (until end of block code recognized)
decode literal/length value from input stream
if value < 256
copy value (literal byte) to output stream
otherwise
if value = end of block (256)
break from loop
otherwise (value = 257..285)
decode distance from input stream
move backwards distance bytes in the output
stream, and copy length bytes from this
position to the output stream.
end loop
while not last block
Note that a duplicated string reference may refer to a string
in a previous block; i.e., the backward distance may cross one
or more block boundaries. However a distance cannot refer past
the beginning of the output stream. (An application using a
Deutsch Informational [Page 10]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
preset dictionary might discard part of the output stream; a
distance can refer to that part of the output stream anyway)
Note also that the referenced string may overlap the current
position; for example, if the last 2 bytes decoded have values
X and Y, a string reference with <length = 5, distance = 2>
adds X,Y,X,Y,X to the output stream.
We now specify each compression method in turn.
3.2.4. Non-compressed blocks (BTYPE=00)
Any bits of input up to the next byte boundary are ignored.
The rest of the block consists of the following information:
0 1 2 3 4...
+---+---+---+---+================================+
| LEN | NLEN |... LEN bytes of literal data...|
+---+---+---+---+================================+
LEN is the number of data bytes in the block. NLEN is the
one's complement of LEN.
3.2.5. Compressed blocks (length and distance codes)
As noted above, encoded data blocks in the "deflate" format
consist of sequences of symbols drawn from three conceptually
distinct alphabets: either literal bytes, from the alphabet of
byte values (0..255), or <length, backward distance> pairs,
where the length is drawn from (3..258) and the distance is
drawn from (1..32,768). In fact, the literal and length
alphabets are merged into a single alphabet (0..285), where
values 0..255 represent literal bytes, the value 256 indicates
end-of-block, and values 257..285 represent length codes
(possibly in conjunction with extra bits following the symbol
code) as follows:
Deutsch Informational [Page 11]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
Extra Extra Extra
Code Bits Length(s) Code Bits Lengths Code Bits Length(s)
---- ---- ------ ---- ---- ------- ---- ---- -------
257 0 3 267 1 15,16 277 4 67-82
258 0 4 268 1 17,18 278 4 83-98
259 0 5 269 2 19-22 279 4 99-114
260 0 6 270 2 23-26 280 4 115-130
261 0 7 271 2 27-30 281 5 131-162
262 0 8 272 2 31-34 282 5 163-194
263 0 9 273 3 35-42 283 5 195-226
264 0 10 274 3 43-50 284 5 227-257
265 1 11,12 275 3 51-58 285 0 258
266 1 13,14 276 3 59-66
The extra bits should be interpreted as a machine integer
stored with the most-significant bit first, e.g., bits 1110
represent the value 14.
Extra Extra Extra
Code Bits Dist Code Bits Dist Code Bits Distance
---- ---- ---- ---- ---- ------ ---- ---- --------
0 0 1 10 4 33-48 20 9 1025-1536
1 0 2 11 4 49-64 21 9 1537-2048
2 0 3 12 5 65-96 22 10 2049-3072
3 0 4 13 5 97-128 23 10 3073-4096
4 1 5,6 14 6 129-192 24 11 4097-6144
5 1 7,8 15 6 193-256 25 11 6145-8192
6 2 9-12 16 7 257-384 26 12 8193-12288
7 2 13-16 17 7 385-512 27 12 12289-16384
8 3 17-24 18 8 513-768 28 13 16385-24576
9 3 25-32 19 8 769-1024 29 13 24577-32768
3.2.6. Compression with fixed Huffman codes (BTYPE=01)
The Huffman codes for the two alphabets are fixed, and are not
represented explicitly in the data. The Huffman code lengths
for the literal/length alphabet are:
Lit Value Bits Codes
--------- ---- -----
0 - 143 8 00110000 through
10111111
144 - 255 9 110010000 through
111111111
256 - 279 7 0000000 through
0010111
280 - 287 8 11000000 through
11000111
Deutsch Informational [Page 12]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
The code lengths are sufficient to generate the actual codes,
as described above; we show the codes in the table for added
clarity. Literal/length values 286-287 will never actually
occur in the compressed data, but participate in the code
construction.
Distance codes 0-31 are represented by (fixed-length) 5-bit
codes, with possible additional bits as shown in the table
shown in Paragraph 3.2.5, above. Note that distance codes 30-
31 will never actually occur in the compressed data.
3.2.7. Compression with dynamic Huffman codes (BTYPE=10)
The Huffman codes for the two alphabets appear in the block
immediately after the header bits and before the actual
compressed data, first the literal/length code and then the
distance code. Each code is defined by a sequence of code
lengths, as discussed in Paragraph 3.2.2, above. For even
greater compactness, the code length sequences themselves are
compressed using a Huffman code. The alphabet for code lengths
is as follows:
0 - 15: Represent code lengths of 0 - 15
16: Copy the previous code length 3 - 6 times.
The next 2 bits indicate repeat length
(0 = 3, ... , 3 = 6)
Example: Codes 8, 16 (+2 bits 11),
16 (+2 bits 10) will expand to
12 code lengths of 8 (1 + 6 + 5)
17: Repeat a code length of 0 for 3 - 10 times.
(3 bits of length)
18: Repeat a code length of 0 for 11 - 138 times
(7 bits of length)
A code length of 0 indicates that the corresponding symbol in
the literal/length or distance alphabet will not occur in the
block, and should not participate in the Huffman code
construction algorithm given earlier. If only one distance
code is used, it is encoded using one bit, not zero bits; in
this case there is a single code length of one, with one unused
code. One distance code of zero bits means that there are no
distance codes used at all (the data is all literals).
We can now define the format of the block:
5 Bits: HLIT, # of Literal/Length codes - 257 (257 - 286)
5 Bits: HDIST, # of Distance codes - 1 (1 - 32)
4 Bits: HCLEN, # of Code Length codes - 4 (4 - 19)
Deutsch Informational [Page 13]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
(HCLEN + 4) x 3 bits: code lengths for the code length
alphabet given just above, in the order: 16, 17, 18,
0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
These code lengths are interpreted as 3-bit integers
(0-7); as above, a code length of 0 means the
corresponding symbol (literal/length or distance code
length) is not used.
HLIT + 257 code lengths for the literal/length alphabet,
encoded using the code length Huffman code
HDIST + 1 code lengths for the distance alphabet,
encoded using the code length Huffman code
The actual compressed data of the block,
encoded using the literal/length and distance Huffman
codes
The literal/length symbol 256 (end of data),
encoded using the literal/length Huffman code
The code length repeat codes can cross from HLIT + 257 to the
HDIST + 1 code lengths. In other words, all code lengths form
a single sequence of HLIT + HDIST + 258 values.
3.3. Compliance
A compressor may limit further the ranges of values specified in
the previous section and still be compliant; for example, it may
limit the range of backward pointers to some value smaller than
32K. Similarly, a compressor may limit the size of blocks so that
a compressible block fits in memory.
A compliant decompressor must accept the full range of possible
values defined in the previous section, and must accept blocks of
arbitrary size.
4. Compression algorithm details
While it is the intent of this document to define the "deflate"
compressed data format without reference to any particular
compression algorithm, the format is related to the compressed
formats produced by LZ77 (Lempel-Ziv 1977, see reference [2] below);
since many variations of LZ77 are patented, it is strongly
recommended that the implementor of a compressor follow the general
algorithm presented here, which is known not to be patented per se.
The material in this section is not part of the definition of the
Deutsch Informational [Page 14]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
specification per se, and a compressor need not follow it in order to
be compliant.
The compressor terminates a block when it determines that starting a
new block with fresh trees would be useful, or when the block size
fills up the compressor's block buffer.
The compressor uses a chained hash table to find duplicated strings,
using a hash function that operates on 3-byte sequences. At any
given point during compression, let XYZ be the next 3 input bytes to
be examined (not necessarily all different, of course). First, the
compressor examines the hash chain for XYZ. If the chain is empty,
the compressor simply writes out X as a literal byte and advances one
byte in the input. If the hash chain is not empty, indicating that
the sequence XYZ (or, if we are unlucky, some other 3 bytes with the
same hash function value) has occurred recently, the compressor
compares all strings on the XYZ hash chain with the actual input data
sequence starting at the current point, and selects the longest
match.
The compressor searches the hash chains starting with the most recent
strings, to favor small distances and thus take advantage of the
Huffman encoding. The hash chains are singly linked. There are no
deletions from the hash chains; the algorithm simply discards matches
that are too old. To avoid a worst-case situation, very long hash
chains are arbitrarily truncated at a certain length, determined by a
run-time parameter.
To improve overall compression, the compressor optionally defers the
selection of matches ("lazy matching"): after a match of length N has
been found, the compressor searches for a longer match starting at
the next input byte. If it finds a longer match, it truncates the
previous match to a length of one (thus producing a single literal
byte) and then emits the longer match. Otherwise, it emits the
original match, and, as described above, advances N bytes before
continuing.
Run-time parameters also control this "lazy match" procedure. If
compression ratio is most important, the compressor attempts a
complete second search regardless of the length of the first match.
In the normal case, if the current match is "long enough", the
compressor reduces the search for a longer match, thus speeding up
the process. If speed is most important, the compressor inserts new
strings in the hash table only when no match was found, or when the
match is not "too long". This degrades the compression ratio but
saves time since there are both fewer insertions and fewer searches.
Deutsch Informational [Page 15]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
5. References
[1] Huffman, D. A., "A Method for the Construction of Minimum
Redundancy Codes", Proceedings of the Institute of Radio
Engineers, September 1952, Volume 40, Number 9, pp. 1098-1101.
[2] Ziv J., Lempel A., "A Universal Algorithm for Sequential Data
Compression", IEEE Transactions on Information Theory, Vol. 23,
No. 3, pp. 337-343.
[3] Gailly, J.-L., and Adler, M., ZLIB documentation and sources,
available in ftp://ftp.uu.net/pub/archiving/zip/doc/
[4] Gailly, J.-L., and Adler, M., GZIP documentation and sources,
available as gzip-*.tar in ftp://prep.ai.mit.edu/pub/gnu/
[5] Schwartz, E. S., and Kallick, B. "Generating a canonical prefix
encoding." Comm. ACM, 7,3 (Mar. 1964), pp. 166-169.
[6] Hirschberg and Lelewer, "Efficient decoding of prefix codes,"
Comm. ACM, 33,4, April 1990, pp. 449-459.
6. Security Considerations
Any data compression method involves the reduction of redundancy in
the data. Consequently, any corruption of the data is likely to have
severe effects and be difficult to correct. Uncompressed text, on
the other hand, will probably still be readable despite the presence
of some corrupted bytes.
It is recommended that systems using this data format provide some
means of validating the integrity of the compressed data. See
reference [3], for example.
7. Source code
Source code for a C language implementation of a "deflate" compliant
compressor and decompressor is available within the zlib package at
ftp://ftp.uu.net/pub/archiving/zip/zlib/.
8. Acknowledgements
Trademarks cited in this document are the property of their
respective owners.
Phil Katz designed the deflate format. Jean-Loup Gailly and Mark
Adler wrote the related software described in this specification.
Glenn Randers-Pehrson converted this document to RFC and HTML format.
Deutsch Informational [Page 16]
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
9. Author's Address
L. Peter Deutsch
Aladdin Enterprises
203 Santa Margarita Ave.
Menlo Park, CA 94025
Phone: (415) 322-0103 (AM only)
FAX: (415) 322-1734
EMail: <ghost@aladdin.com>
Questions about the technical content of this specification can be
sent by email to:
Jean-Loup Gailly <gzip@prep.ai.mit.edu> and
Mark Adler <madler@alumni.caltech.edu>
Editorial comments on this specification can be sent by email to:
L. Peter Deutsch <ghost@aladdin.com> and
Glenn Randers-Pehrson <randeg@alumni.rpi.edu>
Deutsch Informational [Page 17]

View File

@ -0,0 +1,675 @@
Network Working Group P. Deutsch
Request for Comments: 1952 Aladdin Enterprises
Category: Informational May 1996
GZIP file format specification version 4.3
Status of This Memo
This memo provides information for the Internet community. This memo
does not specify an Internet standard of any kind. Distribution of
this memo is unlimited.
IESG Note:
The IESG takes no position on the validity of any Intellectual
Property Rights statements contained in this document.
Notices
Copyright (c) 1996 L. Peter Deutsch
Permission is granted to copy and distribute this document for any
purpose and without charge, including translations into other
languages and incorporation into compilations, provided that the
copyright notice and this notice are preserved, and that any
substantive changes or deletions from the original are clearly
marked.
A pointer to the latest version of this and related documentation in
HTML format can be found at the URL
<ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
Abstract
This specification defines a lossless compressed data format that is
compatible with the widely used GZIP utility. The format includes a
cyclic redundancy check value for detecting data corruption. The
format presently uses the DEFLATE method of compression but can be
easily extended to use other compression methods. The format can be
implemented readily in a manner not covered by patents.
Deutsch Informational [Page 1]
RFC 1952 GZIP File Format Specification May 1996
Table of Contents
1. Introduction ................................................... 2
1.1. Purpose ................................................... 2
1.2. Intended audience ......................................... 3
1.3. Scope ..................................................... 3
1.4. Compliance ................................................ 3
1.5. Definitions of terms and conventions used ................. 3
1.6. Changes from previous versions ............................ 3
2. Detailed specification ......................................... 4
2.1. Overall conventions ....................................... 4
2.2. File format ............................................... 5
2.3. Member format ............................................. 5
2.3.1. Member header and trailer ........................... 6
2.3.1.1. Extra field ................................... 8
2.3.1.2. Compliance .................................... 9
3. References .................................................. 9
4. Security Considerations .................................... 10
5. Acknowledgements ........................................... 10
6. Author's Address ........................................... 10
7. Appendix: Jean-Loup Gailly's gzip utility .................. 11
8. Appendix: Sample CRC Code .................................. 11
1. Introduction
1.1. Purpose
The purpose of this specification is to define a lossless
compressed data format that:
* Is independent of CPU type, operating system, file system,
and character set, and hence can be used for interchange;
* Can compress or decompress a data stream (as opposed to a
randomly accessible file) to produce another data stream,
using only an a priori bounded amount of intermediate
storage, and hence can be used in data communications or
similar structures such as Unix filters;
* Compresses data with efficiency comparable to the best
currently available general-purpose compression methods,
and in particular considerably better than the "compress"
program;
* Can be implemented readily in a manner not covered by
patents, and hence can be practiced freely;
* Is compatible with the file format produced by the current
widely used gzip utility, in that conforming decompressors
will be able to read data produced by the existing gzip
compressor.
Deutsch Informational [Page 2]
RFC 1952 GZIP File Format Specification May 1996
The data format defined by this specification does not attempt to:
* Provide random access to compressed data;
* Compress specialized data (e.g., raster graphics) as well as
the best currently available specialized algorithms.
1.2. Intended audience
This specification is intended for use by implementors of software
to compress data into gzip format and/or decompress data from gzip
format.
The text of the specification assumes a basic background in
programming at the level of bits and other primitive data
representations.
1.3. Scope
The specification specifies a compression method and a file format
(the latter assuming only that a file can store a sequence of
arbitrary bytes). It does not specify any particular interface to
a file system or anything about character sets or encodings
(except for file names and comments, which are optional).
1.4. Compliance
Unless otherwise indicated below, a compliant decompressor must be
able to accept and decompress any file that conforms to all the
specifications presented here; a compliant compressor must produce
files that conform to all the specifications presented here. The
material in the appendices is not part of the specification per se
and is not relevant to compliance.
1.5. Definitions of terms and conventions used
byte: 8 bits stored or transmitted as a unit (same as an octet).
(For this specification, a byte is exactly 8 bits, even on
machines which store a character on a number of bits different
from 8.) See below for the numbering of bits within a byte.
1.6. Changes from previous versions
There have been no technical changes to the gzip format since
version 4.1 of this specification. In version 4.2, some
terminology was changed, and the sample CRC code was rewritten for
clarity and to eliminate the requirement for the caller to do pre-
and post-conditioning. Version 4.3 is a conversion of the
specification to RFC style.
Deutsch Informational [Page 3]
RFC 1952 GZIP File Format Specification May 1996
2. Detailed specification
2.1. Overall conventions
In the diagrams below, a box like this:
+---+
| | <-- the vertical bars might be missing
+---+
represents one byte; a box like this:
+==============+
| |
+==============+
represents a variable number of bytes.
Bytes stored within a computer do not have a "bit order", since
they are always treated as a unit. However, a byte considered as
an integer between 0 and 255 does have a most- and least-
significant bit, and since we write numbers with the most-
significant digit on the left, we also write bytes with the most-
significant bit on the left. In the diagrams below, we number the
bits of a byte so that bit 0 is the least-significant bit, i.e.,
the bits are numbered:
+--------+
|76543210|
+--------+
This document does not address the issue of the order in which
bits of a byte are transmitted on a bit-sequential medium, since
the data format described here is byte- rather than bit-oriented.
Within a computer, a number may occupy multiple bytes. All
multi-byte numbers in the format described here are stored with
the least-significant byte first (at the lower memory address).
For example, the decimal number 520 is stored as:
0 1
+--------+--------+
|00001000|00000010|
+--------+--------+
^ ^
| |
| + more significant byte = 2 x 256
+ less significant byte = 8
Deutsch Informational [Page 4]
RFC 1952 GZIP File Format Specification May 1996
2.2. File format
A gzip file consists of a series of "members" (compressed data
sets). The format of each member is specified in the following
section. The members simply appear one after another in the file,
with no additional information before, between, or after them.
2.3. Member format
Each member has the following structure:
+---+---+---+---+---+---+---+---+---+---+
|ID1|ID2|CM |FLG| MTIME |XFL|OS | (more-->)
+---+---+---+---+---+---+---+---+---+---+
(if FLG.FEXTRA set)
+---+---+=================================+
| XLEN |...XLEN bytes of "extra field"...| (more-->)
+---+---+=================================+
(if FLG.FNAME set)
+=========================================+
|...original file name, zero-terminated...| (more-->)
+=========================================+
(if FLG.FCOMMENT set)
+===================================+
|...file comment, zero-terminated...| (more-->)
+===================================+
(if FLG.FHCRC set)
+---+---+
| CRC16 |
+---+---+
+=======================+
|...compressed blocks...| (more-->)
+=======================+
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| CRC32 | ISIZE |
+---+---+---+---+---+---+---+---+
Deutsch Informational [Page 5]
RFC 1952 GZIP File Format Specification May 1996
2.3.1. Member header and trailer
ID1 (IDentification 1)
ID2 (IDentification 2)
These have the fixed values ID1 = 31 (0x1f, \037), ID2 = 139
(0x8b, \213), to identify the file as being in gzip format.
CM (Compression Method)
This identifies the compression method used in the file. CM
= 0-7 are reserved. CM = 8 denotes the "deflate"
compression method, which is the one customarily used by
gzip and which is documented elsewhere.
FLG (FLaGs)
This flag byte is divided into individual bits as follows:
bit 0 FTEXT
bit 1 FHCRC
bit 2 FEXTRA
bit 3 FNAME
bit 4 FCOMMENT
bit 5 reserved
bit 6 reserved
bit 7 reserved
If FTEXT is set, the file is probably ASCII text. This is
an optional indication, which the compressor may set by
checking a small amount of the input data to see whether any
non-ASCII characters are present. In case of doubt, FTEXT
is cleared, indicating binary data. For systems which have
different file formats for ascii text and binary data, the
decompressor can use FTEXT to choose the appropriate format.
We deliberately do not specify the algorithm used to set
this bit, since a compressor always has the option of
leaving it cleared and a decompressor always has the option
of ignoring it and letting some other program handle issues
of data conversion.
If FHCRC is set, a CRC16 for the gzip header is present,
immediately before the compressed data. The CRC16 consists
of the two least significant bytes of the CRC32 for all
bytes of the gzip header up to and not including the CRC16.
[The FHCRC bit was never set by versions of gzip up to
1.2.4, even though it was documented with a different
meaning in gzip 1.2.4.]
If FEXTRA is set, optional extra fields are present, as
described in a following section.
Deutsch Informational [Page 6]
RFC 1952 GZIP File Format Specification May 1996
If FNAME is set, an original file name is present,
terminated by a zero byte. The name must consist of ISO
8859-1 (LATIN-1) characters; on operating systems using
EBCDIC or any other character set for file names, the name
must be translated to the ISO LATIN-1 character set. This
is the original name of the file being compressed, with any
directory components removed, and, if the file being
compressed is on a file system with case insensitive names,
forced to lower case. There is no original file name if the
data was compressed from a source other than a named file;
for example, if the source was stdin on a Unix system, there
is no file name.
If FCOMMENT is set, a zero-terminated file comment is
present. This comment is not interpreted; it is only
intended for human consumption. The comment must consist of
ISO 8859-1 (LATIN-1) characters. Line breaks should be
denoted by a single line feed character (10 decimal).
Reserved FLG bits must be zero.
MTIME (Modification TIME)
This gives the most recent modification time of the original
file being compressed. The time is in Unix format, i.e.,
seconds since 00:00:00 GMT, Jan. 1, 1970. (Note that this
may cause problems for MS-DOS and other systems that use
local rather than Universal time.) If the compressed data
did not come from a file, MTIME is set to the time at which
compression started. MTIME = 0 means no time stamp is
available.
XFL (eXtra FLags)
These flags are available for use by specific compression
methods. The "deflate" method (CM = 8) sets these flags as
follows:
XFL = 2 - compressor used maximum compression,
slowest algorithm
XFL = 4 - compressor used fastest algorithm
OS (Operating System)
This identifies the type of file system on which compression
took place. This may be useful in determining end-of-line
convention for text files. The currently defined values are
as follows:
Deutsch Informational [Page 7]
RFC 1952 GZIP File Format Specification May 1996
0 - FAT filesystem (MS-DOS, OS/2, NT/Win32)
1 - Amiga
2 - VMS (or OpenVMS)
3 - Unix
4 - VM/CMS
5 - Atari TOS
6 - HPFS filesystem (OS/2, NT)
7 - Macintosh
8 - Z-System
9 - CP/M
10 - TOPS-20
11 - NTFS filesystem (NT)
12 - QDOS
13 - Acorn RISCOS
255 - unknown
XLEN (eXtra LENgth)
If FLG.FEXTRA is set, this gives the length of the optional
extra field. See below for details.
CRC32 (CRC-32)
This contains a Cyclic Redundancy Check value of the
uncompressed data computed according to CRC-32 algorithm
used in the ISO 3309 standard and in section 8.1.1.6.2 of
ITU-T recommendation V.42. (See http://www.iso.ch for
ordering ISO documents. See gopher://info.itu.ch for an
online version of ITU-T V.42.)
ISIZE (Input SIZE)
This contains the size of the original (uncompressed) input
data modulo 2^32.
2.3.1.1. Extra field
If the FLG.FEXTRA bit is set, an "extra field" is present in
the header, with total length XLEN bytes. It consists of a
series of subfields, each of the form:
+---+---+---+---+==================================+
|SI1|SI2| LEN |... LEN bytes of subfield data ...|
+---+---+---+---+==================================+
SI1 and SI2 provide a subfield ID, typically two ASCII letters
with some mnemonic value. Jean-Loup Gailly
<gzip@prep.ai.mit.edu> is maintaining a registry of subfield
IDs; please send him any subfield ID you wish to use. Subfield
IDs with SI2 = 0 are reserved for future use. The following
IDs are currently defined:
Deutsch Informational [Page 8]
RFC 1952 GZIP File Format Specification May 1996
SI1 SI2 Data
---------- ---------- ----
0x41 ('A') 0x70 ('P') Apollo file type information
LEN gives the length of the subfield data, excluding the 4
initial bytes.
2.3.1.2. Compliance
A compliant compressor must produce files with correct ID1,
ID2, CM, CRC32, and ISIZE, but may set all the other fields in
the fixed-length part of the header to default values (255 for
OS, 0 for all others). The compressor must set all reserved
bits to zero.
A compliant decompressor must check ID1, ID2, and CM, and
provide an error indication if any of these have incorrect
values. It must examine FEXTRA/XLEN, FNAME, FCOMMENT and FHCRC
at least so it can skip over the optional fields if they are
present. It need not examine any other part of the header or
trailer; in particular, a decompressor may ignore FTEXT and OS
and always produce binary output, and still be compliant. A
compliant decompressor must give an error indication if any
reserved bit is non-zero, since such a bit could indicate the
presence of a new field that would cause subsequent data to be
interpreted incorrectly.
3. References
[1] "Information Processing - 8-bit single-byte coded graphic
character sets - Part 1: Latin alphabet No.1" (ISO 8859-1:1987).
The ISO 8859-1 (Latin-1) character set is a superset of 7-bit
ASCII. Files defining this character set are available as
iso_8859-1.* in ftp://ftp.uu.net/graphics/png/documents/
[2] ISO 3309
[3] ITU-T recommendation V.42
[4] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification",
available in ftp://ftp.uu.net/pub/archiving/zip/doc/
[5] Gailly, J.-L., GZIP documentation, available as gzip-*.tar in
ftp://prep.ai.mit.edu/pub/gnu/
[6] Sarwate, D.V., "Computation of Cyclic Redundancy Checks via Table
Look-Up", Communications of the ACM, 31(8), pp.1008-1013.
Deutsch Informational [Page 9]
RFC 1952 GZIP File Format Specification May 1996
[7] Schwaderer, W.D., "CRC Calculation", April 85 PC Tech Journal,
pp.118-133.
[8] ftp://ftp.adelaide.edu.au/pub/rocksoft/papers/crc_v3.txt,
describing the CRC concept.
4. Security Considerations
Any data compression method involves the reduction of redundancy in
the data. Consequently, any corruption of the data is likely to have
severe effects and be difficult to correct. Uncompressed text, on
the other hand, will probably still be readable despite the presence
of some corrupted bytes.
It is recommended that systems using this data format provide some
means of validating the integrity of the compressed data, such as by
setting and checking the CRC-32 check value.
5. Acknowledgements
Trademarks cited in this document are the property of their
respective owners.
Jean-Loup Gailly designed the gzip format and wrote, with Mark Adler,
the related software described in this specification. Glenn
Randers-Pehrson converted this document to RFC and HTML format.
6. Author's Address
L. Peter Deutsch
Aladdin Enterprises
203 Santa Margarita Ave.
Menlo Park, CA 94025
Phone: (415) 322-0103 (AM only)
FAX: (415) 322-1734
EMail: <ghost@aladdin.com>
Questions about the technical content of this specification can be
sent by email to:
Jean-Loup Gailly <gzip@prep.ai.mit.edu> and
Mark Adler <madler@alumni.caltech.edu>
Editorial comments on this specification can be sent by email to:
L. Peter Deutsch <ghost@aladdin.com> and
Glenn Randers-Pehrson <randeg@alumni.rpi.edu>
Deutsch Informational [Page 10]
RFC 1952 GZIP File Format Specification May 1996
7. Appendix: Jean-Loup Gailly's gzip utility
The most widely used implementation of gzip compression, and the
original documentation on which this specfication is based, were
created by Jean-Loup Gailly <gzip@prep.ai.mit.edu>. Since this
implementation is a de facto standard, we mention some more of its
features here. Again, the material in this section is not part of
the specification per se, and implementations need not follow it to
be compliant.
When compressing or decompressing a file, gzip preserves the
protection, ownership, and modification time attributes on the local
file system, since there is no provision for representing protection
attributes in the gzip file format itself. Since the file format
includes a modification time, the gzip decompressor provides a
command line switch that assigns the modification time from the file,
rather than the local modification time of the compressed input, to
the decompressed output.
8. Appendix: Sample CRC Code
The following sample code represents a practical implementation of
the CRC (Cyclic Redundancy Check). (See also ISO 3309 and ITU-T V.42
for a formal specification.)
The sample code is in the ANSI C programming language. Non C users
may find it easier to read with these hints:
& Bitwise AND operator.
^ Bitwise exclusive-OR operator.
>> Bitwise right shift operator. When applied to an
unsigned quantity, as here, right shift inserts zero
bit(s) at the left.
! Logical NOT operator.
++ "n++" increments the variable n.
0xNNN 0x introduces a hexadecimal (base 16) constant.
Suffix L indicates a long value (at least 32 bits).
/* Table of CRCs of all 8-bit messages. */
unsigned long crc_table[256];
/* Flag: has the table been computed? Initially false. */
int crc_table_computed = 0;
/* Make the table for a fast CRC. */
void make_crc_table(void)
{
unsigned long c;
Deutsch Informational [Page 11]
RFC 1952 GZIP File Format Specification May 1996
int n, k;
for (n = 0; n < 256; n++) {
c = (unsigned long) n;
for (k = 0; k < 8; k++) {
if (c & 1) {
c = 0xedb88320L ^ (c >> 1);
} else {
c = c >> 1;
}
}
crc_table[n] = c;
}
crc_table_computed = 1;
}
/*
Update a running crc with the bytes buf[0..len-1] and return
the updated crc. The crc should be initialized to zero. Pre- and
post-conditioning (one's complement) is performed within this
function so it shouldn't be done by the caller. Usage example:
unsigned long crc = 0L;
while (read_buffer(buffer, length) != EOF) {
crc = update_crc(crc, buffer, length);
}
if (crc != original_crc) error();
*/
unsigned long update_crc(unsigned long crc,
unsigned char *buf, int len)
{
unsigned long c = crc ^ 0xffffffffL;
int n;
if (!crc_table_computed)
make_crc_table();
for (n = 0; n < len; n++) {
c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
}
return c ^ 0xffffffffL;
}
/* Return the CRC of the bytes buf[0..len-1]. */
unsigned long crc(unsigned char *buf, int len)
{
return update_crc(0L, buf, len);
}
Deutsch Informational [Page 12]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,447 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : FWZipConsts
// * Purpose : Типы и константы используемые для работы с ZIP архивами
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2015.
// * Version : 1.0.11
// * Home Page : http://rouse.drkb.ru
// * Home Blog : http://alexander-bagel.blogspot.ru
// ****************************************************************************
// * Stable Release : http://rouse.drkb.ru/components.php#fwzip
// * Latest Source : https://github.com/AlexanderBagel/FWZip
// ****************************************************************************
//
// Используемые источники:
// ftp://ftp.info-zip.org/pub/infozip/doc/appnote-iz-latest.zip
// http://zlib.net/zlib-1.2.5.tar.gz
// http://www.base2ti.com/
//
unit FWZipConsts;
{$mode delphi}
{$codepage UTF8}
interface
uses
LCLIntf, LCLType, LMessages, windows,
SysUtils,
Classes, FileUtil, LazFileUtils;
type
{
IV. General Format of a .ZIP file
---------------------------------
Files stored in arbitrary order. Large .ZIP files can span multiple
diskette media or be split into user-defined segment sizes. [The
minimum user-defined segment size for a split .ZIP file is 64K.
(removed by PKWare 2003-06-01)]
Overall .ZIP file format:
[local file header 1]
[file data 1]
[data descriptor 1]
.
.
.
[local file header n]
[file data n]
[data descriptor n]
[archive decryption header] (EFS)
[archive extra data record] (EFS)
[central directory]
[zip64 end of central directory record]
[zip64 end of central directory locator]
[end of central directory record]
}
PLocalFileHeader = ^TLocalFileHeader;
TLocalFileHeader = packed record
LocalFileHeaderSignature: Cardinal; // (0x04034b50)
VersionNeededToExtract,
GeneralPurposeBitFlag,
CompressionMethod,
LastModFileTimeTime,
LastModFileTimeDate: Word;
Crc32,
CompressedSize,
UncompressedSize: Cardinal;
FilenameLength,
ExtraFieldLength: Word;
// file name (variable size)
// extra field (variable size)
end;
{
If bit 3 of the general purpose bit flag
is set, these fields are set to zero in the local header
and the correct values are put in the data descriptor and
in the central directory.
}
TDataDescriptor = packed record
DescriptorSignature, // (0x08074b50)
Crc32,
CompressedSize,
UncompressedSize: Cardinal;
{For Zip64 format archives, the compressed
and uncompressed sizes are 8 bytes each. ??!!}
end;
TEFS = packed record
ArchiveExtraDataSignature, // (0x08064b50)
ExtraFieldLength: Cardinal;
// extra field data (variable size)
end;
{
F. Central directory structure:
[file header 1]
.
.
.
[file header n]
[digital signature]
}
TCentralDirectoryFileHeader = packed record
CentralFileHeaderSignature: Cardinal; // (0x02014b50)
VersionMadeBy,
VersionNeededToExtract,
GeneralPurposeBitFlag,
CompressionMethod,
LastModFileTimeTime,
LastModFileTimeDate: Word;
Crc32,
CompressedSize,
UncompressedSize: Cardinal;
FilenameLength,
ExtraFieldLength,
FileCommentLength,
DiskNumberStart,
InternalFileAttributes: Word;
ExternalFileAttributes,
RelativeOffsetOfLocalHeader: Cardinal;
// file name (variable size)
// extra field (variable size)
// file comment (variable size)
end;
TCentralDirectoryFileHeaderEx = packed record
Header: TCentralDirectoryFileHeader;
UncompressedSize,
CompressedSize,
RelativeOffsetOfLocalHeader,
DataOffset: Int64;
DiskNumberStart: Integer;
FileName,
FileComment: string;
Attributes: TWin32FileAttributeData;
ExceptOnWrite: Boolean;
end;
TNTFSFileTime = packed record
Mtime: TFileTime;
Atime: TFileTime;
Ctime: TFileTime;
end;
TExDataHeaderAndSize = packed record
Header: Word;
Size: Word;
end;
TExDataNTFS = packed record
HS: TExDataHeaderAndSize;
Reserved: Cardinal;
Tag: Word;
RecordSize: Word;
Data: TNTFSFileTime;
end;
TExDataInfo64 = packed record
HS: TExDataHeaderAndSize;
UncompressedSize, CompressedSize: Int64;
end;
TCentralDirectoryDigitalSignature = packed record
HeaderSignature: Cardinal; // (0x05054b50)
SizeOfData: Word;
// signature data (variable size)
end;
TZip64EOFCentralDirectoryRecord = packed record
Zip64EndOfCentralDirSignature: Cardinal; // (0x06064b50)
SizeOfZip64EOFCentralDirectoryRecord: int64;
VersionMadeBy,
VersionNeededToExtract: Word;
Number1, // number of this disk
Number2: Cardinal; // number of the disk with the start of the central directory
TotalNumber1, // total number of entries in the central directory on this disk
TotalNumber2, // total number of entries in the central directory
Size, // size of the central directory
Offset: Int64; // offset of start of central directory with respect to the starting disk number
// zip64 extensible data sector (variable size)
end;
TZip64EOFCentralDirectoryLocator = packed record
Signature, // zip64 end of central dir locator signature (0x07064b50)
NumberOfTheDisk: Cardinal; // number of the disk with the start of the zip64 end of central directory
RelativeOffset: Int64; // relative offset of the zip64 end of central directory record
TotalNumberOfDisks: Cardinal;
end;
TEndOfCentralDir = packed record
EndOfCentralDirSignature: Cardinal; // (0x06054b50)
NumberOfThisDisk,
NumberOfTheDiskWithTheStart,
TotalNumberOfEntriesOnThisDisk,
TotalNumberOfEntries: Word;
SizeOfTheCentralDirectory,
OffsetOfStartOfCentralDirectory: Cardinal;
ZipfileCommentLength: Word;
// .ZIP file comment (variable size)
end;
const
LOCAL_FILE_HEADER_SIGNATURE = $04034B50;
DATA_DESCRIPTOR_SIGNATURE = $08074B50;
EXTRA_DATA_SIGNATURE = $08064B50;
CENTRAL_FILE_HEADER_SIGNATURE = $02014B50;
CENTRAL_DIRECTORY_DIGITAL_SIGNATURE = $05054B50;
ZIP64_END_OF_CENTRAL_DIR_SIGNATURE = $06064B50;
ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE = $07064B50;
END_OF_CENTRAL_DIR_SIGNATURE = $06054B50;
ZIP_SLASH = '/';
// Флаги для GeneralPurposeBitFlag
PBF_CRYPTED = 1;
// (For Methods 8 and 9 - Deflating)
PBF_COMPRESS_NORMAL = 0;
PBF_COMPRESS_MAXIMUM = 2;
PBF_COMPRESS_FAST = 4;
PBF_COMPRESS_SUPERFAST = 6;
PBF_DESCRIPTOR = 8;
PBF_STRONG_CRYPT = 64;
PBF_UTF8 = $800;
// константы поддерживаемых полей ExData
SUPPORTED_EXDATA_ZIP64 = 1;
SUPPORTED_EXDATA_NTFSTIME = 10;
defaultWindowBits = -15;
type
TProgressState = (
psStart, // начало распаковки элемента, результирующий файл еще не создан
psInitialization, // результирующий файл создан и залочен, производится подготовка к распаковке
psInProgress, // идет распаковка
psFinalization, // распаковка завершена, сейчас будут разрушены все служебные объекты, результирующий файл все еще залочен
psEnd, // операция распаковки полностью завершена, результирующий файл доступен на чтение/запись
psException // ошибка
);
TZipProgressEvent = procedure(Sender: TObject; const FileName: string;
Percent, TotalPercent: Byte; var Cancel: Boolean; ProgressState: TProgressState) of object;
TZipExtractItemEvent = procedure(Sender: TObject; const FileName: string;
Extracted, TotalSize: Int64; ProgressState: TProgressState) of object;
TZipNeedPasswordEvent = procedure(Sender: TObject; const FileName: string;
var Password: string; var CancelExtract: Boolean) of object;
TZipSaveExDataEvent = procedure(Sender: TObject; ItemIndex: Integer;
UserExDataBlockCount: Integer; var Tag: Word; Data: TStream) of object;
TZipLoadExDataEvent = procedure(Sender: TObject; ItemIndex: Integer;
Tag: Word; Data: TStream) of object;
// Типы поведения TFWZipWriter при ошибке в процессе создания архива
TExceptionAction =
(
eaRetry, // повторить попытку
eaSkip, // пропустить текущий элемент
eaAbort, // остановить создание архива
eaUseNewFilePath, // использовать новый путь к файлу (пар. NewFilePath)
eaUseNewFilePathAndDel, // то-же что и acUseNewFilePath, только файл удаляется после использования
eaUseNewFileData // использовать содержимое файла из стрима (пар. NewFileData)
);
TZipBuildExceptionEvent = procedure(Sender: TObject;
E: Exception; const ItemIndex: Integer;
var Action: TExceptionAction;
var NewFilePath: string; NewFileData: TMemoryStream) of object;
TZipExtractExceptionEvent = procedure(Sender: TObject;
E: Exception; const ItemIndex: Integer;
var Handled: Boolean) of object;
// Типы поведения TFWZipReader при конфликте имен файлов
TDuplicateAction =
(
daSkip, // пропустить файл
daOverwrite, // перезаписать
daUseNewFilePath, // сохранить с новым именем
daAbort // отменить распаковку
);
TZipDuplicateEvent = procedure(Sender: TObject;
var Path: string; var Action: TDuplicateAction) of object;
const
CRC32Table: array[Byte] of Cardinal =
(
$00000000, $77073096, $EE0E612C, $990951BA, $076DC419, $706AF48F,
$E963A535, $9E6495A3, $0EDB8832, $79DCB8A4, $E0D5E91E, $97D2D988,
$09B64C2B, $7EB17CBD, $E7B82D07, $90BF1D91, $1DB71064, $6AB020F2,
$F3B97148, $84BE41DE, $1ADAD47D, $6DDDE4EB, $F4D4B551, $83D385C7,
$136C9856, $646BA8C0, $FD62F97A, $8A65C9EC, $14015C4F, $63066CD9,
$FA0F3D63, $8D080DF5, $3B6E20C8, $4C69105E, $D56041E4, $A2677172,
$3C03E4D1, $4B04D447, $D20D85FD, $A50AB56B, $35B5A8FA, $42B2986C,
$DBBBC9D6, $ACBCF940, $32D86CE3, $45DF5C75, $DCD60DCF, $ABD13D59,
$26D930AC, $51DE003A, $C8D75180, $BFD06116, $21B4F4B5, $56B3C423,
$CFBA9599, $B8BDA50F, $2802B89E, $5F058808, $C60CD9B2, $B10BE924,
$2F6F7C87, $58684C11, $C1611DAB, $B6662D3D, $76DC4190, $01DB7106,
$98D220BC, $EFD5102A, $71B18589, $06B6B51F, $9FBFE4A5, $E8B8D433,
$7807C9A2, $0F00F934, $9609A88E, $E10E9818, $7F6A0DBB, $086D3D2D,
$91646C97, $E6635C01, $6B6B51F4, $1C6C6162, $856530D8, $F262004E,
$6C0695ED, $1B01A57B, $8208F4C1, $F50FC457, $65B0D9C6, $12B7E950,
$8BBEB8EA, $FCB9887C, $62DD1DDF, $15DA2D49, $8CD37CF3, $FBD44C65,
$4DB26158, $3AB551CE, $A3BC0074, $D4BB30E2, $4ADFA541, $3DD895D7,
$A4D1C46D, $D3D6F4FB, $4369E96A, $346ED9FC, $AD678846, $DA60B8D0,
$44042D73, $33031DE5, $AA0A4C5F, $DD0D7CC9, $5005713C, $270241AA,
$BE0B1010, $C90C2086, $5768B525, $206F85B3, $B966D409, $CE61E49F,
$5EDEF90E, $29D9C998, $B0D09822, $C7D7A8B4, $59B33D17, $2EB40D81,
$B7BD5C3B, $C0BA6CAD, $EDB88320, $9ABFB3B6, $03B6E20C, $74B1D29A,
$EAD54739, $9DD277AF, $04DB2615, $73DC1683, $E3630B12, $94643B84,
$0D6D6A3E, $7A6A5AA8, $E40ECF0B, $9309FF9D, $0A00AE27, $7D079EB1,
$F00F9344, $8708A3D2, $1E01F268, $6906C2FE, $F762575D, $806567CB,
$196C3671, $6E6B06E7, $FED41B76, $89D32BE0, $10DA7A5A, $67DD4ACC,
$F9B9DF6F, $8EBEEFF9, $17B7BE43, $60B08ED5, $D6D6A3E8, $A1D1937E,
$38D8C2C4, $4FDFF252, $D1BB67F1, $A6BC5767, $3FB506DD, $48B2364B,
$D80D2BDA, $AF0A1B4C, $36034AF6, $41047A60, $DF60EFC3, $A867DF55,
$316E8EEF, $4669BE79, $CB61B38C, $BC66831A, $256FD2A0, $5268E236,
$CC0C7795, $BB0B4703, $220216B9, $5505262F, $C5BA3BBE, $B2BD0B28,
$2BB45A92, $5CB36A04, $C2D7FFA7, $B5D0CF31, $2CD99E8B, $5BDEAE1D,
$9B64C2B0, $EC63F226, $756AA39C, $026D930A, $9C0906A9, $EB0E363F,
$72076785, $05005713, $95BF4A82, $E2B87A14, $7BB12BAE, $0CB61B38,
$92D28E9B, $E5D5BE0D, $7CDCEFB7, $0BDBDF21, $86D3D2D4, $F1D4E242,
$68DDB3F8, $1FDA836E, $81BE16CD, $F6B9265B, $6FB077E1, $18B74777,
$88085AE6, $FF0F6A70, $66063BCA, $11010B5C, $8F659EFF, $F862AE69,
$616BFFD3, $166CCF45, $A00AE278, $D70DD2EE, $4E048354, $3903B3C2,
$A7672661, $D06016F7, $4969474D, $3E6E77DB, $AED16A4A, $D9D65ADC,
$40DF0B66, $37D83BF0, $A9BCAE53, $DEBB9EC5, $47B2CF7F, $30B5FFE9,
$BDBDF21C, $CABAC28A, $53B39330, $24B4A3A6, $BAD03605, $CDD70693,
$54DE5729, $23D967BF,$B3667A2E, $C4614AB8, $5D681B02, $2A6F2B94,
$B40BBE37, $C30C8EA1, $5A05DF1B, $2D02EF8D
);
CurrentVersionMadeBy = 63;
function IsAttributesPresent(Value: TWin32FileAttributeData): Boolean;
function FileSizeToInt64(FileSizeLo, FileSizeHi: DWORD): Int64;
function PathCanonicalize(Value: string): string;
function MakeUniqueName(const Value: string): string;
function FileSizeToStr(Value: Int64): string;
implementation
function PathCanonicalizeA(lpszDes, lpszSrc: PAnsiChar): BOOL; stdcall; external 'shlwapi.dll';
function PathCanonicalizeW(lpszDes, lpszSrc: PWideChar): BOOL; stdcall; external 'shlwapi.dll';
function PathMakeUniqueName(pszUniqueName: PWideChar; cchMax: UINT;
pszTemplate, pszLongPlate, pszDir: PWideChar): BOOL; stdcall; external 'shell32.dll';
function IsAttributesPresent(Value: TWin32FileAttributeData): Boolean;
begin
Result := (Value.ftCreationTime.dwLowDateTime <> 0) and
(Value.ftCreationTime.dwHighDateTime <> 0);
end;
function FileSizeToInt64(FileSizeLo, FileSizeHi: DWORD): Int64;
begin
Result := FileSizeHi;
Result := Result shl 32;
Inc(Result, FileSizeLo);
end;
function PathCanonicalize(Value: string): string;
begin
if Value = '' then
begin
Result := '';
Exit;
end;
if Value[1] = '.' then
Value := IncludeTrailingPathDelimiter(GetCurrentDirUTF8 { *Преобразовано из GetCurrentDir* }) + Value;
SetLength(Result, MAX_PATH);
{$IFDEF UNICODE}
PathCanonicalizeW(PWideChar(Result), PWideChar(Value));
{$ELSE}
PathCanonicalizeA(PAnsiChar(Result), PAnsiChar(Value));
{$ENDIF}
Result := PChar(Result);
end;
function MakeUniqueName(const Value: string): string;
{$IFDEF UNICODE}
var
FilePath, FileName: string;
begin
Result := Value;
FilePath := ExtractFilePath(Value);
FileName := ExtractFileName(Value);
SetLength(Result, MAX_PATH);
if PathMakeUniqueName(PWideChar(Result), MAX_PATH,
nil, PWideChar(FileName), PWideChar(FilePath)) then
Result := PWideChar(Result);
{$ELSE}
var
UnicodeResult, FilePath, FileName: WideString;
begin
Result := Value;
FilePath := WideString(ExtractFilePath(Value));
FileName := WideString(ExtractFileName(Value));
SetLength(UnicodeResult, MAX_PATH);
if PathMakeUniqueName(PWideChar(UnicodeResult), MAX_PATH,
nil, PWideChar(FileName), PWideChar(FilePath)) then
Result := AnsiString(PWideChar(UnicodeResult));
{$ENDIF}
end;
function FileSizeToStr(Value: Int64): string;
begin
if Value < 1024 then
begin
Result := Format('%d байт', [Value]);
Exit;
end;
Value := Value div 1024;
if Value < 1024 then
begin
Result := Format('%d килобайт', [Value]);
Exit;
end;
Value := Value div 1024;
if Value < 1024 then
begin
Result := Format('%d мегабайт', [Value]);
Exit;
end;
Value := Value div 1024;
if Value < 1024 then
begin
Result := Format('%d гигабайт', [Value]);
Exit;
end;
// ну а чем бог не шутит? :)
Value := Value div 1024;
Result := Format('%d терабайт', [Value]);
end;
end.

147
prereq/fwzip/FWZipCrc32.pas Normal file
View File

@ -0,0 +1,147 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : FWZipCrc32
// * Purpose : Набор функций для рассчета контрольной суммы блока данных
// * : Класс TFWZipCRC32Stream используется в качестве посредника
// * : между двумя стримами и предназначен для бастрого
// * : рассчета контрольной суммы передаваемых блоков данных
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2015.
// * Version : 1.0.11
// * Home Page : http://rouse.drkb.ru
// * Home Blog : http://alexander-bagel.blogspot.ru
// ****************************************************************************
// * Stable Release : http://rouse.drkb.ru/components.php#fwzip
// * Latest Source : https://github.com/AlexanderBagel/FWZip
// ****************************************************************************
//
// Используемые источники:
// ftp://ftp.info-zip.org/pub/infozip/doc/appnote-iz-latest.zip
// http://zlib.net/zlib-1.2.5.tar.gz
// http://www.base2ti.com/
//
unit FWZipCrc32;
{$mode delphi}
{$codepage UTF8}
interface
uses
Classes,
SysUtils,
FWZipConsts;
type
TFWZipCRC32Stream = class(TStream)
private
FOwner: TStream;
FCRC32: Cardinal;
protected
function GetSize: Int64; override;
public
constructor Create(AOwner: TStream);
function Seek(Offset: Longint; Origin: Word): Longint; overload; override;
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; overload; override;
function Read(var Buffer; Count: Longint): Longint; override;
function Write(const Buffer; Count: Longint): Longint; override;
function CRC32: Cardinal;
end;
function CRC32Calc(CurrCRC: Cardinal;
Buffer: PByte; const BufferLen: Int64): Cardinal; overload;
function CRC32Calc(Buffer: PByte; const BufferLen: Int64): Cardinal; overload;
function FileCRC32(const FileName: string): Cardinal;
implementation
function CRC32Calc(CurrCRC: Cardinal;
Buffer: PByte; const BufferLen: Int64): Cardinal;
var
I: Integer;
begin
Result := CurrCRC;
for I := 0 to BufferLen - 1 do
begin
Result := ((Result shr 8) and $00FFFFFF) xor
CRC32Table[(Result xor Buffer^) and $FF];
Inc(Buffer);
end;
end;
function CRC32Calc(Buffer: PByte; const BufferLen: Int64): Cardinal;
begin
Result := CRC32Calc($FFFFFFFF, Buffer, BufferLen) xor $FFFFFFFF;
end;
function FileCRC32(const FileName: string): Cardinal;
var
Buff: Pointer;
F: TFileStream;
Size: Integer;
begin
Result := $FFFFFFFF;
GetMem(Buff, $FFFF);
try
F := TFileStream.Create(FileName, fmOpenRead);
try
Size := 1;
while Size > 0 do
begin
Size := F.Read(Buff^, $FFFF);
Result := CRC32Calc(Result, Buff, Size);
end;
finally
F.Free;
end;
finally
FreeMem(Buff);
end;
Result := Result xor $FFFFFFFF;
end;
{ TFWZipCRC32Stream }
function TFWZipCRC32Stream.CRC32: Cardinal;
begin
Result := FCRC32 xor $FFFFFFFF;
end;
constructor TFWZipCRC32Stream.Create(AOwner: TStream);
begin
FOwner := AOwner;
FCRC32 := $FFFFFFFF;
end;
function TFWZipCRC32Stream.GetSize: Int64;
begin
Result := FOwner.Size;
end;
function TFWZipCRC32Stream.Read(var Buffer; Count: Integer): Longint;
begin
Result := FOwner.Read(Buffer, Count);
FCRC32 := CRC32Calc(FCRC32, @Buffer, Result);
end;
function TFWZipCRC32Stream.Seek(Offset: Integer; Origin: Word): Longint;
begin
Result := FOwner.Seek(Offset, Origin);
end;
function TFWZipCRC32Stream.Seek(const Offset: Int64;
Origin: TSeekOrigin): Int64;
begin
Result := FOwner.Seek(Offset, Origin);
end;
function TFWZipCRC32Stream.Write(const Buffer; Count: Integer): Longint;
begin
Result := FOwner.Write(Buffer, Count);
FCRC32 := CRC32Calc(FCRC32, @Buffer, Result);
end;
end.

361
prereq/fwzip/FWZipCrypt.pas Normal file
View File

@ -0,0 +1,361 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : FWZipCrypt
// * Purpose : Реализация криптографии по методу PKWARE
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2015.
// * Version : 1.0.11
// * Home Page : http://rouse.drkb.ru
// * Home Blog : http://alexander-bagel.blogspot.ru
// ****************************************************************************
// * Stable Release : http://rouse.drkb.ru/components.php#fwzip
// * Latest Source : https://github.com/AlexanderBagel/FWZip
// ****************************************************************************
//
// Используемые источники:
// ftp://ftp.info-zip.org/pub/infozip/doc/appnote-iz-latest.zip
// http://zlib.net/zlib-1.2.5.tar.gz
// http://www.base2ti.com/
//
unit FWZipCrypt;
{$mode delphi}
{$codepage UTF8}
interface
// Переполнения и выход за диапазон неизбежны
// поэтому отключаем данные проверки
{$OVERFLOWCHECKS OFF}
{$RANGECHECKS OFF}
uses
LCLIntf, LCLType, LMessages, windows,
Classes,
FWZipConsts;
{
XIII. Decryption
----------------
The encryption used in PKZIP was generously supplied by Roger
Schlafly. PKWARE is grateful to Mr. Schlafly for his expert
help and advice in the field of data encryption.
PKZIP encrypts the compressed data stream. Encrypted files must
be decrypted before they can be extracted.
Each encrypted file has an extra 12 bytes stored at the start of
the data area defining the encryption header for that file. The
encryption header is originally set to random values, and then
itself encrypted, using three, 32-bit keys. The key values are
initialized using the supplied encryption password. After each byte
is encrypted, the keys are then updated using pseudo-random number
generation techniques in combination with the same CRC-32 algorithm
used in PKZIP and described elsewhere in this document.
The following is the basic steps required to decrypt a file:
1) Initialize the three 32-bit keys with the password.
2) Read and decrypt the 12-byte encryption header, further
initializing the encryption keys.
3) Read and decrypt the compressed data stream using the
encryption keys.
Step 1 - Initializing the encryption keys
-----------------------------------------
Key(0) <- 305419896
Key(1) <- 591751049
Key(2) <- 878082192
loop for i <- 0 to length(password)-1
update_keys(password(i))
end loop
Where update_keys() is defined as:
update_keys(char):
Key(0) <- crc32(key(0),char)
Key(1) <- Key(1) + (Key(0) & 000000ffH)
Key(1) <- Key(1) * 134775813 + 1
Key(2) <- crc32(key(2),key(1) >> 24)
end update_keys
Where crc32(old_crc,char) is a routine that given a CRC value and a
character, returns an updated CRC value after applying the CRC-32
algorithm described elsewhere in this document.
Step 2 - Decrypting the encryption header
-----------------------------------------
The purpose of this step is to further initialize the encryption
keys, based on random data, to render a plaintext attack on the
data ineffective.
Read the 12-byte encryption header into Buffer, in locations
Buffer(0) thru Buffer(11).
loop for i <- 0 to 11
C <- buffer(i) ^ decrypt_byte()
update_keys(C)
buffer(i) <- C
end loop
Where decrypt_byte() is defined as:
unsigned char decrypt_byte()
local unsigned short temp
temp <- Key(2) | 2
decrypt_byte <- (temp * (temp ^ 1)) >> 8
end decrypt_byte
After the header is decrypted, the last 1 or 2 bytes in Buffer
should be the high-order word/byte of the CRC for the file being
decrypted, stored in Intel low-byte/high-byte order, or the high-order
byte of the file time if bit 3 of the general purpose bit flag is set.
Versions of PKZIP prior to 2.0 used a 2 byte CRC check; a 1 byte CRC check is
used on versions after 2.0. This can be used to test if the password
supplied is correct or not.
Step 3 - Decrypting the compressed data stream
----------------------------------------------
The compressed data stream can be decrypted as follows:
loop until done
read a character into C
Temp <- C ^ decrypt_byte()
update_keys(temp)
output Temp
end loop
}
const
EncryptedHeaderSize = 12;
LastEncryptedHeaderByte = EncryptedHeaderSize - 1;
type
TZipKeys = array [0..2] of Cardinal;
TFWZipKeys = class
private
FKeys: TZipKeys;
protected
procedure UpdateKeys(Value: Byte);
function DecryptByte: Byte;
public
constructor Create(const Password: AnsiString);
end;
TFWZipCryptor = class(TFWZipKeys)
protected
function EncryptByte(Value: Byte): Byte;
public
procedure GenerateEncryptionHeader(Stream: TStream;
IsDescryptorFlagPresent: Boolean;
CRC32, FileDate: Cardinal);
procedure EncryptBuffer(Buffer: PByte; Size: Int64);
end;
TFWZipDecryptor = class(TFWZipKeys)
public
function LoadEncryptionHeader(Stream: TStream;
IsDescryptorFlagPresent: Boolean;
CRC32, FileDate: Cardinal): Boolean;
procedure DecryptBuffer(Buffer: PByte; Size: Int64);
end;
implementation
const
DefaultKeys: TZipKeys = (305419896, 591751049, 878082192);
{ TFWZipKeys }
constructor TFWZipKeys.Create(const Password: AnsiString);
var
I: Integer;
begin
inherited Create;
{
Step 1 - Initializing the encryption keys
-----------------------------------------
Key(0) <- 305419896
Key(1) <- 591751049
Key(2) <- 878082192
loop for i <- 0 to length(password)-1
update_keys(password(i))
end loop
}
FKeys := DefaultKeys;
for I := 1 to Length(Password) do
UpdateKeys(Byte(Password[I]));
end;
function TFWZipKeys.DecryptByte: Byte;
var
temp: Word;
begin
{
Where decrypt_byte() is defined as:
unsigned char decrypt_byte()
local unsigned short temp
temp <- Key(2) | 2
decrypt_byte <- (temp * (temp ^ 1)) >> 8
end decrypt_byte
}
temp := FKeys[2] or 2;
Result := (temp * (temp xor 1)) shr 8;
end;
procedure TFWZipKeys.UpdateKeys(Value: Byte);
begin
{
Key(0) <- crc32(key(0),char)
Key(1) <- Key(1) + (Key(0) & 000000ffH)
Key(1) <- Key(1) * 134775813 + 1
Key(2) <- crc32(key(2),key(1) >> 24)
}
FKeys[0] := ((FKeys[0] shr 8) and $FFFFFF) xor
CRC32Table[(FKeys[0] xor Value) and $FF];
FKeys[1] := FKeys[1] + (FKeys[0] and $FF);
FKeys[1] := FKeys[1] * 134775813 + 1;
FKeys[2] := ((FKeys[2] shr 8) and $FFFFFF) xor
CRC32Table[(FKeys[2] xor (FKeys[1] shr 24)) and $FF];
end;
{ TFWZipCryptor }
procedure TFWZipCryptor.EncryptBuffer(Buffer: PByte; Size: Int64);
var
temp: Byte;
begin
// реверсированный вариант TFWZipDecryptor.DecryptBuffer
while Size > 0 do
begin
Dec(Size);
temp := DecryptByte;
UpdateKeys(Buffer^);
Buffer^ := temp xor Buffer^;
Inc(Buffer);
end;
end;
function TFWZipCryptor.EncryptByte(Value: Byte): Byte;
var
temp: Byte;
begin
temp := DecryptByte;
UpdateKeys(Value);
Result := temp xor Value;
end;
procedure TFWZipCryptor.GenerateEncryptionHeader(Stream: TStream;
IsDescryptorFlagPresent: Boolean; CRC32, FileDate: Cardinal);
var
Buffer: array [0..EncryptedHeaderSize - 1] of Byte;
I: Integer;
begin
// реверсированный вариант TFWZipDecryptor.LoadEncryptionHeader
Randomize;
for I := 0 to LastEncryptedHeaderByte - 2 do
Buffer[I] := EncryptByte(Byte(Random(MAXBYTE)));
if IsDescryptorFlagPresent then
begin
Buffer[10] := EncryptByte(LoByte(LoWord(FileDate)));
Buffer[11] := EncryptByte(HiByte(LoWord(FileDate)));
end
else
begin
Buffer[10] := EncryptByte(LoByte(HiWord(CRC32)));
Buffer[11] := EncryptByte(HiByte(HiWord(CRC32)));
end;
Stream.WriteBuffer(Buffer[0], EncryptedHeaderSize);
end;
{ TFWZipDecryptor }
procedure TFWZipDecryptor.DecryptBuffer(Buffer: PByte; Size: Int64);
var
temp: Byte;
begin
{
Step 3 - Decrypting the compressed data stream
----------------------------------------------
The compressed data stream can be decrypted as follows:
loop until done
read a character into C
Temp <- C ^ decrypt_byte()
update_keys(temp)
output Temp
end loop
}
while Size > 0 do
begin
Dec(Size);
temp := Buffer^ xor DecryptByte;
UpdateKeys(temp);
Buffer^ := temp;
Inc(Buffer);
end;
end;
function TFWZipDecryptor.LoadEncryptionHeader(Stream: TStream;
IsDescryptorFlagPresent: Boolean; CRC32, FileDate: Cardinal): Boolean;
var
Buffer: array [0..EncryptedHeaderSize - 1] of Byte;
I: Integer;
C: Byte;
begin
{
Read the 12-byte encryption header into Buffer, in locations
Buffer(0) thru Buffer(11).
loop for i <- 0 to 11
C <- buffer(i) ^ decrypt_byte()
update_keys(C)
buffer(i) <- C
end loop
}
Stream.ReadBuffer(Buffer[0], EncryptedHeaderSize);
for I := 0 to LastEncryptedHeaderByte do
begin
C := Buffer[I] xor DecryptByte;
UpdateKeys(C);
Buffer[I] := C;
end;
{
After the header is decrypted, the last 1 or 2 bytes in Buffer
should be the high-order word/byte of the CRC for the file being
decrypted, stored in Intel low-byte/high-byte order, or the high-order
byte of the file time if bit 3 of the general purpose bit flag is set.
}
if IsDescryptorFlagPresent then
Result := Buffer[LastEncryptedHeaderByte] = HiByte(LoWord(FileDate))
else
Result := Buffer[LastEncryptedHeaderByte] = HiByte(HiWord(CRC32));
end;
end.

View File

@ -0,0 +1,402 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : FWZipModifier
// * Purpose : Класс для модификации созданного ранее ZIP архива
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2015.
// * Version : 1.0.11
// * Home Page : http://rouse.drkb.ru
// * Home Blog : http://alexander-bagel.blogspot.ru
// ****************************************************************************
// * Stable Release : http://rouse.drkb.ru/components.php#fwzip
// * Latest Source : https://github.com/AlexanderBagel/FWZip
// ****************************************************************************
//
// Используемые источники:
// ftp://ftp.info-zip.org/pub/infozip/doc/appnote-iz-latest.zip
// http://zlib.net/zlib-1.2.5.tar.gz
// http://www.base2ti.com/
//
unit FWZipModifier;
{$mode delphi}
{$codepage UTF8}
interface
uses
LCLIntf, LCLType, LMessages, windows,
Classes,
SysUtils,
FWZipConsts,
FWZipReader,
FWZipWriter,
FWZipZLib;
type
TReaderIndex = Integer;
TFWZipModifierItem = class(TFWZipWriterItem)
private
FReaderIndex: TReaderIndex; // индекс TFWZipReader в массиве TFWZipModifier.FReaderList
FOriginalItemIndex: Integer; // оригинальный индекс элемента в изначальном архиве
protected
property ReaderIndex: TReaderIndex read FReaderIndex write FReaderIndex;
property OriginalItemIndex: Integer read FOriginalItemIndex write FOriginalItemIndex;
public
constructor Create(Owner: TFWZipWriter;
const InitFilePath: string;
InitAttributes: TWin32FileAttributeData;
const InitFileName: string = ''); override;
end;
EFWZipModifier = class(Exception);
// Данная структура хранит все блоки ExData из подключаемых архивов
TExDataRecord = record
Index: Integer;
Tag: Word;
Stream: TMemoryStream;
end;
TExDataRecords = array of TExDataRecord;
// структура для хранения подключенного архива и его блоков ExData
TReaderData = record
Reader: TFWZipReader;
ExDataRecords: TExDataRecords;
end;
TReaderList = array of TReaderData;
TFWZipModifier = class(TFWZipWriter)
private
FReaderList: TReaderList;
function CheckZipFileIndex(Value: TReaderIndex): TReaderIndex;
function AddItemFromZip(AReader: TFWZipReader;
ReaderIndex: TReaderIndex; ItemIndex: Integer): Integer;
protected
function GetItemClass: TFWZipWriterItemClass; override;
procedure FillItemCDFHeader(CurrentItem: TFWZipWriterItem;
var Value: TCentralDirectoryFileHeaderEx); override;
procedure CompressItem(CurrentItem: TFWZipWriterItem;
Index: Integer; StreamSizeBeforeCompress: Int64; Stream: TStream); override;
procedure FillExData(Stream: TStream; Index: Integer); override;
procedure OnLoadExData(Sender: TObject; ItemIndex: Integer;
Tag: Word; Data: TStream);
public
destructor Destroy; override;
function AddZipFile(const FilePath: string; SFXOffset: Integer = -1;
ZipEndOffset: Integer = -1): TReaderIndex; overload;
function AddZipFile(FileStream: TStream; SFXOffset: Integer = -1;
ZipEndOffset: Integer = -1): TReaderIndex; overload;
function AddFromZip(ReaderIndex: TReaderIndex): Integer; overload;
function AddFromZip(ReaderIndex: TReaderIndex; const ItemPath: string): Integer; overload;
function AddFromZip(ReaderIndex: TReaderIndex; ItemsList: TStringList): Integer; overload;
end;
implementation
type
TFWZipReaderFriendly = class(TFWZipReader);
TFWZipReaderItemFriendly = class(TFWZipReaderItem);
{ TFWZipModifierItem }
//
// В конструкторе производим первичную инициализацию полей
// Сами поля ReaderIndex и OriginalItemIndex будут инициализироваться только
// при добавлении их посредством класса TFWZipModifier
// =============================================================================
constructor TFWZipModifierItem.Create(Owner: TFWZipWriter;
const InitFilePath: string; InitAttributes: TWin32FileAttributeData;
const InitFileName: string);
begin
inherited Create(Owner, InitFilePath, InitAttributes, InitFileName);
FReaderIndex := -1;
FOriginalItemIndex := -1;
end;
{ TFWZipModifier }
//
// Функция переносит элемент в финальный архив из ранее добавленного архива.
// В качестве результата возвращает индекс элемента в списке.
// Параметры:
// ReaderIndex - индекс ранее добавленно функцией AddZipFile архива
// ItemPath - имя элемента, которое требуется добавить
// =============================================================================
function TFWZipModifier.AddFromZip(ReaderIndex: TReaderIndex;
const ItemPath: string): Integer;
var
Reader: TFWZipReader;
begin
CheckZipFileIndex(ReaderIndex);
Reader := FReaderList[ReaderIndex].Reader;
Result :=
AddItemFromZip(Reader, ReaderIndex, Reader.GetElementIndex(ItemPath));
end;
//
// Функция переносит все элементы из ранее добавленного архива в финальный архив.
// В качестве результата возвращает количество успешно добавленных элементов.
// Параметры:
// ReaderIndex - индекс ранее добавленно функцией AddZipFile архива
// =============================================================================
function TFWZipModifier.AddFromZip(ReaderIndex: TReaderIndex): Integer;
var
I: Integer;
Reader: TFWZipReader;
begin
CheckZipFileIndex(ReaderIndex);
Result := 0;
Reader := FReaderList[ReaderIndex].Reader;
for I := 0 to Reader.Count - 1 do
if AddItemFromZip(Reader, ReaderIndex, I) >= 0 then
Inc(Result);
end;
//
// Функция переносит все элементы из ранее добавленного архива
// по списку в финальный архив.
// В качестве результата возвращает количество успешно добавленных элементов.
// Параметры:
// ReaderIndex - индекс ранее добавленно функцией AddZipFile архива
// ItemsList - список элементов к добавлению
// =============================================================================
function TFWZipModifier.AddFromZip(ReaderIndex: TReaderIndex;
ItemsList: TStringList): Integer;
var
I: Integer;
Reader: TFWZipReader;
begin
CheckZipFileIndex(ReaderIndex);
Result := 0;
Reader := FReaderList[ReaderIndex].Reader;
for I := 0 to ItemsList.Count - 1 do
if AddItemFromZip(Reader, ReaderIndex,
Reader.GetElementIndex(ItemsList[I])) >= 0 then
Inc(Result);
end;
//
// Функция переносит элемент в финальный архив из ранее добавленного архива.
// В качестве результата возвращает индекс элемента в списке.
// =============================================================================
function TFWZipModifier.AddItemFromZip(AReader: TFWZipReader;
ReaderIndex: TReaderIndex; ItemIndex: Integer): Integer;
var
OldItem: TFWZipReaderItemFriendly;
NewItem: TFWZipModifierItem;
begin
Result := -1;
if ItemIndex < 0 then Exit;
// Получаем указатель на элемент из уже существующего архива
OldItem := TFWZipReaderItemFriendly(AReader.Item[ItemIndex]);
// создаем новый элемент, который будем добавлять к новому архиву
NewItem := TFWZipModifierItem(
GetItemClass.Create(Self, '', OldItem.Attributes, OldItem.FileName));
// переключаем его в режим получения данных вручную
NewItem.UseExternalData := True;
// инициализируем ему индексы, дабы потом понять, откуда брать о нем данные
NewItem.ReaderIndex := ReaderIndex;
NewItem.OriginalItemIndex := ItemIndex;
// инициализируем внешние и рассчитываемые поля
NewItem.Comment := OldItem.Comment;
NewItem.NeedDescriptor :=
OldItem.CentralDirFileHeader.GeneralPurposeBitFlag and PBF_DESCRIPTOR <> 0;
NewItem.UseUTF8String :=
OldItem.CentralDirFileHeader.GeneralPurposeBitFlag and PBF_UTF8 <> 0;
// добавляем
Result := AddNewItem(NewItem);
end;
//
// Функция добавляет новый архив из которого можно брать готовые данные.
// В качестве результата возвращает индекс архива в списке добавленных.
// Параметры:
// FileStream - поток с данными архива
// SFXOffset и ZipEndOffset - его границы
// =============================================================================
function TFWZipModifier.AddZipFile(FileStream: TStream; SFXOffset,
ZipEndOffset: Integer): TReaderIndex;
var
AReader: TFWZipReader;
begin
Result := Length(FReaderList);
SetLength(FReaderList, Result + 1);
AReader := TFWZipReader.Create;
AReader.OnLoadExData := OnLoadExData;
AReader.LoadFromStream(FileStream, SFXOffset, ZipEndOffset);
FReaderList[Result].Reader := AReader;
end;
//
// Функция добавляет новый архив из которого можно брать готовые данные.
// В качестве результата возвращает индекс архива в списке добавленных.
// Параметры:
// FilePath - путь к добавляемому архиву
// SFXOffset и ZipEndOffset - его границы
// =============================================================================
function TFWZipModifier.AddZipFile(const FilePath: string;
SFXOffset, ZipEndOffset: Integer): TReaderIndex;
var
AReader: TFWZipReader;
begin
Result := Length(FReaderList);
SetLength(FReaderList, Result + 1);
AReader := TFWZipReader.Create;
AReader.OnLoadExData := OnLoadExData;
AReader.LoadFromFile(FilePath, SFXOffset, ZipEndOffset);
FReaderList[Result].Reader := AReader;
end;
//
// Функция проверяет правильность переданного индекса архива в списке
// =============================================================================
function TFWZipModifier.CheckZipFileIndex(Value: TReaderIndex): TReaderIndex;
begin
Result := Value;
if (Value < 0) or (Value >= Length(FReaderList)) then
raise EFWZipModifier.CreateFmt('Invalid index value (%d).', [Value]);
end;
//
// Процедура перекрывает сжатие данных эелемента
// и берет эти данные из ранее сформированного архива.
// =============================================================================
procedure TFWZipModifier.CompressItem(CurrentItem: TFWZipWriterItem;
Index: Integer; StreamSizeBeforeCompress: Int64; Stream: TStream);
var
OldItem: TFWZipReaderItemFriendly;
NewItem: TFWZipModifierItem;
Reader: TFWZipReaderFriendly;
Offset: Int64;
begin
NewItem := TFWZipModifierItem(CurrentItem);
// проверка, работаем ли мы с элементом, данные которого заполняются вручную?
if not NewItem.UseExternalData then
begin
inherited;
Exit;
end;
// получаем указатель на класс, который держит добавленный ранее архив
Reader := TFWZipReaderFriendly(FReaderList[NewItem.ReaderIndex].Reader);
// получаем указатель на оригинальный элемент архива
OldItem := TFWZipReaderItemFriendly(Reader.Item[NewItem.OriginalItemIndex]);
// рассчитываем его позицию в архиве
Offset := OldItem.CentralDirFileHeader.RelativeOffsetOfLocalHeader;
Inc(Offset, SizeOf(TLocalFileHeader));
Inc(Offset, OldItem.CentralDirFileHeader.FilenameLength);
if OldItem.CentralDirFileHeaderEx.UncompressedSize >= MAXDWORD then
Inc(Offset, SizeOf(TExDataInfo64));
Reader.ZIPStream.Position := Offset;
// копируем данные как есть, без перепаковки
Stream.CopyFrom(Reader.ZIPStream, OldItem.CentralDirFileHeaderEx.CompressedSize);
end;
//
// Modifier слегка не оптимально расходует память, поэтому подчищаем.
// =============================================================================
destructor TFWZipModifier.Destroy;
var
I, A: Integer;
begin
for I := 0 to Length(FReaderList) - 1 do
begin
FReaderList[I].Reader.Free;
for A := 0 to Length(FReaderList[I].ExDataRecords) - 1 do
FReaderList[I].ExDataRecords[A].Stream.Free;
end;
inherited;
end;
//
// Процедура перекрывает заполнение блоков ExData
// и берет эти данные из ранее сформированного архива.
// =============================================================================
procedure TFWZipModifier.FillExData(Stream: TStream; Index: Integer);
var
NewItem: TFWZipModifierItem;
ReaderIndex: TReaderIndex;
I: Integer;
ExDataSize: Word;
ExDataRecord: TExDataRecord;
begin
NewItem := TFWZipModifierItem(Item[Index]);
// проверка, работаем ли мы с элементом, данные которого заполняются вручную?
if not NewItem.UseExternalData then
begin
inherited;
Exit;
end;
// проверяем привязку к архиву, с елементов которого мы будем добавлять блоки ExData
ReaderIndex := CheckZipFileIndex(NewItem.ReaderIndex);
for I := 0 to Length(FReaderList[ReaderIndex].ExDataRecords) - 1 do
if FReaderList[ReaderIndex].ExDataRecords[I].Index = NewItem.OriginalItemIndex then
begin
// блоков может быть несколько, поэтому добавляем их все
ExDataRecord := FReaderList[ReaderIndex].ExDataRecords[I];
Stream.WriteBuffer(ExDataRecord.Tag, 2);
ExDataSize := ExDataRecord.Stream.Size;
Stream.WriteBuffer(ExDataSize, 2);
Stream.CopyFrom(ExDataRecord.Stream, 0);
end;
end;
//
// Процедура перекрывает заполнение сьруктуры TCentralDirectoryFileHeaderEx
// и берет эти данные из ранее сформированного архива.
// =============================================================================
procedure TFWZipModifier.FillItemCDFHeader(CurrentItem: TFWZipWriterItem;
var Value: TCentralDirectoryFileHeaderEx);
var
OldItem: TFWZipReaderItemFriendly;
NewItem: TFWZipModifierItem;
Reader: TFWZipReader;
begin
NewItem := TFWZipModifierItem(CurrentItem);
// проверка, работаем ли мы с элементом, данные которого заполняются вручную?
if not NewItem.UseExternalData then
begin
inherited;
Exit;
end;
Reader := FReaderList[NewItem.ReaderIndex].Reader;
OldItem := TFWZipReaderItemFriendly(Reader.Item[NewItem.OriginalItemIndex]);
// полностью перезаписываем все данные структуры
// исключением является поле RelativeOffsetOfLocalHeader
// но оно реинициализируется после вызова данного метода
Value := OldItem.CentralDirFileHeaderEx;
end;
//
// Расширяем коллекцию
// =============================================================================
function TFWZipModifier.GetItemClass: TFWZipWriterItemClass;
begin
Result := TFWZipModifierItem;
end;
//
// Задача процедуры собрать все ExData в локальное хранилище,
// чтобы их можно было присоединить к структуре архива на этапе ребилда
// =============================================================================
procedure TFWZipModifier.OnLoadExData(Sender: TObject; ItemIndex: Integer;
Tag: Word; Data: TStream);
var
ReaderCount, ExDataCount: Integer;
ExData: TExDataRecord;
begin
ExData.Index := ItemIndex;
ExData.Tag := Tag;
ExData.Stream := TMemoryStream.Create;
ExData.Stream.CopyFrom(Data, 0);
ReaderCount := Length(FReaderList);
ExDataCount := Length(FReaderList[ReaderCount - 1].ExDataRecords);
SetLength(FReaderList[ReaderCount - 1].ExDataRecords, ExDataCount + 1);
FReaderList[ReaderCount - 1].ExDataRecords[ExDataCount] := ExData;
end;
end.

1569
prereq/fwzip/FWZipReader.pas Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,263 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : FWZipStream
// * Purpose : Вспомогательные стримы для поддержки шифрования на лету,
// * : и усеченного заголовка ZLib
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2015.
// * Version : 1.0.11
// * Home Page : http://rouse.drkb.ru
// * Home Blog : http://alexander-bagel.blogspot.ru
// ****************************************************************************
// * Stable Release : http://rouse.drkb.ru/components.php#fwzip
// * Latest Source : https://github.com/AlexanderBagel/FWZip
// ****************************************************************************
//
// Используемые источники:
// ftp://ftp.info-zip.org/pub/infozip/doc/appnote-iz-latest.zip
// http://zlib.net/zlib-1.2.5.tar.gz
// http://www.base2ti.com/
//
//
// Описание идеи модуля:
// При помещении в архив сжатого блока данных методом Deflate у него
// отрезается двухбайтный заголовок в котором указаны параметры сжатия.
// Т.е. в архив помещаются сами данные в чистом виде.
// Для распаковки необходимо данный заголовок восстановить.
// Данный класс позволяет добавить данный заголовок "на лету"
// абсолютно прозрачно для внешнего кода.
// Сам заголовок генерируется в конструкторе и подставляется в методе Read.
// Так-же класс, выступая посредником между двумя стримами,
// позволяет производить шифрование и дешифровку передаваемых данных.
// Шифрование производится в методе Write, в этот момент класс является
// посредником между TCompressionStream и результирующим стримом.
// Дешифрование осуществляется в методе Read, в этот момент класс является
// посредником между стримом со сжатыми и
// пошифрованными данными и TDecompressionStream.
//
unit FWZipStream;
{$mode delphi}
{$codepage UTF8}
interface
{$I fwzip.inc}
uses
Classes,
FWZipConsts,
FWZipCrypt,
FWZipCrc32,
FWZipZLib;
type
TFWZipItemStream = class(TStream)
private
FOwner: TStream;
FCryptor: TFWZipCryptor;
FDecryptor: TFWZipDecryptor;
FSize, FStart, FPosition: Int64;
{$IFDEF USE_AUTOGENERATED_ZLIB_HEADER}
FHeader: Word;
{$ENDIF}
protected
function GetSize: Int64; override;
public
constructor Create(AOwner: TStream; Cryptor: TFWZipCryptor;
Decryptor: TFWZipDecryptor; CompressLevel: Byte; ASize: Int64);
function Seek(Offset: Longint; Origin: Word): Longint; overload; override;
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; overload; override;
function Read(var Buffer; Count: Longint): Longint; override;
function Write(const Buffer; Count: Longint): Longint; override;
end;
implementation
{ TFWZipItemStream }
constructor TFWZipItemStream.Create(AOwner: TStream; Cryptor: TFWZipCryptor;
Decryptor: TFWZipDecryptor; CompressLevel: Byte; ASize: Int64);
begin
inherited Create;
FOwner := AOwner;
FCryptor := Cryptor;
FDecryptor := Decryptor;
FSize := ASize;
FStart := AOwner.Position;
FPosition := 0;
// Rouse_ 30.10.2013
// Устаревший код
{$IFDEF USE_AUTOGENERATED_ZLIB_HEADER}
// Rouse_ 17.03.2011
// Размерчик все-же нужно править увеличикая на размер заголовка
Inc(FSize, 2);
// Восстанавливаем пропущенный заголовок ZLib стрима
// см. deflate.c - int ZEXPORT deflate (strm, flush)
// uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
FHeader := (Z_DEFLATED + (7 {32k Window size} shl 4)) shl 8;
// if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
// level_flags = 0;
// else if (s->level < 6)
// level_flags = 1;
// else if (s->level == 6)
// level_flags = 2;
// else
// level_flags = 3;
//
// сам CompressLevel (level_flags)
// берется из уже заполненного GeneralPurposeBitFlag
// здесь мы из битовой маски восстанавливаем оригинальные значения
case CompressLevel of
PBF_COMPRESS_SUPERFAST:
CompressLevel := 0;
PBF_COMPRESS_FAST:
CompressLevel := 1;
PBF_COMPRESS_NORMAL:
CompressLevel := 2;
PBF_COMPRESS_MAXIMUM:
CompressLevel := 3;
end;
// header |= (level_flags << 6);
FHeader := FHeader or (CompressLevel shl 6);
// if (s->strstart != 0) header |= PRESET_DICT;
// словарь не используется - оставляем без изменений
// header += 31 - (header % 31);
Inc(FHeader, 31 - (FHeader mod 31));
// putShortMSB(s, header);
FHeader := (FHeader shr 8) + (FHeader and $FF) shl 8;
{$ENDIF}
end;
function TFWZipItemStream.GetSize: Int64;
begin
Result := FSize;
end;
function TFWZipItemStream.Read(var Buffer; Count: Integer): Longint;
var
P: PByte;
DecryptBuff: Pointer;
begin
// Rouse_ 30.10.2013
// Устаревший код
{$IFDEF USE_AUTOGENERATED_ZLIB_HEADER}
if FPosition = 0 then
begin
// если зачитываются данные с самого начала
// необходимо перед ними разместить заголовок ZLib
P := @FHeader;
Move(P^, Buffer, 2);
FOwner.Position := FStart;
P := @Buffer;
Inc(P, 2);
if Count > Size then
Count := Size;
FOwner.Position := FStart;
if FDecryptor <> nil then
begin
// в случае если файл зашифрован, производим расшифровку блока
GetMem(DecryptBuff, Count - 2);
try
Result := FOwner.Read(DecryptBuff^, Count - 2);
FDecryptor.DecryptBuffer(DecryptBuff, Result);
Move(DecryptBuff^, P^, Result);
finally
FreeMem(DecryptBuff);
end;
end
else
Result := FOwner.Read(P^, Count - 2);
Inc(Result, 2);
Inc(FPosition, Result);
end
else
begin
FOwner.Position := FStart + Position - 2;
{$ELSE}
begin
FOwner.Position := FStart + Position;
{$ENDIF}
if Count > Size - Position then
Count := Size - Position;
if FDecryptor <> nil then
begin
// в случае если файл зашифрован, производим расшифровку блока
GetMem(DecryptBuff, Count);
try
Result := FOwner.Read(DecryptBuff^, Count);
FDecryptor.DecryptBuffer(DecryptBuff, Result);
P := @Buffer;
Move(DecryptBuff^, P^, Result);
finally
FreeMem(DecryptBuff);
end;
end
else
Result := FOwner.Read(Buffer, Count);
Inc(FPosition, Result);
end;
end;
function TFWZipItemStream.Seek(Offset: Integer; Origin: Word): Longint;
begin
Result := Seek(Int64(Offset), TSeekOrigin(Origin));
end;
function TFWZipItemStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
begin
case Origin of
soBeginning: FPosition := Offset;
soCurrent: Inc(FPosition, Offset);
soEnd: FPosition := Size + Offset;
end;
Result := FPosition;
end;
function TFWZipItemStream.Write(const Buffer; Count: Integer): Longint;
var
EncryptBuffer: PByte;
begin
if FCryptor = nil then
Result := FOwner.Write(Buffer, Count)
else
begin
// криптуем буфер
GetMem(EncryptBuffer, Count);
try
Move(Buffer, EncryptBuffer^, Count);
// Rouse_ 31.10.2013
// Устаревший код
{$IFDEF USE_AUTOGENERATED_ZLIB_HEADER}
// Шифровать блок нужно пропустив двубайтный заголовок ZLib
if FPosition = 0 then
begin
Inc(EncryptBuffer, 2);
FCryptor.EncryptBuffer(EncryptBuffer, Count - 2);
Dec(EncryptBuffer, 2);
end
else
{$ENDIF}
FCryptor.EncryptBuffer(EncryptBuffer, Count);
Result := FOwner.Write(EncryptBuffer^, Count);
finally
FreeMem(EncryptBuffer);
end;
end;
Inc(FPosition, Result);
end;
end.

1822
prereq/fwzip/FWZipWriter.pas Normal file

File diff suppressed because it is too large Load Diff

682
prereq/fwzip/FWZipZLib.pas Normal file
View File

@ -0,0 +1,682 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : FWZipZLib
// * Purpose : Базовые стримы сжатия и распаковки.
// * : Вынесено из ZLibEx в отдельный модуль
// * : для совместимости со старыми версиями Delphi
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2015.
// * Version : 1.0.11
// * Home Page : http://rouse.drkb.ru
// * Home Blog : http://alexander-bagel.blogspot.ru
// ****************************************************************************
// * Stable Release : http://rouse.drkb.ru/components.php#fwzip
// * Latest Source : https://github.com/AlexanderBagel/FWZip
// ****************************************************************************
//
// Используемые источники:
// ftp://ftp.info-zip.org/pub/infozip/doc/appnote-iz-latest.zip
// http://zlib.net/zlib-1.2.5.tar.gz
// http://www.base2ti.com/
//
{*************************************************************************************************
* ZLibEx.pas *
* *
* copyright (c) 2000-2013 base2 technologies *
* copyright (c) 1995-2002 Borland Software Corporation *
* *
*************************************************************************************************}
unit FWZipZLib;
{$mode delphi}
{$codepage UTF8}
interface
{$I fwzip.inc}
uses
Classes,
SysUtils,
{$IFDEF USE_ZLIB_EX}
ZLibExApi
{$ELSE}
{$IFDEF USE_ZLIB_DLL}
ZLib_external
{$ELSE}
ZLib
{$ENDIF}
{$ENDIF};
type
TStreamPos = Int64;
TZStrategy = (
zsDefault,
zsFiltered,
zsHuffman,
zsRLE,
zsFixed
);
TCompressionLevel = (
clNone,
clFastest,
clDefault,
clMax,
clLevel1,
clLevel2,
clLevel3,
clLevel4,
clLevel5,
clLevel6,
clLevel7,
clLevel8,
clLevel9
);
TZError = (
zeError,
zeStreamError,
zeDataError,
zeMemoryError,
zeBufferError,
zeVersionError
);
TZFlush = (
zfNoFlush,
zfPartialFlush,
zfSyncFlush,
zfFullFlush,
zfFinish,
zfBlock,
zfTrees
);
const
ZLevels: Array [TCompressionLevel] of Integer = (
Z_NO_COMPRESSION, // zcNone
Z_BEST_SPEED, // zcFastest
Z_DEFAULT_COMPRESSION, // zcDefault
Z_BEST_COMPRESSION, // zcMax
1, // zcLevel1
2, // zcLevel2
3, // zcLevel3
4, // zcLevel4
5, // zcLevel5
6, // zcLevel6
7, // zcLevel7
8, // zcLevel8
9 // zcLevel9
);
{** compression methods ***********************************************************************}
Z_DEFLATED = 8;
{** compression levels ************************************************************************}
Z_NO_COMPRESSION = 0;
Z_BEST_SPEED = 1;
Z_BEST_COMPRESSION = 9;
Z_DEFAULT_COMPRESSION = (-1);
{** flush constants ***************************************************************************}
Z_NO_FLUSH = 0;
Z_PARTIAL_FLUSH = 1;
Z_SYNC_FLUSH = 2;
Z_FULL_FLUSH = 3;
Z_FINISH = 4;
Z_BLOCK = 5;
Z_TREES = 6;
{** compression strategies ********************************************************************}
Z_FILTERED = 1;
Z_HUFFMAN_ONLY = 2;
Z_RLE = 3;
Z_FIXED = 4;
Z_DEFAULT_STRATEGY = 0;
ZStrategies: Array [TZStrategy] of Integer = (
Z_DEFAULT_STRATEGY, // zsDefault
Z_FILTERED, // zsFiltered
Z_HUFFMAN_ONLY, // zsHuffman
Z_RLE, // zsRLE
Z_FIXED // zsFixed
);
ZErrors: Array [TZError] of Integer = (
Z_ERRNO, // zeError
Z_STREAM_ERROR, // zeStreamError
Z_DATA_ERROR, // zeDataError
Z_MEM_ERROR, // zeMemoryError
Z_BUF_ERROR, // zeBufferError
Z_VERSION_ERROR // zeVersionError
);
ZFlushes: Array [TZFlush] of Integer = (
Z_NO_FLUSH, // zfNoFlush
Z_PARTIAL_FLUSH, // zfPartialFlush
Z_SYNC_FLUSH, // zfSyncFlush
Z_FULL_FLUSH, // zfFullFlush
Z_FINISH, // zfFinish
Z_BLOCK, // zfBlock
Z_TREES // zfTrees
);
{** return code messages **********************************************************************}
z_errmsg: Array [0..9] of String = (
'Need dictionary', // Z_NEED_DICT (2)
'Stream end', // Z_STREAM_END (1)
'OK', // Z_OK (0)
'File error', // Z_ERRNO (-1)
'Stream error', // Z_STREAM_ERROR (-2)
'Data error', // Z_DATA_ERROR (-3)
'Insufficient memory', // Z_MEM_ERROR (-4)
'Buffer error', // Z_BUF_ERROR (-5)
'Incompatible version', // Z_VERSION_ERROR (-6)
''
);
type
{** TCustomZStream ****************************************************************************}
TCustomZStream = class(TStream)
private
FStream : TStream;
FStreamPos : TStreamPos;
FOnProgress: TNotifyEvent;
FZStream : TZStreamRec;
FBuffer : Array [Word] of Byte;
function GetStreamPosition: TStreamPos;
procedure SetStreamPosition(value: TStreamPos);
protected
constructor Create(stream: TStream);
function StreamRead(var buffer; count: Longint): Longint;
function StreamWrite(const buffer; count: Longint): Longint;
function StreamSeek(offset: Longint; origin: Word): Longint;
procedure StreamReadBuffer(var buffer; count: Longint);
procedure StreamWriteBuffer(const buffer; count: Longint);
procedure DoProgress; dynamic;
property StreamPosition: TStreamPos read GetStreamPosition write SetStreamPosition;
property OnProgress: TNotifyEvent read FOnProgress write FOnProgress;
end;
{** TZCompressionStream ***********************************************************************}
TZCompressionStream = class(TCustomZStream)
private
function GetCompressionRate: Single;
public
constructor Create(dest: TStream;
compressionLevel: TCompressionLevel = clDefault); overload;
constructor Create(dest: TStream; compressionLevel: TCompressionLevel;
windowBits, memLevel: Integer; strategy: TZStrategy); overload;
destructor Destroy; override;
function Read(var buffer; count: Longint): Longint; override;
function Write(const buffer; count: Longint): Longint; override;
function Seek(offset: Longint; origin: Word): Longint; override;
property CompressionRate: Single read GetCompressionRate;
property OnProgress;
end;
{** TZDecompressionStream *********************************************************************}
TZDecompressionStream = class(TCustomZStream)
public
constructor Create(source: TStream); overload;
constructor Create(source: TStream; windowBits: Integer); overload;
destructor Destroy; override;
function Read(var buffer; count: Longint): Longint; override;
function Write(const buffer; count: Longint): Longint; override;
function Seek(offset: Longint; origin: Word): Longint; override;
property OnProgress;
end;
type
EZLibErrorClass = class of EZlibError;
EZLibError = class(Exception)
private
FErrorCode: Integer;
public
constructor Create(code: Integer; const dummy: String = ''); overload;
constructor Create(error: TZError; const dummy: String = ''); overload;
property ErrorCode: Integer read FErrorCode write FErrorCode;
end;
EZCompressionError = class(EZLibError);
EZDecompressionError = class(EZLibError);
implementation
const
SZInvalid = 'Invalid ZStream operation!';
function ZCompressCheck(code: Integer): Integer;
begin
result := code;
if code < 0 then
begin
raise EZCompressionError.Create(code);
end;
end;
function ZDecompressCheck(code: Integer; raiseBufferError: Boolean = True): Integer;
begin
Result := code;
if code < 0 then
begin
if (code <> Z_BUF_ERROR) or raiseBufferError then
begin
raise EZDecompressionError.Create(code);
end;
end;
end;
{** zlib deflate routines ***********************************************************************}
function ZDeflateInit(var stream: TZStreamRec;
level: TCompressionLevel): Integer;
begin
result := deflateInit_(stream, ZLevels[level], ZLIB_VERSION,
SizeOf(TZStreamRec));
end;
function ZDeflateInit2(var stream: TZStreamRec;
level: TCompressionLevel; windowBits, memLevel: Integer;
strategy: TZStrategy): Integer;
begin
{$IFDEF OLDEST_ZLIB}
result := ZDeflateInit(stream, level);
{$ELSE}
result := deflateInit2_(stream, ZLevels[level], Z_DEFLATED, windowBits,
memLevel, ZStrategies[strategy], ZLIB_VERSION, SizeOf(TZStreamRec));
{$ENDIF}
end;
function ZDeflate(var stream: TZStreamRec; flush: TZFlush): Integer;
begin
result := deflate(stream, ZFlushes[flush]);
end;
function ZDeflateEnd(var stream: TZStreamRec): Integer;
begin
result := deflateEnd(stream);
end;
{** zlib inflate routines ***********************************************************************}
function ZInflateInit(var stream: TZStreamRec): Integer;
begin
result := inflateInit_(stream, ZLIB_VERSION, SizeOf(TZStreamRec));
end;
function ZInflateInit2(var stream: TZStreamRec;
windowBits: Integer): Integer;
begin
{$IFDEF OLDEST_ZLIB}
result := ZInflateInit(stream);
{$ELSE}
result := inflateInit2_(stream, windowBits, ZLIB_VERSION,
SizeOf(TZStreamRec));
{$ENDIF}
end;
function ZInflate(var stream: TZStreamRec; flush: TZFlush): Integer;
begin
result := inflate(stream, ZFlushes[flush]);
end;
function ZInflateEnd(var stream: TZStreamRec): Integer;
begin
result := inflateEnd(stream);
end;
function ZInflateReset(var stream: TZStreamRec): Integer;
begin
result := inflateReset(stream);
end;
{** EZLibError **********************************************************************************}
constructor EZLibError.Create(code: Integer; const dummy: String);
begin
inherited Create(z_errmsg[2 - code]);
FErrorCode := code;
end;
constructor EZLibError.Create(error: TZError; const dummy: String);
begin
Create(ZErrors[error], dummy);
end;
{** TCustomZStream ******************************************************************************}
constructor TCustomZStream.Create(stream: TStream);
begin
inherited Create;
FStream := stream;
FStreamPos := stream.Position;
{$IFDEF OLDEST_ZLIB}
FZStream.zalloc := zlibAllocMem;
FZStream.zfree := zlibFreeMem;
{$ENDIF}
end;
function TCustomZStream.StreamRead(var buffer; count: Longint): Longint;
begin
if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;
result := FStream.Read(buffer,count);
FStreamPos := FStreamPos + result;
end;
function TCustomZStream.StreamWrite(const buffer; count: Longint): Longint;
begin
if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;
result := FStream.Write(buffer,count);
FStreamPos := FStreamPos + result;
end;
function TCustomZStream.StreamSeek(offset: Longint; origin: Word): Longint;
begin
if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;
result := FStream.Seek(offset,origin);
FStreamPos := FStream.Position;
end;
procedure TCustomZStream.StreamReadBuffer(var buffer; count: Longint);
begin
if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;
FStream.ReadBuffer(buffer,count);
FStreamPos := FStreamPos + count;
end;
procedure TCustomZStream.StreamWriteBuffer(const buffer; count: Longint);
begin
if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;
FStream.WriteBuffer(buffer,count);
FStreamPos := FStreamPos + count;
end;
procedure TCustomZStream.DoProgress;
begin
if Assigned(FOnProgress) then FOnProgress(Self);
end;
function TCustomZStream.GetStreamPosition: TStreamPos;
begin
result := FStream.Position;
end;
procedure TCustomZStream.SetStreamPosition(value: TStreamPos);
begin
FStream.Position := value;
FStreamPos := FStream.Position;
end;
{** TZCompressionStream *************************************************************************}
constructor TZCompressionStream.Create(dest: TStream;
compressionLevel: TCompressionLevel);
begin
inherited Create(dest);
FZStream.next_out := @FBuffer;
FZStream.avail_out := SizeOf(FBuffer);
ZCompressCheck(ZDeflateInit(FZStream, compressionLevel));
end;
constructor TZCompressionStream.Create(dest: TStream;
compressionLevel: TCompressionLevel; windowBits, memLevel: Integer;
strategy: TZStrategy);
begin
{$IFDEF USE_AUTOGENERATED_ZLIB_HEADER}
Create(dest, compressionLevel);
{$ELSE}
inherited Create(dest);
FZStream.next_out := @FBuffer;
FZStream.avail_out := SizeOf(FBuffer);
ZCompressCheck(ZDeflateInit2(FZStream, compressionLevel, windowBits,
memLevel, strategy));
{$ENDIF}
end;
destructor TZCompressionStream.Destroy;
begin
FZStream.next_in := Nil;
FZStream.avail_in := 0;
try
while ZCompressCheck(ZDeflate(FZStream, zfFinish)) <> Z_STREAM_END do
begin
StreamWriteBuffer(FBuffer, SizeOf(FBuffer) - FZStream.avail_out);
FZStream.next_out := @FBuffer;
FZStream.avail_out := SizeOf(FBuffer);
end;
if FZStream.avail_out < SizeOf(FBuffer) then
begin
StreamWriteBuffer(FBuffer, SizeOf(FBuffer) - FZStream.avail_out);
end;
finally
ZDeflateEnd(FZStream);
end;
inherited Destroy;
end;
function TZCompressionStream.Read(var buffer; count: Longint): Longint;
begin
raise EZCompressionError.Create(SZInvalid);
end;
function TZCompressionStream.Write(const buffer; count: Longint): Longint;
var
writeCount: Longint;
begin
result := count;
FZStream.next_in := @buffer;
FZStream.avail_in := count;
while FZStream.avail_in > 0 do
begin
ZCompressCheck(ZDeflate(FZStream, zfNoFlush));
if FZStream.avail_out = 0 then
begin
writeCount := StreamWrite(FBuffer,SizeOf(FBuffer));
if writeCount = SizeOf(FBuffer) then
begin
FZStream.next_out := @FBuffer;
FZStream.avail_out := SizeOf(FBuffer);
DoProgress;
end
else
begin
StreamPosition := StreamPosition - writeCount;
result := Cardinal(count) - Cardinal(FZStream.avail_in);
FZStream.avail_in := 0;
end;
end;
end;
end;
function TZCompressionStream.Seek(offset: Longint; origin: Word): Longint;
begin
if (offset = 0) and (origin = soFromCurrent) then
begin
result := FZStream.total_in;
end
else raise EZCompressionError.Create(SZInvalid);
end;
function TZCompressionStream.GetCompressionRate: Single;
begin
if FZStream.total_in = 0 then result := 0
else result := (1.0 - (FZStream.total_out / FZStream.total_in)) * 100.0;
end;
{** TZDecompressionStream ***********************************************************************}
constructor TZDecompressionStream.Create(source: TStream);
begin
inherited Create(source);
FZStream.next_in := @FBuffer;
FZStream.avail_in := 0;
ZDecompressCheck(ZInflateInit(FZStream));
end;
constructor TZDecompressionStream.Create(source: TStream;
windowBits: Integer);
begin
{$IFDEF USE_AUTOGENERATED_ZLIB_HEADER}
Create(source);
{$ELSE}
inherited Create(source);
FZStream.next_in := @FBuffer;
FZStream.avail_in := 0;
ZDecompressCheck(ZInflateInit2(FZStream, windowBits));
{$ENDIF}
end;
destructor TZDecompressionStream.Destroy;
begin
ZInflateEnd(FZStream);
inherited Destroy;
end;
function TZDecompressionStream.Read(var buffer; count: Longint): Longint;
var
zresult: Integer;
begin
FZStream.next_out := @buffer;
FZStream.avail_out := count;
zresult := Z_OK;
while (FZStream.avail_out > 0) and (zresult <> Z_STREAM_END) do
begin
if FZStream.avail_in = 0 then
begin
FZStream.avail_in := StreamRead(FBuffer,SizeOf(FBuffer));
if FZStream.avail_in = 0 then
begin
result := Cardinal(count) - Cardinal(FZStream.avail_out);
Exit;
end;
FZStream.next_in := @FBuffer;
DoProgress;
end;
zresult := ZDecompressCheck(ZInflate(FZStream, zfNoFlush));
end;
if (zresult = Z_STREAM_END) and (FZStream.avail_in > 0) then
begin
StreamPosition := StreamPosition - FZStream.avail_in;
FZStream.avail_in := 0;
end;
result := Cardinal(count) - Cardinal(FZStream.avail_out);
end;
function TZDecompressionStream.Write(const Buffer; Count: Longint): Longint;
begin
raise EZDecompressionError.Create(SZInvalid);
end;
function TZDecompressionStream.Seek(Offset: Longint; Origin: Word): Longint;
var
buf: Array [0..8191] of Byte;
i : Integer;
begin
if (offset = 0) and (origin = soFromBeginning) then
begin
ZDecompressCheck(ZInflateReset(FZStream));
FZStream.next_in := @FBuffer;
FZStream.avail_in := 0;
StreamPosition := 0;
end
else if ((offset >= 0) and (origin = soFromCurrent)) or
(((Cardinal(offset) - Cardinal(FZStream.total_out)) > 0) and
(origin = soFromBeginning)) then
begin
if origin = soFromBeginning then Dec(offset, FZStream.total_out);
if offset > 0 then
begin
for i := 1 to offset div SizeOf(buf) do ReadBuffer(buf, SizeOf(buf));
ReadBuffer(buf, offset mod SizeOf(buf));
end;
end
else if (offset = 0) and (origin = soFromEnd) then
begin
while Read(buf, SizeOf(buf)) > 0 do ;
end
else raise EZDecompressionError.Create(SZInvalid);
result := FZStream.total_out;
end;
end.

344
prereq/fwzip/Readme.txt Normal file
View File

@ -0,0 +1,344 @@
FWZip версия 1.0.11 от 31 августа 2015 года.
Автор: Александр (Rouse_) Багель
Авторский сайт: http://rouse.drkb.ru
Авторский блог: http://alexander-bagel.blogspot.ru/
Стабильная версия FWZip: http://rouse.drkb.ru/components.php#fwzip
Репозиторий с последней версией FWZip: https://github.com/AlexanderBagel/FWZip
mailto: rouse79@yandex.ru
0. В качестве вступления:
В последнее время по работе я часто начал сталкиваться с задачами требующими работу с архивами.
Формат архива для решения задач был выбран самый распространенный - ZIP и я начал искать уже реализованные сторонние классы для работы с архивами в этом формате.
Изначально требования были просты: мне требовался компонент (набор классов) который не тянул бы за собой сторонние библиотеки.
Таких компонентов нашлось достаточно много.
Но потом задачи стали усложнятся и соответственно требования к компонентам изменились.
Через какое-то время мне нужен был компонент умеющий паковать и распаковывать файлы больших размеров.
Еще через какое-то время потребовалось чтобы при этом он не отьедал почти всю память у приложения.
В конце концов мне потребовалось что бы он умел работать с зашифрованными архивами,
плюс до кучи (т.к. работать приходится в основном с XML - т.е. текстом) чтобы он поддерживал алгоритм сжатия PPMD.
В итоге у меня остался один более-менее приемлимый вариант, но стоящий 400 долларов и не умеющий PPMD (sic).
Пришлось делать все самому (правда PPMD еще не добавлен, но скоро - очень скоро)...
1. Возможности библиотеки:
Набор классов FWZip предназначен для создания и распаковки ZIP архивов с методами сжатия Store и Deflate.
В данный момент поддерживаются следующие расширенные элементы спецификации:
- поддержка ZIP64 расширения
- поддержка DataDescryptors
- поддержка криптографии по методу PKWARE
- поддержка расширенного блока данных с NTFS аттрибутами
- поддержка UTF8 кодировки в именах файлов
Не поддерживаемые элементы спецификации (реализации части из них я не смог встретить ни в одном архиваторе):
- не поддерживаются следующие алгоритмы сжатия Shrunk, ReducedХ, Imploded, TCA, Deflate64, PKWAREхх, BZIP2
- не поддерживаются методы усиленной криптографии
- не поддерживаются многотомные архивы
- не поддерживается шифрование CentralDirectory
Вкратце - все что может сделать WinRar при создании ZIP архива, данный набор классов умеет.
Поддерживаются Delphi версий от седьмой и до XE8 включительно (как 32-бита, так и 64).
Включая работу в составе FireMonkey приложения (iOS/Android сборки не поддерживаются).
ВАЖНО!!!
При использовании данной библиотеки в составе Delphi 2007 и ниже могут быть проблемы с распаковкой данных в связи с тем
что с этими версиями Delphi поставляется устаревший вариант ZLib. Его крайне желательно обновить.
Читайте инструкцию в пункте 11.
Известные ошибки:
FWZip не корректно производит контроль размеров каждого блоков ExData для каждой из записей, ограничивая размер каждого блока числом MAXWORD.
В действительности MAXWORD - это максимальная длина всех ExData блоков в записи.
В связи с этим в следующих версиях будет переписан алгоритм работы с блоками ExData и вполне вероятно он может быть не совместим со старыми версиями FWZip,
так как скорее всего будет отключено наполнение данных блоков через событие и все блоки будут представленны как массив структур.
2. Список изменений:
1.0 (от 22 февраля 2011 года):
- первичный релиз
1.0.1 (от 4 марта 2011 года):
- поправлены некоторые глюки.
Спасибо ребятам с форума www.delphimaster.ru
(Дмитрий Тимохов, Riply, И. Павел, clickmaker, Гость, Думкин, Dennis I. Komarov, han_malign, brother, Sergey Masloff, antonn)
- убрана проверка на уникальность имен в архиве
- добавлена проверка на длину пути
- убрана критическая секция в классе TFWZipReader. Т.к. паралельная распаковка в текущем варианте всеравно не возможна, то смысла морозить потоки я не вижу.
- структура TFWZipWriterItem переделана в виде класса, как следствие убрана функция ReplaceItem
- к классам TFWZipReaderItem и TFWZipWriterItem добавлено свойство Tag
- исправлена ошибка деления на ноль в обработчике OnProgress возникающая при попытка сжать файл нулевого размера.
- добавлена работа с блоком ExData каждого элемента (см. демо UseExDataBlob)
1.0.2 (от 4 апреля 2011 года):
- исправлена ошибка извлечения данных сохраненных без сжатия (Z_NO_COMPRESSION).
Не выставлялся результат erDone в случае упешного извлечения.
Спасибо Роману Игнатьеву ака "Romkin", обнаружевшему данную ошибку.
- исправлена не совсем корректная обработка исключения EZDecompressionError в процедуре ExtractToStream.
- добавлен дополнительный результат erWrongCRC32 к типу TExtractResult.
Он выставляется в случае если параметр CheckCRC32 функции ExtractToStream был выстален в False и контрольная сумма извлеченного файла не совпала с оригинальной.
- обработчик исключения EZDecompressionError изменен на EZLibError.
Спасибо Александру Басову ака "@!!ex" за детект данного глюка.
1.0.3 (от 29 июня 2011 года):
- для тех, кто испытывает сложности с распаковкой архивов созданных сторонними архиваторами при ипользовании Delphi версии 2009 и ниже, функционал zlib вынесен в отдельную библиотеку.
(см. описание в пункте 9) или узнайте о возможности использования альтернативного варианта ZLib описанном в пункте 10.
- исправлено неверное определение размера свободного места на диске в процедуре ExtractAll (не учитывался относительный и UNC пути). Спасибо Павлу Лобачу за детектирование данной ошибки.
- исправлен порядок выставления атрибутов файла и времени при распаковке (если в артибутах присутствовал флаг FILE_ATTRIBUTE_READONLY, то выставление даты файла возвращало ошибку)
- добавлено событие OnDuplicate, возникающее при попытке распаковки уже существующего на диске файла
- реализованы предложения от Антона ака Fr0sT (отдельный респект за подробный анализ кода), а именно:
- исправлены очепятки в наименовании некоторых свойств и внутренних переменных.
- добавлен дополнительный перекрытый конструктор к классу TFWZipWriter, позволяющий выставить сжатие по умолчанию.
- добавлена дополнительная перекрытая функция AddFolder с меньшим количеством параметров.
- в событие TZipProgressEvent добавлена переменная Cancel позволяющая пользователю прервать процесс создания/распаковки архива.
- добавлена обработка исключительных ситуаций при создании архива (см. демо BuildWithException)
1.0.4 (от 21 февраля 2012 года):
- добавлена overload процедура ExtractAll к классу TFWZipReader. Данная процедура принимает дополнительный параметр ExtractMask,
указывающий маску, по которой будет происходить отбор файлов для извлечения. (см. демо ExctractZIPDemo1)
- добавлена процедура AddFilesAndFolders к классу TFWZipWriter. (см. демо CreateZIPDemo1)
- исправлены ошибки найденные v1ctar, за что ему огромное спасибо.
- Добавлены новые типы исключений: EZipReader, EZipReaderItem, EZipWriter и EZipWriterItem.
1.0.5 (от 2 октября 2012 года)
- расширены параметры методов TFWZipReader.LoadFromFile и TFWZipReader.LoadFromStream.
Добавлены два параметра позволяющие указывать оффсеты на начало и конец архива в файле или стриме с данными. (Например с целью пропустить SFX стаб).
1.0.6 (от 14 февраля 2013 года)
- добавлено свойство TrimPackedStreamSize к классу TFWZipWriter, отсекующее лишний мусор в конце ZLib стрима.
По умолчанию данное свойство включено.
Если данное свойство отключено, созданный архив не сможет распаковаться при помощи библиотеки ICSharpCode.SharpZipLibrary, проверяющей валидность размеров стримов.
- Исправлена некорректная запись поля VersionNeededToExtract.
Спасибо Гигорию Поверенному ака 'Grighome' за детектирование вышеперечисленных ошибок.
- добавлен метод AddEmptyFolder для добавления пустых папок.
- добавлено свойство AlwaysAddEmptyFolder. Если оно включено, добавление записи о папке происходит всегда перед добавлением информации об ее элементах.
- исправлена ошибка алгоритма поиска сигнатуры END_OF_CENTRAL_DIR_SIGNATURE.
В случае если последним элементом архива был незапакованый ZIP архив, то был большой шанс неверного определения позиции данной сигнатуры.
Спасибо Владимиру Симашко за детектирование данной ошибки.
1.0.7 (от 10 июня 2013 года)
- исправлена критическая ошибка в модуле FWZipReader приводящая к разрушению памяти приложения при открытии специальным образом сформированных файлов.
Спасибо Олегу Егорову ака 'Ega23' за детектирование данной ошибки.
1.0.8 (от 14 июня 2013 года)
- код протестирован на совместимость с 64 битным режимом компиляции под Delphi XE3.
- изменен алгоритм поиска сигнатуры END_OF_CENTRAL_DIR_SIGNATURE, убран избыточный реаллок.
Реализован набор предложений от Владислава Нечепоренко:
- добавлена поддержка строк в кодировке UTF8. Для этого в классе FWZipWriter добавлен флаг UseUTF8String, этот-же флаг добавлен к классу TFWZipWriterItem для более тонкой настройки параметров.
класс FWZipReader корректно распознает такие строки и преоборазовывает их в OEM формат при открытии архива.
- добавлена поддержка ZLibEx, старые версии которой используются в составе Delphi.
использование данной библиотеки является рекомендованной при ошибках распаковки. (см. описание в пункте 11)
- добавлен файл fwzip.inc в котором можно глобально менять настройки библиотеки
1.0.9 (от 20 июля 2013 года)
- обновлен текст спецификации в разделе документации (текущая поддерживаемая 6.3)
- некоторые свойства архива вынесены в protected поле для возможности анализа архива (см. демо ZipAnalizer)
- добавлен вывод состояния прогресса TProgressState в обработчики событий OnProgress
Исправлены ошибки обнаруженные Дмитрием Головачевым:
- добавлена поддержка спецификации PKWARE версии 6.3 в части работы с архивами более 4 гигабайт. (в частности 7Zip слишком требователем к структуре Zip64EndOfCentralDir и требует размер параметра SizeOfZip64EOFCentralDirectoryRecord декрементированный на 12 байт, в отличие от других архиваторов WinRar/PkZip/WinZip)
- метод AddFolder теперь возвращает правильное количество добавленных файлов с учетом файлов в подпапках
1.0.10 (от 6 ноября 2013 года)
- В класс TFWZipReaderItem добавлено свойство ItemIndex
- Добавлен новый класс исключения EZipReaderRead, поднимающийся при ошибках чтения архива
- Добавлен новый класс исключения EZipWriterWrite, поднимающийся при ошибках создания архива
- Во всех исключениях модуля FWZipReader и частично FWZipWriter предоставляется более подробная информация об ошибке.
- свойство TrimPackedStreamSize является устаревшим и работает только при включенной директиве USE_AUTOGENERATED_ZLIB_HEADER
Реализован набор предложений от Владислава Нечепоренко:
- время модификации файлов пишется с учетом таймзоны
- в класс TFWZipReader добавлена процедура проверки архива Check (производит эмуляцию распаковки без реального извлечения данных)
- для возможности работы с элементом архива до того момента пока он не залочен, добавлены два состояния прогреса psStart и psEnd генерируемый классом TFWZipReader (см. тип TProgressState).
- создание архива переведено на использование deflateInit2_ (см. примечение ВАЖНО!!!)
- убраны очепятки и неиспользуемые переменные
Исправлена ошибка присланная Максимом Буяновым связанная с тем что FWZip не мог распаковать некоторые архивы созданные в 7Zip, а именно ZLib не мог распаковать такой архив с использованием автогенерируемого заголовка и вызовом функции inflateInit_. Правильный вариант заключается в отключении автогенерируемого заголовка и переходу на вызов функции inflateInit2_.
- устаревший код, приводящий к данной ошибке убран под директиву USE_AUTOGENERATED_ZLIB_HEADER, большое спасибо Владиславу Нечепоренко за помощь в исправлении данной ошибки.
ВАЖНО!!!
Использование нового функционала при стандартном модуле ZLib возможно только начиная с Delphi 2009 и выше. Для более старых версий Delphi автоматически будет включена директива USE_AUTOGENERATED_ZLIB_HEADER, переводящая на старый вариант сжатия/распаковки. Если требуется наличие нового функционала необходимо к FWZip подключить библиотеку ZLibEx (плюс включить директиву USE_ZLIB_EX), либо воспользоваться реализацией через библиотеку обьявлением директивы USE_ZLIB_DLL.
1.0.11 (от 31 августа 2015 года)
- Добавлен класс TFWZipModifier, позволяющий производить любые изменения архива "на лету" и не требующий перепаковки данных.
- Небольшие изменения в классе FWZipReader, неверно читался пустой архив, из-за некоретного детектирования END_OF_CENTRAL_DIR_SIGNATURE
- Исправлена небольшая ошибка при проверке архива в случае если проверялся большой файл (неверно рассчитывались проценты)
- Поправлен неверный режим создания TFileStream в процедуре TFWZipReader.LoadFromFile
Реализовано предложение от Максима Буянова:
- К классу TFWZipReader добавлено свойство DefaultDuplicateAction, позволяющее назначить действие по умолчанию при обнаружении дубликатов распаковываемых файлов.
Исправлены ошибки обнаруженные Максимом Минеевым и реализовано новое предложение:
- Исправлена ошибка рабты с граничными значениями MAXDWORD при которых не всегда правильно принималось решение о использовании ZIP64
- В LocalDirectory теперь пишется информация о ZIP64 (ибо некоторые архиваторы почему-то не хотят ее читать из CentralDirectory)
- Добавлен перекрытый метод Extract к классу TFWZipReaderItem позволяющий изменять имя распаковываемого файла
Исправлена ошибка найденная Дмитрием Мозулёвым:
- При использовании UTF8 происходил RangeCheckError в процедуре TFWZipReaderItem.InitFromStream при проверке имени файла на принадлежность директории.
3. Описание файлов:
- .\FWZipConsts.pas - Типы и константы используемые для работы с ZIP архивами
- .\FWZipCrc32.pas - Набор функций для рассчета контрольной суммы блока данных
- .\FWZipCrypt.pas - Реализация криптографии по методу PKWARE
- .\FWZipModifier.pas - Класс для модификации ранее созданных ZIP архивов без перепаковки неизмененных данных.
- .\FWZipReader.pas - Набор классов для распаковки ZIP архива
- .\FWZipStream.pas - Вспомогательный стрим для поддержки шифрования на лету и усеченного заголовка ZLib
- .\FWZipWriter.pas - Класс для создания ZIP архива
- .\FWZipZLib.pas - Базовые стримы сжатия и распаковки. Вынесено из ZLibEx в отдельный модуль для совместимости со старыми версиями Delphi
- .\fwzip.inc - Директивы глобального изменения настроек библиотеки
- .\Demos\ - папки с демонстрационными примерами
- .\Demos\FWZipDemos.bpg - ProjectGroup со всеми демопримерами для Delphi7
- .\Demos\FWZipDemos.groupproj - ProjectGroup со всеми демопримерами для Delphi 2007 и выше
- .\Demos\Create ZIP 1\CreateZIPDemo1.dpr - Демонстрация создания архива используя различные варианты добавления данных
- .\Demos\Create ZIP 2\CreateZIPDemo2.dpr - Демонстрация создания архива и изменения добавленных записей
- .\Demos\Extract ZIP 1\ExctractZIPDemo1.dpr - Демонстрация распаковки архива.
- .\Demos\Extract ZIP 2\ExctractZIPDemo2.dpr - Демонстрация распаковки зашифрованного архива.
- .\Modify ZIP\ - папки с примерами модификации архивов без их перепаковки
- .\Modify ZIP\Merge two ZIP\MergeZip.dpr - пример обьединения данных из нескольких архивов в один
- .\Modify ZIP\Replace data in ZIP\ReplaceZipItemData.dpr - пример изменения части данных в архиве не требующий перепаковки неизмененных данных.
- .\Modify ZIP\Split ZIP\SplitZip.dpr - пример разбития архива на несколько частей.
- .\Demos\Use ZIP ExData\UseExDataBlob.dpr - Демонстрация работы с блоком ExData каждого элемента архива.
- .\Demos\Test Build With Exception\BuildWithException.dpr - Демонстрация обработки исключительных ситуаций при создании архива.
- .\Demos\PerfomanceTest\ - папка с проектом тестировщика производительности.
- .\Demos\DemoResults\ - папка создается при работе демонстрационных примеров.
- .\Demos\ZipAnalizer\ - папка с проектом анализатора ZIP архивов с использованием FWZipReader
- .\Demos\ZipAnalizer2\ - папка с проектом анализатора ZIP архивов с использованием сканирования сигнатур
- .\Doc\* - документация, на основании которой велась разработка данного набора классов.
- .\zlib_external.pas - Юнит для подключения внешней библиотеки (см. описание в пункте 9) - устарел
- .\zlib_dll\ - папка с проектом внешней библиотеки
- .\zlib_dll\zlib_d2010.dpr - проект внешней библиотеки
- .\zlib_dll\zlib_d2010.dll - скомпилированная библиотека
4. Создание архива:
Для создания архива применяется класс TFWZipWriter.
Порядок действий:
- создать TFWZipWriter
- при помощи методов AddStream/AddFiles/AddFolder указать содержимое будующего архива.
- выполнить тонкую настройку каждого элемента при помощи изменения свойств класса TFWZipWriterItem
- при необходимости удалить лишние элементы вызовом метода DeleteItem или Clear
- установить коментарий к архиву
- по необходимости назначить обработчики OnException, OnProgress и OnSaveExData
- вызвать метод BuildZip
- проанализировать результат вызова метода BuildZip
- разрушить TFWZipWriter
4.1 - Модификация архива
Для модификации архива применяется класс TFWZipModifier, являющийся настледником TFWZipWriter.
Порядок действий аналогичен созданию архива, за исключением наличия двух дополнительных методов:
- AddZipFile - добавляем уже существующий архив из которого будут браться данные не требующие перепаковки
- AddFromZip - добавляет данные из существующего архива в текущий (скажнем аналог AddStream)
Смотрите примеры в папке .\Demos\Modify ZIP\
5. Распаковка архива:
Для распаковки архива применяется класс TFWZipReader
Порядок действий:
- создать TFWZipReader
- открыть архив вызовом методов LoadFromFile/LoadFromStream
- при желании выполнить проверку целостности архива вызовом метода Check
- по необходимости назначить обработчик OnProgress
- автоматическая распаковка всего архива:
- если архив зашифрован, то передать список паролей свойству PasswordList или назначить обработчик OnPassword
- если предполагается работа с блоком ExData назначить обработчик OnLoadExData
- по необходимости назначить обработчик OnExeption. В нем вы будете принимать решение, продолжать распаковку архива при исключении или прервать.
- вызвать метод ExtractAll
- ручная распаковка поэлементно:
- выбрать необходимый элемент архива при помощи TFWZipReader.Item[Index] и вызвать метод Extract/ExtractToStream
- если предполагается работа с блоком ExData назначить обработчик OnLoadExData выбранному элементу
- если Extract/ExtractToStream вернул erNeedPassword, повторить вызов метода при этом указав верный пароль
- разрушить TFWZipReader
6. Планируемые расширения классов:
В ближайшем будующем планируется добавить поддержку многотомных архивов, и NTFS стримов (ExDataTag = $0E, в принципе вы и сами можете ее добаить работая с обработчиками блока ExData вынесенными наружу).
Так-же планируется поддержка X.509 сертификатов и следующих методов сжатия (BZIP2, LZMA, PPMD).
Но, т.к. данный набор классов пишется под себя, то данные расширения будут добавлены только по мере их необходимости в моей основной работе.
7. Производительность:
- перед созданием архива резервируется память под CentralDirectory = SizeOf(TCentralDirectoryFileHeaderEx) * количество элементов архива.
- средний объем используемой памяти при сжатии 400кб, в пиках до полумегобайта.
- средний объем используемой памяти при распаковке 100Кб, в пиках до 160кб.
Тестирование производилось из рассчета сжатия файла с диска напрямую в архив, и извлечение напрямую из архива в файл на диске.
При использовании промежуточных стримов - размер памяти естественно увеличится.
Результаты нагрузочных тестов (уровень сжатия clDefault):
- сжималось 3 файла по 3 6 и 9 гигабайт:
(тестировалось использование ZIP64 расширения из-за превышения по размеру элементов)
- размер CentralDirectory: 378 байт
- количество элементов: 3
- общий обьем данных: 18,989,302,272 байт (~17 гигабайт)
- время сжатия: 30 минут
- средний расход памяти при сжатии: 396,085 байт
- пиковый расход памяти при сжатии: 396,099 байт
- время распаковки: 15 минут
- средний расход памяти при распаковке: 170,413 байт
- пиковый расход памяти при распаковке: 170,420 байт
- сжималась папка Program Files со старого диска с установленной Windows XP, все элементы шифровались паролем "qwe":
(тестировалось использование ZIP64 расширения из-за превышения по кол-ву элементов + использование дескрипторов)
- размер CentralDirectory: 11,264,400 байт (~10 мегабайт)
- количество элементов: 89,400
- общий обьем данных: 43,748,481,918 байт (~40 гигабайт)
- время сжатия: 1 час 56 минут
- средний расход памяти при сжатии: 403,953 байт
- пиковый расход памяти при сжатии: 413,636 байт
- время распаковки: 40 минут
- средний расход памяти при распаковке: 158,419 байт
- пиковый расход памяти при распаковке: 172,628 байт
8. Технические нюансы:
При формировании архива блок ExData (за исключением ZIP64) не пишется в LocalDirectory (по спецификации его наличие там не обязательно, хотя он и может там присутствовать).
Т.к. этот-же блок присутствует в CentralDirectory, то я посчитал не оптимальным увеличивать размер архива излишним дубляжом информации.
При шифровании файлов в архиве желательно включать DataDescryptors для каждого зашифрованного элемента (состояние данного флага по умолчанию указывается в конструкторе класса TFWZipWriter).
Дело в том, что при шифровании необходимо сгенерировать заголовок инициализации ключа, в создании которого принимает контрольная сумма файла или (при включенных DataDescryptors) время модицикации файла.
Если не указать DataDescryptors то придется зачитывать файл два раза. Первый раз перед генерацией криптозаголовка для получения CRC32, второй раз уже непосредственно при упаковке файла. Таким образом время формирования зашифрованного архива с отключенными DataDescryptors в два раза больше чем с включенными. Сама-же контрольная сумма рассчитается в любом случае на лету при сжатии данных.
Если шифрование не используется, то DataDescryptors желательно отключить, с целью экономии 20 байт на каждый элемент архива.
Сохранение сжатого файла в архив сделано немного не оптимально.
По условию при сжатии методом Deflate, реализуемым ZLib-ом нужно отсекать ZLibHeader размером в два байта.
Я не стал излишне заморачиваться и сделал следующим образом, сначала пишем весь сжатый стрим по его оффсету минус 2 байта, а потом пишем поверх имя файла (ну или EncryptedFileHeader) затирая эти два байта.
Исправить можно немного переписав TFWZipItemStream, но чес слово, лениво сильно :)
Кто хочет - пусть сделает.
9. Использование внешней библиотеки (устарело, см. пункт 11)
При использовании FWZip в версиях Delphi ниже 2010 Александр Басов ака "@!!ex" обнаружил ошибку.
Некоторые архивы, созданные сторонними архиваторами, не рапаковывались. Вызвано это было тем, что старые версии Delphi используют устаревший код ZLib, который не позволял произвести корректную распаковку сжатого стрима. При сборке под Delphi 2010 и выше, данная ошибка изчезала.
Т.к. код ZLib вкомпилен в zlib.dcu, а сами DCU разных версий не совместимы между собой, то пришлось написать отдельную библиотеку, экпортирующую следующие функции в том виде, в котором они реализованы в 2010-ой дельфи:
- deflateInit_
- DeflateInit2_
- deflate
- deflateEnd
- inflateInit_
- inflateInit2_
- inflate
- inflateEnd
- inflateReset
- adler32
Для использования данной библиотеки, необходимо обьявить глобальную директиву USE_ZLIB_DLL и тогда, вместо стантартного юнита ZLib, поставляемого с Delphi, FWZip будет использовать юнит ZLib_external, который будет производить вызов данных функций не из zlib.dcu, а из библиотеки.
10. Использование ZLib поставляемой с Indy (устарело, см. пункт 11)
Еще один вариант замены устаревшей ZLib предложил Павел Лобач.
1. Необходимо скачать и установить самую последнюю версию Indy по следующей ссылке: ftp://indy.fulgan.com/ZIP/
На конец февраля 2012-го года прямая ссылка была следующей: ftp://indy.fulgan.com/ZIP/Indy10_4736.zip
2. Прописать путь к папке с ZLib (.\Lib\Protocols\ZLib\)
3. Сделать этот путь самым первым в настройках проекта (или в настройках IDE, смотря как вы его подключили)
11. Использование ZLibEx (рекомендованный вариант)
Наиболее правильный вариант решения проблем с ошибками распаковок архивов, собранных с использованием более новых версий ZLib предложил Владислав Нечепоренко.
1. Необходимо скачать и установить самую последнюю версию ZLibEx по следующей ссылке: http://www.base2ti.com/
2. Выполнить установку в соответствии с рекомендациями в разделе "installation" из файла Readme.txt
3. Обьявить в настройках проекта глобальную директиву USE_ZLIB_EX

72
prereq/fwzip/fwzip.inc Normal file
View File

@ -0,0 +1,72 @@
////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : fwzip.inc
// * Purpose : Набор классов для распаковки ZIP архива
// * Author : Александр (Rouse_) Багель
// * Copyright : © Fangorn Wizards Lab 1998 - 2015.
// * Version : 1.0.11
// * Home Page : http://rouse.drkb.ru
// * Home Blog : http://alexander-bagel.blogspot.ru
// ****************************************************************************
// * Stable Release : http://rouse.drkb.ru/components.php#fwzip
// * Latest Source : https://github.com/AlexanderBagel/FWZip
// ****************************************************************************
//
// Используемые источники:
// ftp://ftp.info-zip.org/pub/infozip/doc/appnote-iz-latest.zip
// http://zlib.net/zlib-1.2.5.tar.gz
// http://www.base2ti.com/
//
// Данный модуль предназначен для глобального включения
// директив настройки пакета FWZip
// Если необходимо использовать ZLibEx раскоментируйте директиву ниже
// {$DEFINE USE_ZLIB_EX}
// Если необходимо использовать внешнюю библиотеку раскоментируйте директиву ниже
// {$DEFINE USE_ZLIB_DLL}
// Если необходима поддержка сжатия/распаковки по старому варианту
// c генерацией ZLib заголовка раскоментируйте директиву ниже
// Но есть нюанс - распаковка с автогенерируемым заголовком в очень редких случаях
// не сможет открыть архивы созданные при помощи 7Zip
// {$DEFINE USE_AUTOGENERATED_ZLIB_HEADER}
// ВНИМАНИЕ!!!
// =============================================================================
// КОД СЛЕДУЮЩИЙ НИЖЕ НЕ ПРЕДНАЗНАЧЕН ДЛЯ ИЗМЕНЕНИЯ ПРОГРАММИСТОМ И
// СОДЕРЖИТ КРИТИЧЕСКИЕ НАСТРОЙКИ ДЛЯ БИБЛИОТЕКИ FWZip
// Если подключена библиотека ZLibEx, отключаем использование внешней библиотеки
{$IFDEF USE_ZLIB_EX}
{$UNDEF USE_ZLIB_DLL}
{$ENDIF}
// deflateInit2_ и inflateInit2_ отсутствуют в Delphi вплоть до 2009-ой
// поэтому при использовании старых версий дельфи и стандартного модуля ZLib
// необходимо отключать использование данных функций
{$UNDEF OLDEST_ZLIB}
// Если подключена библиотека ZLibEx, то использовать deflateInit2_ и inflateInit2_ можно
{$IFDEF USE_ZLIB_EX}
{$UNDEF OLDEST_ZLIB}
{$ENDIF}
// Если подключена внешняя библиотека, то использовать deflateInit2_ и inflateInit2_ можно
{$IFDEF USE_ZLIB_DLL}
{$UNDEF OLDEST_ZLIB}
{$ENDIF}
// Если использовать deflateInit2_ и inflateInit2_ нельзя,
// принудительно переключаемся на старый режим работы с автогенерируемыми заголовками
{$IFDEF OLDEST_ZLIB}
{$DEFINE USE_AUTOGENERATED_ZLIB_HEADER}
{$ENDIF}

352
prereq/fwzip/fwzip.lpk Normal file
View File

@ -0,0 +1,352 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<Package Version="4">
<PathDelim Value="\"/>
<Name Value="fwzip"/>
<Type Value="RunAndDesignTime"/>
<Author Value="Александр (Rouse_) Багель"/>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<SearchPaths>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
</CompilerOptions>
<Description Value="FWZip"/>
<License Value="0. В качестве вступления:
В последнее время по работе я часто начал сталкиваться с задачами требующими работу с архивами.
Формат архива для решения задач был выбран самый распространенный - ZIP и я начал искать уже реализованные сторонние классы для работы с архивами в этом формате.
Изначально требования были просты: мне требовался компонент (набор классов) который не тянул бы за собой сторонние библиотеки.
Таких компонентов нашлось достаточно много.
Но потом задачи стали усложнятся и соответственно требования к компонентам изменились.
Через какое-то время мне нужен был компонент умеющий паковать и распаковывать файлы больших размеров.
Еще через какое-то время потребовалось чтобы при этом он не отьедал почти всю память у приложения.
В конце концов мне потребовалось что бы он умел работать с зашифрованными архивами, плюс до кучи (т.к. работать приходится в основном с XML - т.е. текстом) чтобы он поддерживал алгоритм сжатия PPMD.
В итоге у меня остался один более-менее приемлимый вариант, но стоящий 400 долларов и не умеющий PPMD (sic).
Пришлось делать все самому (правда PPMD еще не добавлен, но скоро - очень скоро)...
1. Возможности библиотеки:
Набор классов FWZip предназначен для создания и распаковки ZIP архивов с методами сжатия Store и Deflate. В данный момент поддерживаются следующие расширенные элементы спецификации:
- поддержка ZIP64 расширения
- поддержка DataDescryptors
- поддержка криптографии по методу PKWARE
- поддержка расширенного блока данных с NTFS аттрибутами
- поддержка UTF8 кодировки в именах файлов
Не поддерживаемые элементы спецификации (реализации части из них я не смог встретить ни в одном архиваторе):
- не поддерживаются следующие алгоритмы сжатия Shrunk, ReducedХ, Imploded, TCA, Deflate64, PKWAREхх, BZIP2
- не поддерживаются методы усиленной криптографии
- не поддерживаются многотомные архивы
- не поддерживается шифрование CentralDirectory
Вкратце - все что может сделать WinRar при создании ZIP архива, данный набор классов умеет.
Поддерживаются Delphi версий от седьмой и до XE5 включительно (как 32-бита, так и 64) и Lazarus 1.4.4 и выше.
ВАЖНО!!!
При использовании данной библиотеки в составе Delphi 2007 и ниже могут быть проблемы с распаковкой данных в связи с тем что с этими версиями Delphi поставляется устаревший вариант ZLib. Его крайне желательно обновить. Читайте инструкцию в пункте 11.
2. Список изменений:
1.0 (от 22 февраля 2011 года):
- первичный релиз
1.0.1 (от 4 марта 2011 года):
- поправлены некоторые глюки. Спасибо ребятам с форума www.delphimaster.ru
(Дмитрий Тимохов, Riply, И. Павел, clickmaker, Гость, Думкин, Dennis I. Komarov, han_malign, brother, Sergey Masloff, antonn)
- убрана проверка на уникальность имен в архиве
- добавлена проверка на длину пути
- убрана критическая секция в классе TFWZipReader. Т.к. паралельная распаковка в текущем варианте всеравно не возможна, то смысла морозить потоки я не вижу.
- структура TFWZipWriterItem переделана в виде класса, как следствие убрана функция ReplaceItem
- к классам TFWZipReaderItem и TFWZipWriterItem добавлено свойство Tag
- исправлена ошибка деления на ноль в обработчике OnProgress возникающая при попытка сжать файл нулевого размера.
- добавлена работа с блоком ExData каждого элемента (см. демо UseExDataBlob)
1.0.2 (от 4 апреля 2011 года):
- исправлена ошибка извлечения данных сохраненных без сжатия (Z_NO_COMPRESSION). Не выставлялся результат erDone в случае упешного извлечения. Спасибо Роману Игнатьеву ака &quot;Romkin&quot;, обнаружевшему данную ошибку.
- исправлена не совсем корректная обработка исключения EZDecompressionError в процедуре ExtractToStream.
- добавлен дополнительный результат erWrongCRC32 к типу TExtractResult.
Он выставляется в случае если параметр CheckCRC32 функции ExtractToStream был выстален в False и контрольная сумма извлеченного файла не совпала с оригинальной.
- обработчик исключения EZDecompressionError изменен на EZLibError.
Спасибо Александру Басову ака &quot;@!!ex&quot; за детект данного глюка.
1.0.3 (от 29 июня 2011 года):
- для тех, кто испытывает сложности с распаковкой архивов созданных сторонними архиваторами при ипользовании Delphi версии 2009 и ниже, функционал zlib вынесен в отдельную библиотеку.
(см. описание в пункте 9) или узнайте о возможности использования альтернативного варианта ZLib описанном в пункте 10.
- исправлено неверное определение размера свободного места на диске в процедуре ExtractAll (не учитывался относительный и UNC пути). Спасибо Павлу Лобачу за детектирование данной ошибки.
- исправлен порядок выставления атрибутов файла и времени при распаковке (если в артибутах присутствовал флаг FILE_ATTRIBUTE_READONLY, то выставление даты файла возвращало ошибку)
- добавлено событие OnDuplicate, возникающее при попытке распаковки уже существующего на диске файла
- реализованы предложения от Антона ака Fr0sT (отдельный респект за подробный анализ кода), а именно:
- исправлены очепятки в наименовании некоторых свойств и внутренних переменных.
- добавлен дополнительный перекрытый конструктор к классу TFWZipWriter, позволяющий выставить сжатие по умолчанию.
- добавлена дополнительная перекрытая функция AddFolder с меньшим количеством параметров.
- в событие TZipProgressEvent добавлена переменная Cancel позволяющая пользователю прервать процесс создания/распаковки архива.
- добавлена обработка исключительных ситуаций при создании архива (см. демо BuildWithException)
1.0.4 (от 21 февраля 2012 года):
- добавлена overload процедура ExtractAll к классу TFWZipReader. Данная процедура принимает дополнительный параметр ExtractMask,
указывающий маску, по которой будет происходить отбор файлов для извлечения. (см. демо ExctractZIPDemo1)
- добавлена процедура AddFilesAndFolders к классу TFWZipWriter. (см. демо CreateZIPDemo1)
- исправлены ошибки найденные v1ctar, за что ему огромное спасибо.
- Добавлены новые типы исключений: EZipReader, EZipReaderItem, EZipWriter и EZipWriterItem.
1.0.5 (от 2 октября 2012 года)
- расширены параметры методов TFWZipReader.LoadFromFile и TFWZipReader.LoadFromStream.
- Добавлены два параметра позволяющие указывать оффсеты на начало и конец архива в файле или стриме с данными. (Например с целью пропустить SFX стаб).
1.0.6 (от 14 февраля 2013 года)
- добавлено свойство TrimPackedStreamSize к классу TFWZipWriter, отсекующее лишний мусор в конце ZLib стрима. По умолчанию данное свойство включено.
Если данное свойство отключено, созданный архив не сможет распаковаться при помощи библиотеки ICSharpCode.SharpZipLibrary, проверяющей валидность размеров стримов.
- Исправлена некорректная запись поля VersionNeededToExtract.
Спасибо Гигорию Поверенному ака 'Grighome' за детектирование вышеперечисленных ошибок.
- добавлен метод AddEmptyFolder для добавления пустых папок.
- добавлено свойство AlwaysAddEmptyFolder. Если оно включено, добавление записи о папке происходит всегда перед добавлением информации об ее элементах.
- исправлена ошибка алгоритма поиска сигнатуры END_OF_CENTRAL_DIR_SIGNATURE.
В случае если последним элементом архива был незапакованый ZIP архив, то был большой шанс неверного определения позиции данной сигнатуры.
Спасибо Владимиру Симашко за детектирование данной ошибки.
1.0.7 (от 10 июня 2013 года)
- исправлена критическая ошибка в модуле FWZipReader приводящая к разрушению памяти приложения при открытии специальным образом сформированных файлов.
Спасибо Олегу Егорову ака 'Ega23' за детектирование данной ошибки.
1.0.8 (от 14 июня 2013 года)
- код протестирован на совместимость с 64 битным режимом компиляции под Delphi XE3.
- изменен алгоритм поиска сигнатуры END_OF_CENTRAL_DIR_SIGNATURE, убран избыточный реаллок.
Реализован набор предложений от Владислава Нечепоренко:
- добавлена поддержка строк в кодировке UTF8. Для этого в классе FWZipWriter добавлен флаг UseUTF8String, этот-же флаг добавлен к классу TFWZipWriterItem для более тонкой настройки параметров.
- класс FWZipReader корректно распознает такие строки и преоборазовывает их в OEM формат при открытии архива.
- добавлена поддержка ZLibEx, старые версии которой используются в составе Delphi.
использование данной библиотеки является рекомендованной при ошибках распаковки. (см. описание в пункте 11)
- добавлен файл fwzip.inc в котором можно глобально менять настройки библиотеки
1.0.9 (от 20 июля 2013 года)
- обновлен текст спецификации в разделе документации (текущая поддерживаемая 6.3)
- некоторые свойства архива вынесены в protected поле для возможности анализа архива (см. демо ZipAnalizer)
- добавлен вывод состояния прогресса TProgressState в обработчики событий OnProgress
- Исправлены ошибки обнаруженные Дмитрием Головачевым:
- добавлена поддержка спецификации PKWARE версии 6.3 в части работы с архивами более 4 гигабайт. (в частности 7Zip слишком требователем к структуре Zip64EndOfCentralDir и требует размер параметра SizeOfZip64EOFCentralDirectoryRecord декрементированный на 12 байт, в отличие от других архиваторов WinRar/PkZip/WinZip)
- метод AddFolder теперь возвращает правильное количество добавленных файлов с учетом файлов в подпапках
1.0.10 (от 6 ноября 2013 года)
- В класс TFWZipReaderItem добавлено свойство ItemIndex
- Добавлен новый класс исключения EZipReaderRead, поднимающийся при ошибках чтения архива
- Добавлен новый класс исключения EZipWriterWrite, поднимающийся при ошибках создания архива
- Во всех исключениях модуля FWZipReader и частично FWZipWriter предоставляется более подробная информация об ошибке.
- свойство TrimPackedStreamSize является устаревшим и работает только при включенной директиве USE_AUTOGENERATED_ZLIB_HEADER
- Реализован набор предложений от Владислава Нечепоренко:
- время модификации файлов пишется с учетом таймзоны
- в класс TFWZipReader добавлена процедура проверки архива Check (производит эмуляцию распаковки без реального извлечения данных)
- для возможности работы с элементом архива до того момента пока он не залочен, добавлены два состояния прогреса psStart и psEnd генерируемый классом TFWZipReader (см. тип TProgressState).
- создание архива переведено на использование deflateInit2_ (см. примечение ВАЖНО!!!)
- убраны очепятки и неиспользуемые переменные
Исправлена ошибка присланная Максимом Буяновым связанная с тем что FWZip не мог распаковать некоторые архивы созданные в 7Zip, а именно ZLib не мог распаковать такой архив с использованием автогенерируемого заголовка и вызовом функции inflateInit_. Правильный вариант заключается в отключении автогенерируемого заголовка и переходу на вызов функции inflateInit2_.
- устаревший код, приводящий к данной ошибке убран под директиву USE_AUTOGENERATED_ZLIB_HEADER, большое спасибо Владиславу Нечепоренко за помощь в исправлении данной ошибки.
ВАЖНО!!!
Использование нового функционала при стандартном модуле ZLib возможно только начиная с Delphi 2009 и выше. Для более старых версий Delphi автоматически будет включена директива USE_AUTOGENERATED_ZLIB_HEADER, переводящая на старый вариант сжатия/распаковки. Если требуется наличие нового функционала необходимо к FWZip подключить библиотеку ZLibEx (плюс включить директиву USE_ZLIB_EX), либо воспользоваться реализацией через библиотеку обьявлением директивы USE_ZLIB_DLL.
Версия 1.0.11
- Добавлен класс TFWZipModifier, позволяющий производить любые изменения архива &quot;на лету&quot; и не требующий перепаковки данных.
- Небольшие изменения в классе FWZipReader, неверно читался пустой архив, из-за некоретного детектирования END_OF_CENTRAL_DIR_SIGNATURE
- Исправлена небольшая ошибка при проверке архива в случае если проверялся большой файл (неверно рассчитывались проценты)
- Поправлен неверный режим создания TFileStream в процедуре TFWZipReader.LoadFromFile
- Реализовано предложение от Максима Буянова:
- К классу TFWZipReader добавлено свойство DefaultDuplicateAction, позволяющее назначить действие по умолчанию при обнаружении дубликатов распаковываемых файлов.
- Исправлены ошибки обнаруженные Максимом Минеевым и реализовано новое предложение:
- Исправлена ошибка рабты с граничными значениями MAXDWORD при которых не всегда правильно принималось решение о использовании ZIP64
- В LocalDirectory теперь пишется информация о ZIP64 (ибо некоторые архиваторы почему-то не хотят ее читать из CentralDirectory)
- Добавлен перекрытый метод Extract к классу TFWZipReaderItem позволяющий изменять имя распаковываемого файла
- Исправлена ошибка найденная Дмитрием Мозулёвым:
- При использовании UTF8 происходил RangeCheckError в процедуре TFWZipReaderItem.InitFromStream при проверке имени файла на принадлежность директории.
3. Описание файлов:
- .\FWZipConsts.pas - Типы и константы используемые для работы с ZIP архивами
- .\FWZipCrc32.pas - Набор функций для рассчета контрольной суммы блока данных
- .\FWZipCrypt.pas - Реализация криптографии по методу PKWARE
- .\FWZipReader.pas - Набор классов для распаковки ZIP архива
- .\FWZipStream.pas - Вспомогательный стрим для поддержки шифрования на лету и усеченного заголовка ZLib
- .\FWZipWriter.pas - Класс для создания ZIP архива
- .\FWZipZLib.pas - Базовые стримы сжатия и распаковки. Вынесено из ZLibEx в отдельный модуль для совместимости со старыми версиями Delphi
- .\fwzip.inc - Директивы глобального изменения настроек библиотеки
- .\Demos\ - папки с демонстрационными примерами
- .\Demos\FWZipDemos.bpg - ProjectGroup со всеми демопримерами для Delphi7
- .\Demos\FWZipDemos.groupproj - ProjectGroup со всеми демопримерами для Delphi 2007 и выше
- .\Demos\Create ZIP 1\CreateZIPDemo1.dpr - Демонстрация создания архива используя различные варианты добавления данных
- .\Demos\Create ZIP 2\CreateZIPDemo2.dpr - Демонстрация создания архива и изменения добавленных записей
- .\Demos\Extract ZIP 1\ExctractZIPDemo1.dpr - Демонстрация распаковки архива.
- .\Demos\Extract ZIP 2\ExctractZIPDemo2.dpr - Демонстрация распаковки зашифрованного архива.
- .\Demos\Use ZIP ExData\UseExDataBlob.dpr - Демонстрация работы с блоком ExData каждого элемента архива.
- .\Demos\Test Build With Exception\BuildWithException.dpr - Демонстрация обработки исключительных ситуаций при создании архива.
- .\Demos\PerfomanceTest\ - папка с проектом тестировщика производительности.
- .\Demos\DemoResults\ - папка создается при работе демонстрационных примеров.
- .\Demos\ZipAnalizer\ - папка с проектом анализатора ZIP архивов с использованием FWZipReader
- .\Demos\ZipAnalizer2\ - папка с проектом анализатора ZIP архивов с использованием сканирования сигнатур
- .\Doc\* - документация, на основании которой велась разработка данного набора классов.
- .\zlib_external.pas - Юнит для подключения внешней библиотеки (см. описание в пункте 9) - устарел
- .\zlib_dll\ - папка с проектом внешней библиотеки
- .\zlib_dll\zlib_d2010.dpr - проект внешней библиотеки
- .\zlib_dll\zlib_d2010.dll - скомпилированная библиотека
4. Создание архива:
Для создания архива применяется класс TFWZipWriter.
Порядок действий:
- создать TFWZipWriter
- при помощи методов AddStream/AddFiles/AddFolder указать содержимое будующего архива.
- выполнить тонкую настройку каждого элемента при помощи изменения свойств класса TFWZipWriterItem
- при необходимости удалить лишние элементы вызовом метода DeleteItem
- установить коментарий к архиву
- по необходимости назначить обработчики OnException, OnProgress и OnSaveExData
- вызвать метод BuildZip
- проанализировать результат вызова метода BuildZip
- разрушить TFWZipWriter
5. Распаковка архива:
Для распаковки архива применяется класс TFWZipReader
Порядок действий:
- создать TFWZipReader
- открыть архив вызовом методов LoadFromFile/LoadFromStream
- при желании выполнить проверку целостности архива вызовом метода Check
- по необходимости назначить обработчик OnProgress
- автоматическая распаковка всего архива:
- если архив зашифрован, то передать список паролей свойству PasswordList или назначить обработчик OnPassword
- если предполагается работа с блоком ExData назначить обработчик OnLoadExData
- по необходимости назначить обработчик OnExeption. В нем вы будете принимать решение, продолжать распаковку архива при исключении или прервать.
- вызвать метод ExtractAll
- ручная распаковка поэлементно:
- выбрать необходимый элемент архива при помощи TFWZipReader.Item[Index] и вызвать метод Extract/ExtractToStream
- если предполагается работа с блоком ExData назначить обработчик OnLoadExData выбранному элементу
- если Extract/ExtractToStream вернул erNeedPassword, повторить вызов метода при этом указав верный пароль
- разрушить TFWZipReader
6. Планируемые расширения классов:
В ближайшем будующем планируется добавить поддержку многотомных архивов, и NTFS стримов (ExDataTag = $0E, в принципе вы и сами можете ее добаить работая с обработчиками блока ExData вынесенными наружу).
Так-же планируется поддержка X.509 сертификатов и следующих методов сжатия (BZIP2, LZMA, PPMD).
Но, т.к. данный набор классов пишется под себя, то данные расширения будут добавлены только по мере их необходимости в моей основной работе.
7. Производительность:
- перед созданием архива резервируется память под CentralDirectory = SizeOf (TCentralDirectoryFileHeaderEx) * количество элементов архива.
- средний объем используемой памяти при сжатии 400кб, в пиках до полумегобайта.
- средний объем используемой памяти при распаковке 100Кб, в пиках до 160кб.
Тестирование производилось из рассчета сжатия файла с диска напрямую в архив, и извлечение напрямую из архива в файл на диске.
При использовании промежуточных стримов - размер памяти естественно увеличится.
Результаты нагрузочных тестов (уровень сжатия clDefault):
- сжималось 3 файла по 3 6 и 9 гигабайт:
(тестировалось использование ZIP64 расширения из-за превышения по размеру элементов)
- размер CentralDirectory: 378 байт
- количество элементов: 3
- общий обьем данных: 18,989,302,272 байт (~17 гигабайт)
- время сжатия: 30 минут
- средний расход памяти при сжатии: 396,085 байт
- пиковый расход памяти при сжатии: 396,099 байт
- время распаковки: 15 минут
- средний расход памяти при распаковке: 170,413 байт
- пиковый расход памяти при распаковке: 170,420 байт
- сжималась папка Program Files со старого диска с установленной Windows XP, все элементы шифровались паролем &quot;qwe&quot;:
(тестировалось использование ZIP64 расширения из-за превышения по кол-ву элементов + использование дескрипторов)
- размер CentralDirectory: 11,264,400 байт (~10 мегабайт)
- количество элементов: 89,400
- общий обьем данных: 43,748,481,918 байт (~40 гигабайт)
- время сжатия: 1 час 56 минут
- средний расход памяти при сжатии: 403,953 байт
- пиковый расход памяти при сжатии: 413,636 байт
- время распаковки: 40 минут
- средний расход памяти при распаковке: 158,419 байт
- пиковый расход памяти при распаковке: 172,628 байт
8. Технические нюансы:
Не реализована возможность модификации ранее созданного архива. Т.к. при изменении файлов в архиве или их свойств необходимо произвести полную пересборку архива - я посчитал наличие данного функцианала избыточным.
При формировании архива блок ExData не пишется в LocalDirectory (по спецификации его наличие там не обязательно, хотя он и может там присутствовать).
Т.к. этот-же блок присутствует в CentralDirectory, то я посчитал не оптимальным увеличивать размер архива излишним дубляжом информации.
При шифровании файлов в архиве желательно включать DataDescryptors для каждого зашифрованного элемента (состояние данного флага по умолчанию указывается в конструкторе класса TFWZipWriter).
Дело в том, что при шифровании необходимо сгенерировать заголовок инициализации ключа, в создании которого принимает контрольная сумма файла или (при включенных DataDescryptors) время модицикации файла.
Если не указать DataDescryptors то придется зачитывать файл два раза. Первый раз перед генерацией криптозаголовка для получения CRC32, второй раз уже непосредственно при упаковке файла. Таким образом время формирования зашифрованного архива с отключенными DataDescryptors в два раза больше чем с включенными. Сама-же контрольная сумма рассчитается в любом случае на лету при сжатии данных.
Если шифрование не используется, то DataDescryptors желательно отключить, с целью экономии 20 байт на каждый элемент архива.
Сохранение сжатого файла в архив сделано немного не оптимально.
По условию при сжатии методом Deflate, реализуемым ZLib-ом нужно отсекать ZLibHeader размером в два байта.
Я не стал излишне заморачиваться и сделал следующим образом, сначала пишем весь сжатый стрим по его оффсету минус 2 байта, а потом пишем поверх имя файла (ну или EncryptedFileHeader) затирая эти два байта.
Исправить можно немного переписав TFWZipItemStream, но чес слово, лениво сильно :)
Кто хочет - пусть сделает.
9. Использование внешней библиотеки (устарело, см. пункт 11)
При использовании FWZip в версиях Delphi ниже 2010 Александр Басов ака &quot;@!!ex&quot; обнаружил ошибку. Некоторые архивы, созданные сторонними архиваторами, не рапаковывались. Вызвано это было тем, что старые версии Delphi используют устаревший код ZLib, который не позволял произвести корректную распаковку сжатого стрима. При сборке под Delphi 2010 и выше, данная ошибка изчезала.
Т.к. код ZLib вкомпилен в zlib.dcu, а сами DCU разных версий не совместимы между собой, то пришлось написать отдельную библиотеку, экпортирующую следующие функции в том виде, в котором они реализованы в 2010-ой дельфи:
- deflateInit_
- DeflateInit2_
- deflate
- deflateEnd
- inflateInit_
- inflateInit2_
- inflate
- inflateEnd
- inflateReset
- adler32
Для использования данной библиотеки, необходимо обьявить глобальную директиву USE_ZLIB_DLL и тогда, вместо стантартного юнита ZLib, поставляемого с Delphi, FWZip будет использовать юнит ZLib_external, который будет производить вызов данных функций не из zlib.dcu, а из библиотеки.
10. Использование ZLib поставляемой с Indy (устарело, см. пункт 11)
Еще один вариант замены устаревшей ZLib предложил Павел Лобач.
1. Необходимо скачать и установить самую последнюю версию Indy по следующей ссылке: ftp://indy.fulgan.com/ZIP/
На конец февраля 2012-го года прямая ссылка была следующей: ftp://indy.fulgan.com/ZIP/Indy10_4736.zip
2. Прописать путь к папке с ZLib (.\Lib\Protocols\ZLib\)
3. Сделать этот путь самым первым в настройках проекта (или в настройках IDE, смотря как вы его подключили)
11. Использование ZLibEx (рекомендованный вариант)
Наиболее правильный вариант решения проблем с ошибками распаковок архивов, собранных с использованием более новых версий ZLib предложил Владислав Нечепоренко.
1. Необходимо скачать и установить самую последнюю версию ZLibEx по следующей ссылке: http://www.base2ti.com/
2. Выполнить установку в соответствии с рекомендациями в разделе &quot;installation&quot; из файла Readme.txt
3. Обьявить в настройках проекта глобальную директиву USE_ZLIB_EX"/>
<Version Major="1" Release="11"/>
<Files Count="7">
<Item1>
<Filename Value="FWZipConsts.pas"/>
<UnitName Value="FWZipConsts"/>
</Item1>
<Item2>
<Filename Value="FWZipCrc32.pas"/>
<UnitName Value="FWZipCrc32"/>
</Item2>
<Item3>
<Filename Value="FWZipCrypt.pas"/>
<UnitName Value="FWZipCrypt"/>
</Item3>
<Item4>
<Filename Value="FWZipReader.pas"/>
<UnitName Value="FWZipReader"/>
</Item4>
<Item5>
<Filename Value="FWZipStream.pas"/>
<UnitName Value="FWZipStream"/>
</Item5>
<Item6>
<Filename Value="FWZipWriter.pas"/>
<UnitName Value="FWZipWriter"/>
</Item6>
<Item7>
<Filename Value="FWZipZLib.pas"/>
<UnitName Value="FWZipZLib"/>
</Item7>
</Files>
<RequiredPkgs Count="2">
<Item1>
<PackageName Value="LCL"/>
</Item1>
<Item2>
<PackageName Value="FCL"/>
</Item2>
</RequiredPkgs>
<UsageOptions>
<UnitPath Value="$(PkgOutDir)"/>
</UsageOptions>
<PublishOptions>
<Version Value="2"/>
</PublishOptions>
<CustomOptions Items="ExternHelp" Version="2">
<_ExternHelp Items="Count"/>
</CustomOptions>
</Package>
</CONFIG>

21
prereq/fwzip/fwzip.pas Normal file
View File

@ -0,0 +1,21 @@
{ This file was automatically created by Lazarus. Do not edit!
This source is only used to compile and install the package.
}
unit fwzip;
interface
uses
FWZipConsts, FWZipCrc32, FWZipCrypt, FWZipReader, FWZipStream, FWZipWriter,
FWZipZLib, LazarusPackageIntf;
implementation
procedure Register;
begin
end;
initialization
RegisterPackage ('fwzip', @Register );
end.

View File

@ -0,0 +1,25 @@
library zlib_d2010;
uses
ZLib;
{$R *.res}
{$IF CompilerVersion < 21}
{$MESSAGE FATAL ' Ñáîðêà äàííîé áèáëîòåêè âîçìîæíà òîëüêî ñ èñïîëüçîâàíèå Delphi 2010 è âûøå '}
{$IFEND}
exports
adler32,
deflateInit_,
DeflateInit2_,
deflate,
deflateEnd,
inflateInit_,
inflateInit2_,
inflate,
inflateEnd,
inflateReset;
begin
end.

BIN
prereq/zlib1.rar Normal file

Binary file not shown.