Add some rudimentary sort to the structure compare window

This commit is contained in:
Dark Byte 2019-01-11 14:31:58 +01:00
parent 029a9b7f26
commit 1ff8f69a7f
3 changed files with 174 additions and 69 deletions

View File

@ -409,14 +409,14 @@ begin
if TDebugThreadHandler(threadlist[i]).ThreadId=tid then
begin
SuspendThread(TDebugThreadHandler(threadlist[i]).handle);
break;
exit;
end;
end;
finally
debuggerthread.unlockThreadlist;
end;
end
else
end;
begin
th:=OpenThread(THREAD_SUSPEND_RESUME, false, tid);
@ -457,14 +457,14 @@ begin
if TDebugThreadHandler(threadlist[i]).ThreadId=tid then
begin
ResumeThread(TDebugThreadHandler(threadlist[i]).handle);
break;
exit;
end;
end;
finally
debuggerthread.unlockThreadlist;
end;
end
else
end;
begin
th:=OpenThread(THREAD_SUSPEND_RESUME, false, tid);

View File

@ -1,7 +1,7 @@
object frmStructureCompare: TfrmStructureCompare
Left = 667
Left = 806
Height = 400
Top = 244
Top = 380
Width = 622
AutoSize = True
Caption = 'Structure Compare'
@ -24,7 +24,7 @@ object frmStructureCompare: TfrmStructureCompare
ClientHeight = 380
ClientWidth = 622
TabOrder = 0
object ListView1: TListView
object lvResults: TListView
Left = 0
Height = 214
Top = 166
@ -38,9 +38,10 @@ object frmStructureCompare: TfrmStructureCompare
RowSelect = True
TabOrder = 0
ViewStyle = vsReport
OnCustomDrawSubItem = ListView1CustomDrawSubItem
OnData = ListView1Data
OnDblClick = ListView1DblClick
OnColumnClick = lvResultsColumnClick
OnCustomDrawSubItem = lvResultsCustomDrawSubItem
OnData = lvResultsData
OnDblClick = lvResultsDblClick
end
object Panel3: TPanel
Left = 0

View File

