mirror of https://github.com/x64dbg/zydis
396 lines
12 KiB
Plaintext
396 lines
12 KiB
Plaintext
unit formGenerator;
|
|
|
|
interface
|
|
|
|
uses
|
|
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
|
|
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, VirtualTrees, System.ImageList, Vcl.ImgList, cxGraphics,
|
|
Vcl.StdCtrls, untInstructionEditor;
|
|
|
|
type
|
|
TfrmGenerator = class(TForm)
|
|
GroupBox: TGroupBox;
|
|
btnClose: TButton;
|
|
btnGenerate: TButton;
|
|
imgIcons16: TcxImageList;
|
|
TreeView: TVirtualStringTree;
|
|
imgTreeView: TcxImageList;
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure TreeViewCollapsing(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
|
var Allowed: Boolean);
|
|
procedure TreeViewFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
|
|
procedure TreeViewGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
|
Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean; var ImageIndex: Integer);
|
|
procedure TreeViewGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex;
|
|
TextType: TVSTTextType; var CellText: string);
|
|
procedure btnCloseClick(Sender: TObject);
|
|
procedure btnGenerateClick(Sender: TObject);
|
|
procedure TreeViewBeforeCellPaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas;
|
|
Node: PVirtualNode; Column: TColumnIndex; CellPaintMode: TVTCellPaintMode; CellRect: TRect;
|
|
var ContentRect: TRect);
|
|
strict private
|
|
FEditor: TInstructionEditor;
|
|
FProgressNodeTotal: PVirtualNode;
|
|
FProgressNode: array[TGeneratorWorkOperation] of PVirtualNode;
|
|
FInfoNode: array[0..6] of PVirtualNode;
|
|
FCurrentOperation: TGeneratorWorkOperation;
|
|
strict private
|
|
procedure GeneratorWorkStart(Sender: TObject; Operation: TGeneratorWorkOperation; MinWorkCount,
|
|
MaxWorkCount: Integer);
|
|
procedure GeneratorWork(Sender: TObject; WorkCount: Integer);
|
|
procedure GeneratorWorkEnd(Sender: TObject);
|
|
public
|
|
property Editor: TInstructionEditor read FEditor write FEditor;
|
|
end;
|
|
|
|
var
|
|
frmGenerator: TfrmGenerator;
|
|
|
|
implementation
|
|
|
|
uses
|
|
untHelperClasses;
|
|
|
|
{$R *.dfm}
|
|
|
|
type
|
|
TGeneratorNodeType = (ntCategory, ntSpacer, ntOperation, ntValue);
|
|
|
|
PGeneratorNodeData = ^TGeneratorNodeData;
|
|
TGeneratorNodeData = record
|
|
public
|
|
NodeType: TGeneratorNodeType;
|
|
Text: String;
|
|
ProgressActive: Boolean;
|
|
ProgressMax: Integer;
|
|
ProgressUpdateStep: Integer;
|
|
Progress: Double;
|
|
Value: String;
|
|
public
|
|
procedure ProgressInit(MaxWorkCount: Integer; MinWorkCount: Integer); inline;
|
|
procedure ProgressUpdate(NewProgress: Double); inline;
|
|
procedure WorkCountUpdate(WorkCount: Integer); inline;
|
|
function IsProgressUpdateStep(WorkCount: Integer): Boolean; inline;
|
|
end;
|
|
|
|
{ TGeneratorNodeData }
|
|
|
|
function TGeneratorNodeData.IsProgressUpdateStep(WorkCount: Integer): Boolean;
|
|
begin
|
|
Assert(NodeType = ntOperation);
|
|
Result := ((WorkCount mod ProgressUpdateStep) = 0);
|
|
end;
|
|
|
|
procedure TGeneratorNodeData.ProgressInit(MaxWorkCount, MinWorkCount: Integer);
|
|
begin
|
|
Assert(NodeType = ntOperation);
|
|
ProgressMax := (MaxWorkCount - MinWorkCount);
|
|
ProgressUpdateStep := Round(ProgressMax / 100) + 1;
|
|
end;
|
|
|
|
procedure TGeneratorNodeData.ProgressUpdate(NewProgress: Double);
|
|
var
|
|
Format: TFormatSettings;
|
|
begin
|
|
Assert(NodeType = ntOperation);
|
|
Progress := NewProgress;
|
|
Format.DecimalSeparator := '.';
|
|
Value := FormatFloat('0.00', Progress * 100, Format) + '%';
|
|
end;
|
|
|
|
procedure TGeneratorNodeData.WorkCountUpdate(WorkCount: Integer);
|
|
begin
|
|
Assert(NodeType = ntOperation);
|
|
if (ProgressMax = 0) then
|
|
begin
|
|
ProgressUpdate(1.0);
|
|
end else
|
|
begin
|
|
ProgressUpdate(WorkCount / ProgressMax);
|
|
end;
|
|
end;
|
|
|
|
{ TfrmGenerator }
|
|
|
|
procedure TfrmGenerator.btnCloseClick(Sender: TObject);
|
|
begin
|
|
Close;
|
|
end;
|
|
|
|
procedure TfrmGenerator.btnGenerateClick(Sender: TObject);
|
|
|
|
procedure SetInfoNodeValue(Node: PVirtualNode; const Value: String);
|
|
var
|
|
NodeData: PGeneratorNodeData;
|
|
begin
|
|
NodeData := TreeView.GetNodeData(Node);
|
|
NodeData^.Value := Value;
|
|
end;
|
|
|
|
var
|
|
Generator: TTableGenerator;
|
|
Node: PVirtualNode;
|
|
NodeData: PGeneratorNodeData;
|
|
I: Integer;
|
|
begin
|
|
TreeView.BeginUpdate;
|
|
try
|
|
for Node in FProgressNode do
|
|
begin
|
|
NodeData := TreeView.GetNodeData(Node);
|
|
NodeData^.ProgressActive := false;
|
|
NodeData^.ProgressUpdate(0);
|
|
end;
|
|
NodeData := TreeView.GetNodeData(FProgressNodeTotal);
|
|
NodeData^.ProgressActive := false;
|
|
NodeData^.ProgressUpdate(0);
|
|
finally
|
|
TreeView.EndUpdate;
|
|
end;
|
|
Generator := TTableGenerator.Create;
|
|
try
|
|
Generator.OnWorkStart := GeneratorWorkStart;
|
|
Generator.OnWork := GeneratorWork;
|
|
Generator.OnWorkEnd := GeneratorWorkEnd;
|
|
Generator.GenerateFiles(FEditor,
|
|
'D:\Verteron Development\GitHub\zyan-disassembler-engine old\include\Zydis\Internal\');
|
|
TreeView.BeginUpdate;
|
|
try
|
|
for I := Low(FInfoNode) to High(FInfoNode) do
|
|
begin
|
|
case I of
|
|
0: SetInfoNodeValue(FInfoNode[I], IntToStr(Generator.Statistics.FilterCount));
|
|
1: SetInfoNodeValue(FInfoNode[I], IntToStr(Generator.Statistics.DefinitionCount));
|
|
2: SetInfoNodeValue(FInfoNode[I], IntToStr(Generator.Statistics.MnemonicCount));
|
|
3: SetInfoNodeValue(FInfoNode[I], TSizeFormatter.Format(Generator.Statistics.FilterSize));
|
|
4: SetInfoNodeValue(FInfoNode[I],
|
|
TSizeFormatter.Format(Generator.Statistics.DefinitionSize));
|
|
5: SetInfoNodeValue(FInfoNode[I],
|
|
TSizeFormatter.Format(Generator.Statistics.MnemonicSize));
|
|
6: SetInfoNodeValue(FInfoNode[I], TSizeFormatter.Format(Generator.Statistics.FilterSize
|
|
+ Generator.Statistics.DefinitionSize + Generator.Statistics.MnemonicSize));
|
|
end;
|
|
end;
|
|
finally
|
|
TreeView.EndUpdate;
|
|
end;
|
|
Application.ProcessMessages;
|
|
finally
|
|
Generator.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmGenerator.FormCreate(Sender: TObject);
|
|
|
|
function AddNodeData(Parent: PVirtualNode; NodeType: TGeneratorNodeType; const Text: String;
|
|
const Value: String = ''): PVirtualNode;
|
|
var
|
|
NodeData: PGeneratorNodeData;
|
|
begin
|
|
Result := TreeView.AddChild(Parent);
|
|
NodeData := TreeView.GetNodeData(Result);
|
|
if (Assigned(NodeData)) then
|
|
begin
|
|
NodeData^.NodeType := NodeType;
|
|
NodeData^.Text := Text;
|
|
case NodeType of
|
|
ntOperation:
|
|
begin
|
|
NodeData^.ProgressActive := false;
|
|
NodeData^.ProgressUpdate(0);
|
|
end;
|
|
ntValue:
|
|
NodeData^.Value := Value;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
var
|
|
Category: PVirtualNode;
|
|
begin
|
|
TreeView.NodeDataSize := SizeOf(TGeneratorNodeData);
|
|
TreeView.BeginUpdate;
|
|
try
|
|
Category := AddNodeData(nil, ntCategory, 'Progress');
|
|
FProgressNode[woIndexingDefinitions] :=
|
|
AddNodeData(Category, ntOperation, 'Indexing definitions');
|
|
FProgressNode[woIndexingFilters] :=
|
|
AddNodeData(Category, ntOperation, 'Indexing filters');
|
|
FProgressNode[woGeneratingFilterFiles] :=
|
|
AddNodeData(Category, ntOperation, 'Generating filter files');
|
|
FProgressNode[woGeneratingDefinitionFiles] :=
|
|
AddNodeData(Category, ntOperation, 'Generating definition files');
|
|
FProgressNode[woGeneratingMnemonicFiles] :=
|
|
AddNodeData(Category, ntOperation, 'Generating mnemonic files');
|
|
FProgressNodeTotal :=
|
|
AddNodeData(Category, ntOperation, 'Total progress');
|
|
TreeView.Expanded[Category] := true;
|
|
AddNodeData(nil, ntSpacer, '');
|
|
Category := AddNodeData(nil, ntCategory, 'Statistics');
|
|
FInfoNode[0] := AddNodeData(Category, ntValue, 'Filter Count', '-');
|
|
FInfoNode[1] := AddNodeData(Category, ntValue, 'Definition Count', '-');
|
|
FInfoNode[2] := AddNodeData(Category, ntValue, 'Mnemonic Count', '-');
|
|
FInfoNode[3] := AddNodeData(Category, ntValue, 'Filter Size', '-');
|
|
FInfoNode[4] := AddNodeData(Category, ntValue, 'Definition Size', '-');
|
|
FInfoNode[5] := AddNodeData(Category, ntValue, 'MnemonicSize', '-');
|
|
FInfoNode[6] := AddNodeData(Category, ntValue, 'TotalSize', '-');
|
|
TreeView.Expanded[Category] := true;
|
|
finally
|
|
TreeView.EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmGenerator.GeneratorWork(Sender: TObject; WorkCount: Integer);
|
|
var
|
|
Node: PVirtualNode;
|
|
NodeData: PGeneratorNodeData;
|
|
ProgressTotal: Double;
|
|
begin
|
|
NodeData := TreeView.GetNodeData(FProgressNode[FCurrentOperation]);
|
|
NodeData^.WorkCountUpdate(WorkCount);
|
|
if (NodeData^.IsProgressUpdateStep(WorkCount)) then
|
|
begin
|
|
TreeView.RepaintNode(FProgressNode[FCurrentOperation]);
|
|
ProgressTotal := 0;
|
|
for Node in FProgressNode do
|
|
begin
|
|
NodeData := TreeView.GetNodeData(Node);
|
|
ProgressTotal := ProgressTotal + NodeData^.Progress;
|
|
end;
|
|
NodeData := TreeView.GetNodeData(FProgressNodeTotal);
|
|
NodeData^.ProgressUpdate(ProgressTotal / Length(FProgressNode));
|
|
TreeView.RepaintNode(FProgressNodeTotal);
|
|
Application.ProcessMessages;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmGenerator.GeneratorWorkEnd(Sender: TObject);
|
|
var
|
|
NodeData: PGeneratorNodeData;
|
|
begin
|
|
NodeData := TreeView.GetNodeData(FProgressNode[FCurrentOperation]);
|
|
NodeData^.ProgressActive := false;
|
|
NodeData^.ProgressUpdate(1);
|
|
TreeView.RepaintNode(FProgressNode[FCurrentOperation]);
|
|
NodeData := TreeView.GetNodeData(FProgressNodeTotal);
|
|
if (FCurrentOperation = High(TGeneratorWorkOperation)) then
|
|
begin
|
|
NodeData^.ProgressActive := false;
|
|
end;
|
|
NodeData^.ProgressUpdate((Integer(FCurrentOperation) + 1) / Length(FProgressNode));
|
|
TreeView.RepaintNode(FProgressNodeTotal);
|
|
end;
|
|
|
|
procedure TfrmGenerator.GeneratorWorkStart(Sender: TObject; Operation: TGeneratorWorkOperation;
|
|
MinWorkCount, MaxWorkCount: Integer);
|
|
var
|
|
NodeData: PGeneratorNodeData;
|
|
begin
|
|
FCurrentOperation := Operation;
|
|
NodeData := TreeView.GetNodeData(FProgressNode[Operation]);
|
|
NodeData^.ProgressInit(MaxWorkCount, MinWorkCount);
|
|
NodeData^.ProgressActive := true;
|
|
TreeView.RepaintNode(FProgressNode[FCurrentOperation]);
|
|
NodeData := TreeView.GetNodeData(FProgressNodeTotal);
|
|
if (FCurrentOperation = Low(TGeneratorWorkOperation)) then
|
|
begin
|
|
NodeData^.ProgressActive := true;
|
|
TreeView.RepaintNode(FProgressNodeTotal);
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmGenerator.TreeViewBeforeCellPaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas;
|
|
Node: PVirtualNode; Column: TColumnIndex; CellPaintMode: TVTCellPaintMode; CellRect: TRect;
|
|
var ContentRect: TRect);
|
|
var
|
|
NodeData: PGeneratorNodeData;
|
|
ProgressWidth: Integer;
|
|
begin
|
|
if (Column = 1) then
|
|
begin
|
|
NodeData := Sender.GetNodeData(Node);
|
|
if (Assigned(NodeData) and (NodeData^.NodeType = ntOperation) and
|
|
(NodeData^.Progress <> 1) and (NodeData^.Progress <> 0)) then
|
|
begin
|
|
TargetCanvas.Pen.Color := $0000A162;
|
|
TargetCanvas.Brush.Color := $0055F2B5;
|
|
TargetCanvas.Rectangle(CellRect.Left, CellRect.Top, CellRect.Right,
|
|
CellRect.Bottom - CellRect.Top);
|
|
TargetCanvas.Pen.Color := $0000A162;
|
|
TargetCanvas.Brush.Color := $000FE18E;
|
|
ProgressWidth := Round(NodeData^.Progress * (CellRect.Right - CellRect.Left));
|
|
TargetCanvas.Rectangle(CellRect.Left, CellRect.Top, CellRect.Left + ProgressWidth,
|
|
CellRect.Bottom - CellRect.Top);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmGenerator.TreeViewCollapsing(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
|
var Allowed: Boolean);
|
|
begin
|
|
Allowed := false;
|
|
end;
|
|
|
|
procedure TfrmGenerator.TreeViewFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
|
|
var
|
|
NodeData: PGeneratorNodeData;
|
|
begin
|
|
NodeData := Sender.GetNodeData(Node);
|
|
if (Assigned(NodeData)) then
|
|
begin
|
|
Finalize(NodeData^);
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmGenerator.TreeViewGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
|
Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean; var ImageIndex: Integer);
|
|
var
|
|
NodeData: PGeneratorNodeData;
|
|
begin
|
|
ImageIndex := -1;
|
|
if (Column = 0) and (Kind in [ikNormal, ikSelected]) then
|
|
begin
|
|
NodeData := Sender.GetNodeData(Node);
|
|
if (Assigned(NodeData)) then
|
|
begin
|
|
case NodeData^.NodeType of
|
|
ntCategory:
|
|
ImageIndex := 0;
|
|
ntOperation:
|
|
begin
|
|
if (NodeData^.ProgressActive) then
|
|
begin
|
|
ImageIndex := 2;
|
|
end else
|
|
begin
|
|
ImageIndex := 1;
|
|
end;
|
|
end;
|
|
ntValue:
|
|
ImageIndex := 3;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TfrmGenerator.TreeViewGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
|
Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
|
|
var
|
|
NodeData: PGeneratorNodeData;
|
|
begin
|
|
CellText := '';
|
|
NodeData := Sender.GetNodeData(Node);
|
|
if (Assigned(NodeData)) then
|
|
begin
|
|
if (NodeData^.NodeType in [ntCategory, ntOperation, ntValue]) then
|
|
begin
|
|
case Column of
|
|
0: CellText := NodeData^.Text;
|
|
1: CellText := NodeData^.Value;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
end.
|