mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-05 05:28:17 +02:00
305 lines
7.9 KiB
ObjectPascal
305 lines
7.9 KiB
ObjectPascal
unit reMainUnit;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
SysUtils, resource, LazUTF8, SynEdit, Forms, Controls, Dialogs, ComCtrls,
|
|
ActnList, Menus, ExtCtrls, Grids, bitmapresource, versionresource,
|
|
groupiconresource, Classes;
|
|
|
|
type
|
|
|
|
{ TreMainForm }
|
|
|
|
TreMainForm = class(TForm)
|
|
fileSave: TAction;
|
|
HeaderControl1: THeaderControl;
|
|
hlpAbout: TAction;
|
|
fileExit: TAction;
|
|
fileOpen: TAction;
|
|
ActionList1: TActionList;
|
|
Image1: TImage;
|
|
ImageList1: TImageList;
|
|
MainMenu1: TMainMenu;
|
|
MenuItem1: TMenuItem;
|
|
MenuItem2: TMenuItem;
|
|
MenuItem3: TMenuItem;
|
|
MenuItem4: TMenuItem;
|
|
MenuItem5: TMenuItem;
|
|
MenuItem6: TMenuItem;
|
|
OpenDialog1: TOpenDialog;
|
|
PageControl1: TPageControl;
|
|
Splitter1: TSplitter;
|
|
StatusBar1: TStatusBar;
|
|
StringGrid1: TStringGrid;
|
|
SynEdit1: TSynEdit;
|
|
tabBinary: TTabSheet;
|
|
tabString: TTabSheet;
|
|
tabImage: TTabSheet;
|
|
ToolBar1: TToolBar;
|
|
ToolButton1: TToolButton;
|
|
ToolButton2: TToolButton;
|
|
ToolButton3: TToolButton;
|
|
ToolButton4: TToolButton;
|
|
TreeView1: TTreeView;
|
|
procedure fileExitExecute(Sender: TObject);
|
|
procedure fileOpenExecute(Sender: TObject);
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure FormDestroy(Sender: TObject);
|
|
procedure HeaderControl1SectionResize(HeaderControl: TCustomHeaderControl;
|
|
Section: THeaderSection);
|
|
procedure hlpAboutExecute(Sender: TObject);
|
|
procedure Splitter1ChangeBounds(Sender: TObject);
|
|
procedure TreeView1SelectionChanged(Sender: TObject);
|
|
private
|
|
Res:TResources;
|
|
procedure ClearDisplay;
|
|
procedure LoadVersionResource(V:TVersionResource);
|
|
procedure LoadBitmapResource(B:TBitmapResource);
|
|
procedure LoadGroupIconResource(G:TGroupIconResource);
|
|
procedure LoadResourceAsBinary(R: TAbstractResource);
|
|
public
|
|
procedure OpenFile(const AFileName:string);
|
|
end;
|
|
|
|
var
|
|
reMainForm: TreMainForm;
|
|
|
|
implementation
|
|
|
|
{$R *.lfm}
|
|
|
|
uses
|
|
winpeimagereader, elfreader, resreader, reAboutUnit, reConstsUnit;
|
|
|
|
{ TreMainForm }
|
|
|
|
procedure TreMainForm.fileExitExecute(Sender: TObject);
|
|
begin
|
|
Close;
|
|
end;
|
|
|
|
procedure TreMainForm.fileOpenExecute(Sender: TObject);
|
|
begin
|
|
if OpenDialog1.Execute then
|
|
OpenFile(UTF8ToSys(OpenDialog1.FileName));
|
|
end;
|
|
|
|
procedure TreMainForm.FormCreate(Sender: TObject);
|
|
begin
|
|
Caption:=sResourceExplorer;
|
|
|
|
fileSave.Caption:=sSaveResource; //'Save resource...'
|
|
hlpAbout.Caption:=sAbout; //'About...'
|
|
fileExit.Caption:=sExit; //'Exit'
|
|
fileOpen.Caption:=sOpen; //'Open...'
|
|
MenuItem1.Caption:=sFile;
|
|
MenuItem2.Caption:=sHelp;
|
|
tabString.Caption:=sStrings;
|
|
tabImage.Caption:=sImage;
|
|
HeaderControl1.Sections[0].Text := sResources;
|
|
|
|
{$IFDEF Windows}
|
|
OpenDialog1.Filter := sAllFilesExcutableFilesExeExeDLLDllDll;
|
|
{$ELSE}
|
|
OpenDialog1.Filter := sAllFilesSharedLibSoSo;
|
|
{$ENDIF}
|
|
Splitter1ChangeBounds(nil);
|
|
SynEdit1.Gutter.Visible := False;
|
|
ClearDisplay;
|
|
end;
|
|
|
|
procedure TreMainForm.FormDestroy(Sender: TObject);
|
|
begin
|
|
if Assigned(Res) then Res.Free;
|
|
end;
|
|
|
|
procedure TreMainForm.HeaderControl1SectionResize(
|
|
HeaderControl: TCustomHeaderControl; Section: THeaderSection);
|
|
begin
|
|
TreeView1.Width:=HeaderControl1.Sections[0].Width;
|
|
HeaderControl1.Sections[1].Width:=Width - TreeView1.Width;
|
|
end;
|
|
|
|
procedure TreMainForm.hlpAboutExecute(Sender: TObject);
|
|
begin
|
|
reAboutForm:=TreAboutForm.Create(Application);
|
|
reAboutForm.ShowModal;
|
|
reAboutForm.Free;
|
|
end;
|
|
|
|
procedure TreMainForm.Splitter1ChangeBounds(Sender: TObject);
|
|
begin
|
|
HeaderControl1.Sections[0].Width:=TreeView1.Width;
|
|
HeaderControl1.Sections[1].Width:=Width - TreeView1.Width;
|
|
end;
|
|
|
|
procedure TreMainForm.TreeView1SelectionChanged(Sender: TObject);
|
|
var
|
|
ResItem:TAbstractResource;
|
|
begin
|
|
if Assigned(TreeView1.Selected) then ClearDisplay;
|
|
if Assigned(TreeView1.Selected) and Assigned(TreeView1.Selected.Data) then
|
|
begin
|
|
ResItem:=TAbstractResource(TreeView1.Selected.Data);
|
|
HeaderControl1.Sections[1].Text:=ResItem.ClassName + ' : ' + ResItem.Name.Name;
|
|
if ResItem is TVersionResource then
|
|
LoadVersionResource(ResItem as TVersionResource)
|
|
else
|
|
if ResItem is TBitmapResource then
|
|
LoadBitmapResource(ResItem as TBitmapResource)
|
|
else
|
|
if ResItem is TGroupIconResource then
|
|
LoadGroupIconResource(ResItem as TGroupIconResource)
|
|
else
|
|
LoadResourceAsBinary(ResItem);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TreMainForm.ClearDisplay;
|
|
begin
|
|
StringGrid1.Clean;
|
|
StringGrid1.Visible := False;
|
|
Image1.Picture.Clear;
|
|
SynEdit1.Lines.Clear;
|
|
end;
|
|
|
|
procedure TreMainForm.LoadVersionResource(V: TVersionResource);
|
|
var
|
|
i,j, k:integer;
|
|
begin
|
|
PageControl1.ActivePage:=tabString;
|
|
StringGrid1.Visible := True;
|
|
k:=0;
|
|
StringGrid1.RowCount:=0;
|
|
StringGrid1.ColCount:=2;
|
|
for i:=0 to V.StringFileInfo.Count-1 do
|
|
begin
|
|
for j:=0 to V.StringFileInfo[i].Count-1 do
|
|
begin
|
|
StringGrid1.RowCount:=StringGrid1.RowCount + 1;
|
|
StringGrid1.Cells[0, k]:=SysToUTF8(V.StringFileInfo[i].Keys[j]);
|
|
StringGrid1.Cells[1, k]:=SysToUTF8(V.StringFileInfo[i].ValuesByIndex[j]);
|
|
inc(k);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TreMainForm.LoadBitmapResource(B: TBitmapResource);
|
|
begin
|
|
PageControl1.ActivePage:=tabImage;
|
|
B.BitmapData.Position:=0;
|
|
Image1.Picture.Bitmap.LoadFromStream(B.BitmapData);
|
|
//
|
|
end;
|
|
|
|
procedure TreMainForm.LoadGroupIconResource(G: TGroupIconResource);
|
|
begin
|
|
//ToDo: implement proper method to display
|
|
LoadResourceAsBinary(G);
|
|
end;
|
|
|
|
procedure TreMainForm.LoadResourceAsBinary(R: TAbstractResource);
|
|
var
|
|
Offset, Size, BytesRead: Int64;
|
|
Buf: Array[0..15] of Byte;
|
|
Line, BinLine, AscLine: ShortString;
|
|
i: Integer;
|
|
begin
|
|
PageControl1.ActivePage:=tabBinary;
|
|
//writeln('TreMainForm.LoadResourceAsBinary');
|
|
//writeln(' ClassName = ',R.ClassName);
|
|
//writeln(' DataSize = ',R.DataSize);
|
|
//writeln(' R.RawData.Size = ',R.RawData.Size);
|
|
//writeln(' DataOffset = ',R.DataOffset);
|
|
//writeln(' DataVersion = ',R.DataVersion);
|
|
SynEdit1.Lines.BeginUpdate;
|
|
try
|
|
Offset := 0;
|
|
R.RawData.Position := 0;
|
|
Size := R.RawData.Size;
|
|
while (Offset < Size) do
|
|
begin
|
|
FillChar(Buf{%H-}, SizeOf(Buf), #0);
|
|
BytesRead := R.RawData.Read(Buf[0], SizeOf(Buf));
|
|
//writeln(' BytesRead = ',BytesRead);
|
|
Line := '';
|
|
BinLine := '';
|
|
Ascline := '';
|
|
for i := 0 to BytesRead - 1 do
|
|
begin
|
|
BinLine := BinLine + IntToHex(Buf[i],2) + #32;
|
|
if (Buf[i] in [32..127]) then
|
|
AscLine := AscLine + Char(Buf[i])
|
|
else
|
|
AscLine := AscLine + #32;
|
|
end;
|
|
for i := (BytesRead + 1) to SizeOf(Buf) do
|
|
begin
|
|
BinLine := BinLine + ' ';
|
|
AscLine := AscLine + ' ';
|
|
end;
|
|
Line := IntToHex(Offset, 8) + #32;
|
|
Line := Line + BinLine + #32 + AscLine + LineEnding;
|
|
//writeln(' Line = ',Line);
|
|
SynEdit1.Lines.Add(Line);
|
|
Inc(Offset, SizeOf(Buf));
|
|
end;
|
|
finally
|
|
SynEdit1.Lines.EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TreMainForm.OpenFile(const AFileName: string);
|
|
var
|
|
Ext:string;
|
|
Reader:TAbstractResourceReader;
|
|
i:integer;
|
|
Root, ResNode:TTreeNode;
|
|
begin
|
|
if not FileExists(AFileName) then exit;
|
|
Ext:=LowerCase(ExtractFileExt(AFileName));
|
|
if (Ext = '.exe') or (Ext = '.dll') then
|
|
Reader:=TWinPEImageResourceReader.Create
|
|
else
|
|
if (Ext = '.res')then
|
|
Reader:=TResResourceReader.Create
|
|
else
|
|
if (Ext = '.o')then
|
|
Reader:=TResResourceReader.Create
|
|
else
|
|
if (Ext = '')then
|
|
Reader:=TElfResourceReader.Create;
|
|
|
|
TreeView1.Items.Clear;
|
|
ClearDisplay;
|
|
if Assigned(Res) then
|
|
FreeAndNil(Res);
|
|
|
|
if not Assigned(Reader) then exit;
|
|
|
|
Res:=TResources.Create;
|
|
try
|
|
Res.LoadFromFile(AFileName, Reader);
|
|
|
|
for i:=0 to Res.Count-1 do
|
|
begin
|
|
Root:=TreeView1.Items.FindTopLvlNode(Res[i].ClassName);
|
|
if not Assigned(Root) then
|
|
Root:=TreeView1.Items.AddChild(nil, Res[i].ClassName);
|
|
ResNode:=TreeView1.Items.AddChild(Root, Res[i].Name.Name);
|
|
ResNode.Data:=Res[i];
|
|
end;
|
|
finally
|
|
Reader.Free;
|
|
end;
|
|
|
|
StatusBar1.SimpleText:=AFileName;
|
|
end;
|
|
|
|
end.
|
|
|