@ -77,6 +77,7 @@ type
function getDoubleFromAddress(address: ptruint; var error: boolean): double;
function getPointerFromAddress(address: ptruint; var error: boolean): ptruint;
procedure writeRecord(filestream: TfileStream; precord: PPointerRecord); //for sorting
public
vartype: TVariableType;
procedure clearPointerCache;
@ -85,6 +86,10 @@ type
function getStringFromPointerRecord(p: ppointerrecord; address: ptruint; shadow: ptruint; shadowsize: integer): string;
function getStringAndAddress(index: qword; var address: ptruint; out p: PPointerRecord; shadow: ptruint; shadowsize: integer): string;
procedure sort(offsetnr: integer);
procedure CloseFile;
procedure LoadFile(filename: string);
constructor create(filename: string);
destructor destroy; override;
@ -267,7 +272,7 @@ type
lblMaxLevel: TLabel;
lblStructsize: TLabel;
lblvds: TLabel;
ListView1: TListView;
lvResults: TListView;
MainMenu1: TMainMenu;
MenuItem1: TMenuItem;
MenuItem2: TMenuItem;
@ -314,11 +319,12 @@ type
procedure FormDestroy(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure gbNFLClick(Sender: TObject);
procedure ListView1CustomDrawSubItem(Sender: TCustomListView;
procedure lvResultsColumnClick(Sender: TObject; Column: TListColumn);
procedure lvResultsCustomDrawSubItem(Sender: TCustomListView;
Item: TListItem; SubItem: Integer; State: TCustomDrawState;
var DefaultDraw: Boolean);
procedure ListView1Data(Sender: TObject; Item: TListItem);
procedure ListView1DblClick(Sender: TObject);
procedure lvResultsData(Sender: TObject; Item: TListItem);
procedure lvResultsDblClick(Sender: TObject);
procedure miCopyClick(Sender: TObject);
procedure miCutClick(Sender: TObject);
procedure miDeleteAddressClick(Sender: TObject);
@ -489,6 +495,8 @@ var
pos: int64;
begin
if index>fcount then exit(nil);
result:=nil;
@ -644,12 +652,110 @@ begin
end;
end;
constructor TPointerfileReader.create(filename: string);
procedure TPointerfileReader.writeRecord(filestream: TfileStream; precord: PPointerRecord);
begin
filestream.WriteBuffer(precord^,entrysize);
end;
procedure TPointerfileReader.sort(offsetnr: integer); //sorts more on level than on offsetvalues
var
configfile: TFilestream=nil;
results: Array of Tfilestream;
resultcount: integer;
tempfilename: string;
i: qword;
j: integer;
pr: PPointerRecord;
fl: Tstringlist;
s1,s2: string;
begin
if count=0 then exit;
if offsetnr>pointerfilelevelwidth then exit;
tempfilename:=filename+'.sorting';
configfile:=tfilestream.create(tempfilename, fmCreate);
configfile.WriteByte($ec); //HEADER
configfile.WriteByte(compareversion);
configfile.WriteDWord(pointerfileLevelwidth);
configfile.free;
configfile:=nil;
setlength(results,pointerfileLevelwidth);
resultcount:=pointerfileLevelwidth;
for j:=0 to length(results)-1 do
results[j]:=tfilestream.create(tempfilename+'.results.'+inttostr(j+1), fmCreate);
for i:=0 to count-1 do
begin
pr:=getPointerRec(i);
writeRecord(results[pr^.level], pr);
end;
for j:=0 to length(results)-1 do
begin
results[j].free;
results[j]:=nil
end;
setlength(results,0);
closeFile;
fl:=tstringlist.create;
findAllResultFilesForThisPtr(filename,fl);
for j:=0 to fl.Count-1 do
DeleteFile(fl[j]);
DeleteFile(filename);
fl.free;
RenameFile(tempfilename, filename);
for j:=1 to resultcount do
begin
s1:=tempfilename+'.results.'+inttostr(j);
s2:=filename+'.results.'+inttostr(j);
if RenameFile(s1, s2)=false then
OutputDebugString('Failed to rename sorted results');
end;
loadFile(filename);
end;
procedure TPointerFileReader.closeFile;
var i: integer;
begin
if pointerrecords<>nil then
FreeMemAndNil(pointerrecords);
if stringbuf<>nil then
FreeMemAndNil(stringbuf);
widestringbuf:=nil;
if pointermap<>nil then
freeandnil(pointermap);
for i:=0 to length(files)-1 do
begin
if files[i].f<>nil then
freeandnil(files[i].f);
end;
setlength(files,0);
fcount:=0;
entrysize:=0;
end;
procedure TPointerfileReader.LoadFile(filename: string);
var
f: Tstringlist=nil;
configfile: TFilestream=nil;
i,j: integer;
begin
ffilename:=filename;
@ -719,28 +825,18 @@ begin
if configfile<>nil then
freeandnil(configfile);
end;
end;
constructor TPointerfileReader.create(filename: string);
begin
loadFile(filename);
end;
destructor TPointerfileReader.destroy;
var i: integer;
begin
if pointerrecords<>nil then
FreeMemAndNil(pointerrecords);
closefile;
if stringbuf<>nil then
FreeMemAndNil(stringbuf);
if pointermap<>nil then
freeandnil(pointermap);
for i:=0 to length(files)-1 do
begin
if files[i].f<>nil then
freeandnil(files[i].f);
end;
setlength(files,0);
//cleanup the maps
inherited destroy;
@ -1621,8 +1717,14 @@ begin
end;
procedure TfrmStructureCompare.lvResultsColumnClick(Sender: TObject;
Column: TListColumn);
begin
if pointerfilereader<>nil then
pointerfilereader.sort(column.Index);
end;
procedure TfrmStructureCompare.ListView1Data(Sender: TObject; Item: TListItem);
procedure TfrmStructureCompare.lvResultsData(Sender: TObject; Item: TListItem);
var
i: integer;
s,s2: string;
@ -1714,14 +1816,14 @@ begin
end;
end;
procedure TfrmStructureCompare.ListView1DblClick(Sender: TObject);
procedure TfrmStructureCompare.lvResultsDblClick(Sender: TObject);
var
p: tpoint;
i,j: integer;
x: integer;
a: ptruint;
begin
if (listview1.Selected<>nil) and (pointerfilereader<>nil) then
if (lvResults.Selected<>nil) and (pointerfilereader<>nil) then
begin
if edtLF.count>1 then
a:=TAddressEdit(edtLF[0]).address
@ -1733,11 +1835,11 @@ begin
//get the mousecursor
p:=listview1.ScreenToClient(mouse.CursorPos);
p:=lvResults.ScreenToClient(mouse.CursorPos);
x:=0;
for i:=0 to listview1.Columns.Count-1 do
for i:=0 to lvResults.Columns.Count-1 do
begin
if (p.x>x) and (p.x<x+listview1.Column[i].Width) then
if (p.x>x) and (p.x<x+lvResults.Column[i].Width) then
begin
//found the columns
j:=i-pointerfilereader.pointerfileLevelwidth;
@ -1754,9 +1856,9 @@ begin
break;
end;
inc(x, listview1.Column[i].Width);
inc(x, lvResults.Column[i].Width);
end;
MemoryBrowser.hexview.address:=pointerfilereader.getAddressFromPointerRecord(pointerfilereader.getPointerRec(listview1.Selected.Index), a, 0, 0);
MemoryBrowser.hexview.address:=pointerfilereader.getAddressFromPointerRecord(pointerfilereader.getPointerRec(lvResults.Selected.Index), a, 0, 0);
end;
end;
@ -1875,7 +1977,7 @@ begin
listview1.items.count:=min(1000000, pointerfilereader.count);
lvResults.items.count:=min(1000000, pointerfilereader.count);
lblInfo.caption:=inttostr(pointerfilereader.count);
end;
@ -1963,9 +2065,9 @@ begin
freeandnil(scanner);
end;
listview1.items.count:=0;
while listview1.ColumnCount>0 do
listview1.Columns.Delete(0);
lvResults.items.count:=0;
while lvResults.ColumnCount>0 do
lvResults.Columns.Delete(0);
if pointerfilereader<>nil then
freeandnil(pointerfilereader);
@ -2087,7 +2189,7 @@ begin
if pointerfilereader<>nil then
pointerfilereader.hexadecimal:=cbHexadecimal.checked;
listview1.Refresh;
lvResults.Refresh;
end;
procedure TfrmStructureCompare.reloadlistviewcolumns;
@ -2098,22 +2200,22 @@ var
begin
if pointerfilereader=nil then
begin
if listview1.Columns.Count>0 then
listview1.Columns.Clear;
if lvResults.Columns.Count>0 then
lvResults.Columns.Clear;
end
else
begin
nr:=0;
for i:=0 to pointerfilereader.levelWidth-1 do
begin
if listview1.Columns.count<=nr then
if lvResults.Columns.count<=nr then
begin
lc:=listview1.Columns.Add;
lc:=lvResults.Columns.Add;
lc.MinWidth:=2;
lc.Width:=70;
end
else
lc:=listview1.Column[nr];
lc:=lvResults.Column[nr];
lc.Caption:=rsSPSUOffset+inttostr(i);
inc(nr);
@ -2122,14 +2224,14 @@ begin
for i:=0 to edtLF.Count-1 do
begin
if listview1.Columns.count<=nr then
if lvResults.Columns.count<=nr then
begin
lc:=listview1.Columns.Add;
lc:=lvResults.Columns.Add;
lc.MinWidth:=2;
lc.Width:=120;
end
else
lc:=listview1.Column[nr];
lc:=lvResults.Column[nr];
lc.Caption:='G1:'+TAddressEdit(edtLF[i]).Text;
inc(nr);
@ -2137,21 +2239,21 @@ begin
for i:=0 to edtNLF.Count-1 do
begin
if listview1.Columns.count<=nr then
if lvResults.Columns.count<=nr then
begin
lc:=listview1.Columns.Add;
lc:=lvResults.Columns.Add;
lc.MinWidth:=2;
lc.Width:=120;
end
else
lc:=listview1.Column[nr];
lc:=lvResults.Column[nr];
lc.Caption:='G2:'+TAddressEdit(edtNLF[i]).Text;
inc(nr);
end;
while listview1.columns.count>nr do
listview1.Columns.Delete(listview1.columns.count-1);
while lvResults.columns.count>nr do
lvResults.Columns.Delete(lvResults.columns.count-1);
end;
end;
@ -2159,7 +2261,7 @@ end;
procedure TfrmStructureCompare.AddressEditChange(Sender: TObject);
begin
reloadlistviewcolumns;
listview1.Refresh;
lvResults.Refresh;
end;
procedure TfrmStructureCompare.btnAddAddressClick(Sender: TObject);
@ -2198,7 +2300,7 @@ begin
8: pointerfilereader.vartype:=vtPointer;
end;
listview1.Refresh;
lvResults.Refresh;
end;
end;
@ -2219,15 +2321,15 @@ begin
cs:=frMatchCase in finddialog1.Options;
if not cs then findtext:=uppercase(findtext);
for i:=listview1.ItemIndex+1 to listview1.Items.Count-1 do
for i:=lvResults.ItemIndex+1 to lvResults.Items.Count-1 do
begin
s:=listview1.items[i].SubItems.Text;
s:=lvResults.items[i].SubItems.Text;
if not cs then s:=uppercase(s);
if pos(FindText, s)>0 then
begin
listview1.ItemIndex:=i;
listview1.Items[i].MakeVisible(false);
lvResults.ItemIndex:=i;
lvResults.Items[i].MakeVisible(false);
exit;
end;
end;
@ -2280,7 +2382,9 @@ begin
end;
procedure TfrmStructureCompare.ListView1CustomDrawSubItem(
procedure TfrmStructureCompare.lvResultsCustomDrawSubItem(
Sender: TCustomListView; Item: TListItem; SubItem: Integer;
State: TCustomDrawState; var DefaultDraw: Boolean);
var i: integer;
@ -2350,7 +2454,7 @@ begin
if pointerfilereader<>nil then
pointerfilereader.clearPointerCache;
listview1.Refresh;
lvResults.Refresh;
end;
procedure TfrmStructureCompare.miPasteClick(Sender: TObject);
@ -2406,7 +2510,7 @@ begin
e.tag:=0;
e.ReadOnly:=false;
listview1.Refresh;
lvResults.Refresh;
exit;
end;
@ -2487,7 +2591,7 @@ end;
procedure TfrmStructureCompare.tRefresherTimer(Sender: TObject);
begin
listview1.refresh;
lvResults.refresh;
end;
procedure TfrmStructureCompare.setGUIStateEnabled(state: boolean);