/************************************************************************
* gname.cpp *
* generic name class *
* the basic gname class consists of a name and a location, and these *
* are the basic management functions for the class. The class is *
* inherited by names, exports and imports which are all treated very *
* slightly differently. These are essentially the common routines *
* The gname class itself inherits the list class for management of the *
* array of named locations. *
************************************************************************/
#include <windows.h>
#include "gname.h"
#include "disasm.h"
#include "data.h"
#include "debug.h"
#ifdef NEW_GNAME
gnameitem::gnameitem() { name=NULL;}
gnameitem::~gnameitem() {
if (name)
delete name;
}
#endif
/************************************************************************
* gname constructor function *
************************************************************************/
gname::gname() { }
/************************************************************************
* gname destructor function *
* - empty. the deletion of the list is carried out by the list class *
* and by the deletion function *
************************************************************************/
gname::~gname() { }
/************************************************************************
* gname compare function *
* - the compare function for ordering the list of names *
* - the names are kept in location order *
************************************************************************/
int gname::compare(gnameitem *i,gnameitem *j) {
if (i->addr==j->addr) return 0;
if (i->addr>j->addr) return 1;
return -1;
}
/************************************************************************
* gname delete function *
* - overrides the stnadard gnamefunc delete function *
************************************************************************/
#ifndef NEW_GNAME
void gname::delfunc(gnameitem *i) { // delete name.
delete i->name;
// delete gnameitem.
delete i;
}
#endif
/************************************************************************
* addname *
* - this is to add a name to the list of names. *
* - if the address is not covered in our list of segments then we *
* ignore the request *
* - we check that it is ok to name the location before naming it. This *
* basically ensures that names cannot be added in the middle of a *
* disassembled instruction, etc. It should not affect imports/exports *
* since these will be named prior to disassembly *
* - the name is copied and a new string created for it, so the calling *
* function must delete any memory created to hold the name *
* - if the same location is named twice then the first name is deleted *
* - the name is added to the disassembly so that it appears in the *
* listing. *
* - naming a location with "" results in any name being deleted *
************************************************************************/
BOOL gname::addname(lptr loc,char *nm) {
gnameitem *newname,*checkdup;
dsegitem *l_ds;
// check for non-existant address added v2.20
l_ds=dta->findseg(loc);
if (!l_ds) return FALSE;
if (!dsm->oktoname(loc)) return FALSE; // check not in the middle of an instruction.
if (findname(nm)) return FALSE;
newname=new gnameitem;
newname->name=new char[lstrlen(nm)+1];
lstrcpy(newname->name,nm);
demangle(&newname->name);
newname->addr=loc;
checkdup=find(newname);
// just add it once.
if (checkdup) {
if (NamesBox) PostMessage(NamesBox,WM_DELETENAME,0,(LPARAM)checkdup);
if (checkdup->addr==loc) {
delete checkdup->name;
checkdup->name=newname->name;
delete newname;
dsm->delcomment(loc,dsmnameloc);
if (lstrlen(checkdup->name)) {
dsm->discomment(loc,dsmnameloc,(byte *)checkdup->name);
}else{
delfrom(checkdup);
}
return TRUE;
}
}
if (!lstrlen(newname->name)) { // bugfix by Mark Ogden
delete newname->name;
delete newname;
return TRUE;
}
checkdup=addto(newname);
if (NamesBox) PostMessage(NamesBox,WM_ADDNAME,0,(LPARAM)checkdup);
dsm->discomment(loc,dsmnameloc,(byte *)newname->name);
// NB - no need for this anymore. Need to ensure that
// printing of names is done as :
// if names.isname() ...
// else if imports.isname()...
// else if export.isexport()...
// so names aren't printed twice, and import names,etc are retained always
//if(dta.findseg(loc)!=NULL)name.addname(loc,nm);
return TRUE;
}
BOOL gname::findname(LPCTSTR nm) {
// Search for string in the list
gnameitem *i;
resetiterator();
while (i=nextiterator()) {
if (!lstrcmpi(i->name,nm)) return TRUE;
}
return FALSE;
}
/************************************************************************
* isname *
* - returns true if loc has a name *
************************************************************************/
bool gname::isname(lptr loc)
{ gnameitem checkit,*findit;
checkit.addr=loc;
findit=find(&checkit);
if(findit!=NULL)
if(findit->addr==loc)
return true;
return false;
}
/************************************************************************
* isname *
* - prints name to last buffer location in mainwindow buffering array *
* - use with isname, for example: *
* if(name.isname(loc))name.printname(loc); etc *
************************************************************************/
void gname::printname(lptr loc)
{ gnameitem checkit,*findit;
checkit.addr=loc;
findit=find(&checkit);
if(findit!=NULL)
cvd->LastPrintBuff("%s",findit->name);
}
/************************************************************************
* delname *
* - used as a simple name deleter for a given location *
* - also deletes the name from the disassembly listing *
************************************************************************/
void gname::delname(lptr loc)
{ gnameitem dname,*checkdup;
dname.addr=loc;
checkdup=find(&dname);
if(checkdup!=NULL)
if(checkdup->addr==loc)
delfrom(checkdup);
dsm->delcomment(loc,dsmnameloc);
}
/************************************************************************
* getoffsfromname *
* - this checks to see if a name is in the list, and if it is then it *
* returns the offset of its loc otherwise it returns 0. This function *
* is used in generating the segment for imports in an NE file. *
************************************************************************/
dword gname::getoffsfromname(char *nm)
{ gnameitem *t;
resetiterator();
t=nextiterator();
while(t!=NULL)
{ if(!lstrcmp(t->name,nm))
return t->addr.offs;
t=nextiterator();
}
return 0;
}
Vorgefundene Kodierung: ASCII (7 bit) | 2
|