/************************************************************************
* dlg_view.cpp *
* - the functions here are viewers for various lists within Borg, for *
* example exports,imports and xrefs Dialog box viewers, along with *
* any calling functions which stop/start the secondary thread. *
* - Extracted from various classes v2.22 *
* - All routines in here when entered from outside should stop the *
* secondary thread and restart it on exit. *
************************************************************************/
#include <windows.h>
//#include "menuids.rh"
#include "resource.h"
#include "dasm.h"
#include "schedule.h"
#include "xref.h"
#include "range.h"
#include "gname.h"
#include "disio.h"
#include "data.h"
#include "disasm.h"
#include "debug.h"
// standard creation for modeless dialog boxes
// wnd must reference to a global-static HWND
void MyCreateDialog(HWND &wnd, UINT id, DLGPROC dlgproc) {
if (dlgproc) {
if (wnd) SetActiveWindow(wnd);
else wnd=CreateDialog(hInst,MAKEINTRESOURCE(id),MainWnd,dlgproc);
}else if (wnd) DestroyWindow(wnd);
}
// standard processing for modeless dialog boxes
// wnd must reference to a global-static HWND
void MyDefDlgProc(HWND &wnd, HWND w, UINT Msg, WPARAM wParam) {
switch (Msg) {
case WM_ACTIVATE: KBHand=wParam?w:0; break;
case WM_COMMAND: if (LOWORD(wParam)==IDCANCEL) DestroyWindow(w); break;
case WM_DESTROY: wnd=0;
}
}
HWND ExportsBox;
/************************************************************************
* exportsbox *
* - this is the exports viewer dialog box. It is simpler than the names *
* class dialog box, featuring only a jump to option. As for the names *
* class a request is added to the scheduler for any jump and the *
* dialog box exits. the main code is for filling the initial list box *
* and for displaying a new address when the selection is changed *
************************************************************************/
BOOL CALLBACK exportsbox(HWND Wnd,UINT Msg,WPARAM wParam,LPARAM lParam) {
static gnameitem *t;
dword st;
dword i;
MyDefDlgProc(ExportsBox,Wnd,Msg,wParam);
switch (Msg) {
case WM_INITDIALOG: {
HWND w=GetDlgItem(Wnd,IDC_LISTBOX);
expt->resetiterator();
for (i=0;i<expt->numlistitems();i++) {
t=expt->nextiterator();
SendMessage(w,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)t->name);
}
SendMessage(w,LB_SETCURSEL,0,0);
SendMessage(Wnd,WM_COMMAND,MAKELONG(IDC_LISTBOX,LBN_SELCHANGE),(LPARAM)w);
}return TRUE;
case WM_COMMAND: switch (LOWORD(wParam)) {
case IDC_LISTBOX: switch (HIWORD(wParam)) {
case LBN_SELCHANGE: {
TCHAR s[20];
i=SendMessage((HWND)lParam,LB_GETCURSEL,0,0)+1;
expt->resetiterator();
while (i) {
t=expt->nextiterator();
i--;
}
st=t->addr.segm;
wsprintf(s,"0x%lx",st); SetDlgItemText(Wnd,EXPORTS_TEXTSTART,s);
wsprintf(s,"0x%lx",t->addr.offs); SetDlgItemText(Wnd,EXPORTS_TEXTEND,s);
}break;
case LBN_DBLCLK: SendMessage(Wnd,WM_COMMAND,IDOK,0);
}break;
case IDOK: {
scheduler.addtask(user_jumptoaddr,priority_userrequest,t->addr,NULL);
}break;
}
}
return FALSE;
}
/************************************************************************
* exportsviewer *
* - stops the thread and displays the exports viewer dialog. *
************************************************************************/
void exportsviewer(bool state) {
// scheduler.stopthread();
if (state) {
if (!expt->numlistitems()) {
MessageBox(MainWnd,"There are no exports in the list","Borg Message",MB_OK);
}else{
MyCreateDialog(ExportsBox,Exports_Viewer,exportsbox);
}
}else MyCreateDialog(ExportsBox,0,NULL);
// scheduler.continuethread();
}
HWND ImportsBox;
/************************************************************************
* importsbox *
* - this is the imports viewer dialog box, it is similar to the exports *
* and names dialog, although simpler since there is only an ok button *
* Most of the code is for filling the list box and displaying info *
* when an item is selected *
************************************************************************/
BOOL CALLBACK importsbox(HWND Wnd,UINT Msg,WPARAM wParam,LPARAM lParam) {
static gnameitem *t;
dword st;
dword i;
MyDefDlgProc(ImportsBox,Wnd,Msg,wParam);
switch (Msg) {
case WM_INITDIALOG: {
HWND w=GetDlgItem(Wnd,IDC_LISTBOX);
import->resetiterator();
for (i=0;i<import->numlistitems();i++) {
t=import->nextiterator();
SendMessage(w,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)t->name);
}
SendMessage(w,LB_SETCURSEL,0,0);
SendMessage(Wnd,WM_COMMAND,MAKELONG(IDC_LISTBOX,LBN_SELCHANGE),(LPARAM)w);
}return TRUE;
case WM_COMMAND: switch (LOWORD(wParam)) {
case IDC_LISTBOX: switch (HIWORD(wParam)) {
case LBN_SELCHANGE: {
TCHAR s[20];
i=SendMessage((HWND)lParam,LB_GETCURSEL,0,0)+1;
import->resetiterator();
while (i) {
t=import->nextiterator();
i--;
}
st=t->addr.segm;
wsprintf(s,"0x%lx",st); SetDlgItemText(Wnd,IMPORTS_TEXTSTART,s);
wsprintf(s,"0x%lx",t->addr.offs); SetDlgItemText(Wnd,IMPORTS_TEXTEND,s);
}break;
case LBN_DBLCLK: SendMessage(Wnd,WM_COMMAND,IDOK,0);
}break;
case IDOK:
case Xrefs_Viewer: {
xrefsviewer(&t->addr);
}break;
}
}
return FALSE;
}
/************************************************************************
* importsviewer *
* - stops the thread and displays the imports viewer dialog. *
************************************************************************/
void importsviewer(bool state) {
// scheduler.stopthread();
if (state) {
if (!import->numlistitems()) {
MessageBox(MainWnd,"There are no imports in the list","Borg Message",MB_OK);
}else{
MyCreateDialog(ImportsBox,Imports_Viewer,importsbox);
}
}else MyCreateDialog(ImportsBox,0,NULL);
// scheduler.continuethread();
}
/************************************************************************
* getnamebox *
* - this is a small dialog for the input of name for a location. the *
* name is stored (pointer) in the extra parameter from *
* DialogBoxParam *
************************************************************************/
BOOL CALLBACK getnamebox(HWND Wnd,UINT Msg,WPARAM wParam,LPARAM lParam) {
switch (Msg) {
case WM_INITDIALOG: {
SetWindowLong(Wnd,DWL_USER,lParam);
SetDlgItemText(Wnd,IDC_NAMEEDIT,(LPSTR)lParam);
} return TRUE;
case WM_COMMAND: switch (LOWORD(wParam)) {
case IDOK: {
lParam=GetWindowLong(Wnd,DWL_USER);
GetDlgItemText(Wnd,IDC_NAMEEDIT,(LPSTR)lParam,GNAME_MAXLEN);
}nobreak;
case IDCANCEL: EndDialog(Wnd,wParam);
}
}
return FALSE;
}
HWND NamesBox; // modeless dialog, with dynamic changeable list box
/************************************************************************
* namesbox *
* - the dialog box for the names list. *
* - the list is a simple location order of names, which is the same as *
* the underlying list class ordering *
************************************************************************/
BOOL CALLBACK namesbox(HWND Wnd,UINT Msg,WPARAM wParam,LPARAM lParam) {
static gnameitem *t;
dword st;
dword i;
MyDefDlgProc(NamesBox,Wnd,Msg,wParam);
switch (Msg) {
case WM_INITDIALOG: {
HWND w=GetDlgItem(Wnd,IDC_LISTBOX);
name->resetiterator();
for (i=0;i<name->numlistitems();i++) {
t=name->nextiterator();
WPARAM j=SendMessage(w,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)t->name);
SendMessage(w,LB_SETITEMDATA,j,(LPARAM)t);
}
SendMessage(w,LB_SETCURSEL,0,0);
SendMessage(Wnd,WM_COMMAND,MAKELONG(IDC_LISTBOX,LBN_SELCHANGE),(LPARAM)w);
}return TRUE;
case WM_SETADDR: {
HWND w=GetDlgItem(Wnd,IDC_LISTBOX);
WPARAM k=SendMessage(w,LB_GETCOUNT,0,0);
for (i=0; i<k; i++) { // focus to the address given
gnameitem *j=(gnameitem*)SendMessage(w,LB_GETITEMDATA,i,0);
if (j->addr==*(lptr*)lParam) {
SendMessage(w,LB_SETCURSEL,i,0);
SendMessage(Wnd,WM_COMMAND,MAKELONG(IDC_LISTBOX,LBN_SELCHANGE),(LPARAM)w);
break;
}
}
}break;
case WM_DELETENAME: {
HWND w=GetDlgItem(Wnd,IDC_LISTBOX);
WPARAM k=SendMessage(w,LB_GETCOUNT,0,0);
for (i=0; i<k; i++) { // if already present, delete item
LPARAM j=SendMessage(w,LB_GETITEMDATA,i,0);
if (j==lParam) {
SendMessage(w,LB_DELETESTRING,i,0);
break;
}
}
}break;
case WM_ADDNAME: {
HWND w=GetDlgItem(Wnd,IDC_LISTBOX);
WPARAM j=SendMessage(w,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)((gnameitem*)lParam)->name);
SendMessage(w,LB_SETITEMDATA,j,(LPARAM)(gnameitem*)lParam);
}break;
case WM_COMMAND: switch (LOWORD(wParam)) {
case IDC_LISTBOX: switch (HIWORD(wParam)) {
case LBN_SELCHANGE: {
TCHAR s[20];
i=SendMessage((HWND)lParam,LB_GETCURSEL,0,0);
t=(gnameitem*)SendMessage((HWND)lParam,LB_GETITEMDATA,i,0);
st=t->addr.segm;
wsprintf(s,"0x%lx",st); SetDlgItemText(Wnd,NAMES_TEXTSTART,s);
wsprintf(s,"0x%lx",t->addr.offs); SetDlgItemText(Wnd,NAMES_TEXTEND,s);
}break;
case LBN_DBLCLK: SendMessage(Wnd,WM_COMMAND,IDOK,0); // make a "jump to"
}break;
case NAMES_DELETE: {
name->delname(t->addr);
// scheduler.addtask(user_repeatnameview,priority_userrequest,nlptr,NULL);
}break;
case NAMES_RENAME: {
TCHAR s[20];
lstrcpy(s,t->name);
if (DialogBoxParam(hInst,MAKEINTRESOURCE(Get_Name),Wnd,getnamebox,
(LPARAM)s)==IDOK) {
scheduler.addtask(namecurloc,priority_userrequest,t->addr,s);
}
// scheduler.addtask(user_repeatnameview,priority_userrequest,nlptr,NULL);
}break;
case Xrefs_Viewer: {
xrefsviewer(&t->addr);
}break;
case IDOK: {
scheduler.addtask(user_jumptoaddr,priority_userrequest,t->addr,NULL);
}break;
}
}
return FALSE;
}
/************************************************************************
* namesviewer *
* - this controls the display of the names viewer dialog box. names are *
* viewed in the dialog box in location order. *
************************************************************************/
void namesviewer(const lptr *loc) {
// scheduler.stopthread();
if (loc) {
if (!name->numlistitems()) {
MessageBox(MainWnd,"There are no names in the list","Borg Message",MB_OK);
}else{
MyCreateDialog(NamesBox,Names_Viewer,namesbox);
SendMessage(NamesBox,WM_SETADDR,0,(LPARAM)loc);
}
}else MyCreateDialog(NamesBox,0,NULL);
// scheduler.continuethread();
}
/************************************************************************
* namelocation *
* - this calls the user dialog for a name to be entered for the current *
* location, and names it *
************************************************************************/
void namelocation(void) {
lptr loc;
TCHAR s[20];
// scheduler.stopthread();
s[0]=0;
if (DialogBoxParam(hInst,MAKEINTRESOURCE(Get_Name),MainWnd,getnamebox,
(LPARAM)s)==IDOK) {
cvd->findcurrentaddr(&loc);
scheduler.addtask(namecurloc,priority_userrequest,loc,s);
}
// scheduler.continuethread();
}
/************************************************************************
* blockbox *
* - this is the dialog which just shows the extents of the current *
* block *
************************************************************************/
BOOL CALLBACK blockbox(HWND Wnd,UINT Msg,WPARAM wParam,LPARAM) {
switch (Msg) {
case WM_INITDIALOG: {
TCHAR s[30],*sp;
wsprintf(s,"%04x:%08lxh",blk.top.segm,blk.top.offs);
SetDlgItemText(Wnd,Text_Top,s);
wsprintf(s,"%04x:%08lxh",blk.bottom.segm,blk.bottom.offs);
SetDlgItemText(Wnd,Text_Bottom,s);
if (blk.top==nlptr) sp=T("Top not set");
else if(blk.bottom==nlptr) sp=T("Bottom not set");
else if(blk.top>blk.bottom) sp=T("Range is empty");
else sp=T("Range set");
SetDlgItemText(Wnd,Text_Status,sp);
}return TRUE;
case WM_COMMAND: switch (LOWORD(wParam)) {
case IDOK:
case IDCANCEL: EndDialog(Wnd,wParam);
}
}
return FALSE;
}
/************************************************************************
* blockview *
* - this stops the secondary thread and puts up the dialog box for *
* viewing the extents of the block *
************************************************************************/
void blockview(void)
{ //scheduler.stopthread();
DialogBox(hInst,MAKEINTRESOURCE(Block_Dialog),MainWnd,blockbox);
// scheduler.continuethread();
}
HWND XrefsBox;
/************************************************************************
* dialog box controls and workings - most message processing is *
* standardised across Borg (colorchanges, etc) *
************************************************************************/
BOOL CALLBACK xrefsbox(HWND Wnd,UINT Msg,WPARAM wParam,LPARAM lParam) {
static xrefitem *currentsel,xtmp,*vt;
static int numberofitems;
dword st;
dword i;
MyDefDlgProc(XrefsBox,Wnd,Msg,wParam);
switch (Msg) {
case WM_INITDIALOG: {
}return TRUE;
case WM_SETADDR: { // build the list from address given
HWND w=GetDlgItem(Wnd,IDC_LISTBOX);
TCHAR s[40];
SendMessage(w,LB_RESETCONTENT,0,0);
// cvd->findcurrentaddr(&xtmp.addr);
xtmp.addr=*(lptr*)lParam;
xtmp.refby=nlptr;
xrefs->findnext(&xtmp);
vt=xrefs->nextiterator();
currentsel=vt;
numberofitems=0;
if (vt) {
while (vt->addr==xtmp.addr) {
st=vt->refby.segm;
wsprintf(s,"0x%lx:0x%lx",st,vt->refby.offs);
numberofitems++;
SendMessage(w,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)s);
vt=xrefs->nextiterator();
if (!vt) break;
}
}
SendMessage(w,LB_SETCURSEL,0,0);
name->resetiterator();
for (i=0;i<name->numlistitems();i++) {
gnameitem *t=name->nextiterator();
if (t->addr==*(lptr*)lParam) {
SetDlgItemText(Wnd,102,t->name);
break;
}
}
}break;
case WM_COMMAND: switch (LOWORD(wParam)) {
case IDC_LISTBOX: switch (HIWORD(wParam)) {
case LBN_SELCHANGE: {
i=SendMessage((HWND)lParam,LB_GETCURSEL,0,0)+1;
xrefs->findnext(&xtmp);
while (i) {
vt=xrefs->nextiterator();
i--;
}
currentsel=vt;
}break;
case LBN_DBLCLK: SendMessage(Wnd,WM_COMMAND,IDOK,0); // make a "jump to"
}break;
case NAMES_DELETE: {
scheduler.addtask(user_delxref,priority_userrequest,currentsel->refby,NULL);
scheduler.addtask(windowupdate,priority_window,nlptr,NULL);
// if (numberofitems>1)
// scheduler.addtask(user_repeatxrefview,priority_userrequest,nlptr,NULL);
}break;
case IDOK: {
scheduler.addtask(user_jumptoaddr,priority_userrequest,currentsel->refby,NULL);
}break;
}
}
return FALSE;
}
/************************************************************************
* the xrefs viewer - stops the thread and continues it after *
* displaying the dialog box *
************************************************************************/
void xrefsviewer(const lptr *loc) {
xrefitem *findit,xtmp;
// scheduler.stopthread();
if (loc) {
xtmp.addr=*loc;
xtmp.refby=nlptr;
findit=xrefs->findnext(&xtmp);
if (!findit) {
MessageBox(MainWnd,"Unable to find any xrefs for the location","Borg Message",MB_OK);
}else if (findit->addr!=xtmp.addr) {
MessageBox(MainWnd,"There are no xrefs for the current location in the list","Borg Message",MB_OK);
}else{
MyCreateDialog(XrefsBox,Xrefs_Viewer,xrefsbox);
SendMessage(XrefsBox,WM_SETADDR,0,(LPARAM)loc);
}
}else MyCreateDialog(XrefsBox,0,NULL);
// scheduler.continuethread();
}
HWND SegBox;
/************************************************************************
* segbox *
* - this is the segment viewer dialog box which shows the segments, and *
* details of them as they are clicked on. It allows jumping to the *
* segments as well. Background analysis is halted when calling this *
* particularly because iterators are used, and they there is only one *
* iterator for the segment list *
************************************************************************/
void SetType(HWND Wnd, dsegitem *t) {
TCHAR s[20];
dword st;
wsprintf(s,"0x%lx",t->addr.offs); SetDlgItemText(Wnd,SEG_TEXTSTART,s);
st=t->addr.offs+t->size-1;
wsprintf(s,"0x%lx",st); SetDlgItemText(Wnd,SEG_TEXTEND,s);
wsprintf(s,"0x%lx",t->size); SetDlgItemText(Wnd,SEG_TEXTSIZE,s);
SetDlgItemText(Wnd,SEG_TEXTTYPE,typ2name(t->typ));
SetDlgItemText(Wnd,IDC_SEGNAMETEXT,t->name);
}
BOOL CALLBACK segbox(HWND Wnd,UINT Msg,WPARAM wParam,LPARAM lParam) {
static string *segt;
static dsegitem *t;
dword st;
dword i;
MyDefDlgProc(SegBox,Wnd,Msg,wParam);
switch (Msg) {
case WM_INITDIALOG: {
HWND w=GetDlgItem(Wnd,IDC_LISTBOX);
segt=new string[dta->numlistitems()];
dta->resetiterator();
for (i=0;i<dta->numlistitems();i++) {
segt[i]=new char[20];
t=dta->nextiterator();
st=t->addr.segm;
wsprintf(segt[i],"0x%x",st);
st=t->addr.offs;
wsprintf(segt[i]+lstrlen(segt[i]),":0x%04lx",st);
SendMessage(w,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)segt[i]);
}
SendMessage(w,LB_SETCURSEL,0,0);
SendMessage(Wnd,WM_COMMAND,MAKELONG(IDC_LISTBOX,LBN_SELCHANGE),(LPARAM)w);
}return TRUE;
case WM_COMMAND: switch (LOWORD(wParam)) {
case IDC_LISTBOX: switch (HIWORD(wParam)) {
case LBN_SELCHANGE: {
i=SendMessage((HWND)lParam,LB_GETCURSEL,0,0);
dta->resetiterator();
t=dta->nextiterator();
while(i) {
t=dta->nextiterator();
i--;
}
SetType(Wnd,t);
}break;
case LBN_DBLCLK: SendMessage(Wnd,WM_COMMAND,IDOK,0);
}break;
case IDOK: {
scheduler.addtask(user_jumptoaddr,priority_userrequest,t->addr,NULL);
}break;
}break;
case WM_DESTROY: {
for (i=0;i<dta->numlistitems();i++) {
delete segt[dta->numlistitems()-i-1];
}
delete segt;
}break;
}
return FALSE;
}
/************************************************************************
* segviewer *
* - stops the secondary thread, and calls the dialog box for viewing *
* the segments, then restarts the thread when the dialog box is done. *
************************************************************************/
void segviewer(bool state) {
// scheduler.stopthread();
MyCreateDialog(SegBox,Seg_Viewer,state?segbox:NULL);
// scheduler.continuethread();
}
/************************************************************************
* getcommentbox *
* - this is the small dialog box for getting a comment from the user. *
* - it determines the current address, and obtains a comment, adding it *
* to the database, and deleting any previous comment. *
************************************************************************/
BOOL CALLBACK getcommentbox(HWND Wnd,UINT Msg,WPARAM wParam,LPARAM) {
static lptr loc;
switch (Msg) {
case WM_INITDIALOG: {
// need to get any initial comments and stuff into edit box.
dsmitem titem,*tblock;
cvd->findcurrentaddr(&loc);
titem.addr=loc;
titem.type=dsmnull;
dsm->findnext(&titem);
tblock=dsm->nextiterator();
if (tblock) while(tblock->addr==loc) {
if(tblock->type==dsmcomment) {
SetDlgItemText(Wnd,IDC_COMMENTEDIT,(LPSTR)tblock->tptr);
break;
}
tblock=dsm->nextiterator();
if (!tblock) break;
}
}return TRUE;
case WM_COMMAND: switch (LOWORD(wParam)) {
case IDOK: {
char *newcomment;
newcomment= new char[80];
GetDlgItemText(Wnd,IDC_COMMENTEDIT,newcomment,80);
scheduler.addtask(user_delcomment,priority_userrequest,loc,NULL);
if (lstrlen((char *)newcomment))
scheduler.addtask(user_addcomment,priority_userrequest,loc,newcomment);
}nobreak;
case IDCANCEL: EndDialog(Wnd,wParam);
}
}
return FALSE;
}
/************************************************************************
* getcomment *
* - stops the thread and gets a comment from the user to be added to *
* the disassembly database, and posts a windowupdate request. *
************************************************************************/
void getcomment(void) {
// scheduler.stopthread();
DialogBox(hInst,MAKEINTRESOURCE(Comment_Editor),MainWnd,getcommentbox);
// scheduler.continuethread();
}
Vorgefundene Kodierung: ASCII (7 bit) | 2
|