// DLX Dynamic Loading and eXecution V2.91 // Copyright (c) 1997-1998, Nanosoft, Inc. #include #include #include #include #include "dlx.h" class CDLXImports { protected: char** names; long* weakoff; long* numlocs; long** relocs; long numimports; public: CDLXImports(void* infile, long nums); ~CDLXImports(); void Replace(char* data, char* name, char* placement); void ReplaceWeak(char* data, char* name, char* placement); long CheckEmpty(); }; class CDLX; class CDLXListedLibraries { protected: friend CDLX; CDLX** libslist; long numlibs; public: CDLXListedLibraries(); ~CDLXListedLibraries(); CDLXListedLibraries& operator+=(CDLX* l); CDLXListedLibraries& operator-=(CDLX* l); CDLXListedLibraries& operator-=(CDLXListedLibraries& l); long Exist(CDLX* l); long Allow(hdlx_t toal); void Unload(); void Finalize(); void Increment(); void Decrement(); }; class CDLXSymbolList { protected: char*** tosymbols; hdlx_t* ids; long numdlx; public: CDLXSymbolList(); void AddExports(hdlx_t id, char** tosymbol); long Resolve(CDLXListedLibraries& ils, CDLXImports& ims, char* data); void RemoveExports(hdlx_t id); }; static CDLXSymbolList GlobalSymbols; class CEntryTracker { protected: void** functions; char** names; long numentries; public: CEntryTracker(); ~CEntryTracker(); void AddPoint(char* name, void* function); void AddEntries(char **data); void* GetEntry(char* name); }; class CDLX { public: char* data; long datalen; protected: void (*LibMain)(int); char* name; long linstance; long rinstance; long lt; long libloadpos; CDLXImports* myimps; long derror; dlxiddesc versions; CEntryTracker myentries; CDLXListedLibraries mylibs; public: long FinishLoad(); void FinalPass(); void AddDependancies(CDLXListedLibraries& m); void CDLX::InstanceLoad(); void CDLX::InstanceUnload(); CDLX(char* iname, void* infile); ~CDLX(); operator hdlx_t(); int operator==(char*); int operator++(); int operator--(); int operator!(); void* GetEntry(char* name); }; static void* _DefaultOpen(char* name){return((void*)fopen(name,"rb"));} static void _DefaultClose(void* fl){fclose((FILE*)fl); } static void _DefaultRead(void* d, long l, void* fl){ fread(d,1,l,(FILE*)fl); } static void* _DefaultMalloc(size_t s){return malloc(s);} static void* _DefaultRealloc(void* m, size_t s){return realloc(m,s);} static void _DefaultFree(void* m){free(m);} static char* __dlxerrortbl[]= { "File Error:", "DLX Not In Memory:", "Unresolved External:", "Error Unloading Named Symbols:", "Invalid DLX:", "Illegal Operating System:", "Load Error:" }; static void _DefaultError(long t,char *i){printf("DLX Error!\n%s\n %s\n",__dlxerrortbl[t],i);} static hdlx_t _DefaultGet(char*){ return 0; } void* (*DLXOpenFile)(char*)=_DefaultOpen; void (*DLXCloseFile)(void*)=_DefaultClose; void (*DLXReadFile)(void*,long,void*)=_DefaultRead; void (*DLXError)(long,char*)=_DefaultError; void* (*DLXMalloc)(size_t)=_DefaultMalloc; void (*DLXFree)(void*)=_DefaultFree; void* (*DLXRealloc)(void*,size_t)=_DefaultRealloc; hdlx_t (*DLXGetID)(char*)=_DefaultGet; static CDLX** _dlxlist=(CDLX**)DLXMalloc(0); static long _numdlx=0; // begin of new changes... static CDLXListedLibraries* tofinalize; static CDLX* _DLXLoad(char* name) { strlwr(name); for(long l=0; l<_numdlx; l++) { if(*_dlxlist[l]==name) { return _dlxlist[l]; } } hdlx_t test=DLXGetID(name); if(test!=0) { for(long l=0; l<_numdlx; l++) { if((hdlx_t)*_dlxlist[l]==test) { return _dlxlist[l]; } } } void* me=DLXOpenFile(name); if(me==NULL) { DLXError(0,name); return NULL; } CDLX* ndlx=new CDLX(name,me); DLXCloseFile(me); (*tofinalize)+=ndlx; if(ndlx->FinishLoad()) { (*tofinalize)-=ndlx; DLXError(6,name); return NULL; } _numdlx++; _dlxlist=(CDLX**)DLXRealloc(_dlxlist, sizeof(CDLX**)*_numdlx); _dlxlist[_numdlx-1]=ndlx; return ndlx; } hdlx_t DLXLoad(char* name) { tofinalize=new CDLXListedLibraries; CDLX* myd=_DLXLoad(name); if(myd==NULL) { delete tofinalize; return 0; } hdlx_t mydlx=(hdlx_t)*myd; tofinalize->Finalize(); myd->InstanceLoad(); delete tofinalize; return mydlx; } static void _DLXUnload(CDLX* d) { for(long l=0; l<_numdlx; l++) { if(_dlxlist[l]==d) { delete(_dlxlist[l]); _dlxlist[l]=_dlxlist[_numdlx-1]; _numdlx--; _dlxlist=(CDLX**)DLXRealloc(_dlxlist, sizeof(CDLX**)*_numdlx); return; } } DLXError(1,"(by pointer)"); } void DLXUnload(hdlx_t handle) { for(long l=0; l<_numdlx; l++) { if((hdlx_t)*_dlxlist[l]==handle) { CDLX* tempdlx=_dlxlist[l]; tempdlx->InstanceUnload(); if(!*tempdlx) { CDLXListedLibraries m; tempdlx->AddDependancies(m); m-=tempdlx; _DLXUnload(tempdlx); m.Unload(); } return; } } DLXError(1,"(by number)"); } void DLXUnload(char* name) { strlwr(name); for(long l=0; l<_numdlx; l++) { if(*_dlxlist[l]==name) { CDLX* tempdlx=_dlxlist[l]; tempdlx->InstanceUnload(); if(!*tempdlx) { CDLXListedLibraries m; tempdlx->AddDependancies(m); m-=tempdlx; _DLXUnload(tempdlx); m.Unload(); } return; } } DLXError(1,name); } void DLXImport(char** symbols) { GlobalSymbols.AddExports(0,symbols); } void* DLXGetEntry(hdlx_t target, char* name) { for(long l=0; l<_numdlx; l++) { if((hdlx_t)*_dlxlist[l]==target) { return _dlxlist[l]->GetEntry(name); } } return NULL; } void* DLXGetMemoryBlock(hdlx_t target) { for(long l=0; l<_numdlx; l++) { if((hdlx_t)*_dlxlist[l]==target) { return _dlxlist[l]->data; } } return NULL; } long DLXGetMemoryBlockLength(hdlx_t target) { for(long l=0; l<_numdlx; l++) { if((hdlx_t)*_dlxlist[l]==target) { return _dlxlist[l]->datalen; } } return NULL; } CDLXImports::CDLXImports(void* infile, long nums) { numimports=nums; names=(char**)DLXMalloc(sizeof(char *)*nums); numlocs=(long*)DLXMalloc(sizeof(long)*nums); relocs=(long**)DLXMalloc(sizeof(long*)*nums); weakoff=(long*)DLXMalloc(sizeof(long)*nums); long stlen; for(long l=0; l=lt) LibMain(3); rinstance--; } CDLX::operator hdlx_t() { return( versions.UNID ); } void* CDLX::GetEntry(char* name) { return(myentries.GetEntry(name)); } void CDLX::AddDependancies(CDLXListedLibraries& m) { for(long l=0; lAddDependancies(m); } } void CDLX::InstanceLoad() { CDLXListedLibraries m; AddDependancies(m); m-=this; linstance++; m.Increment(); } void CDLX::InstanceUnload() { if(linstance>0) { CDLXListedLibraries m; AddDependancies(m); m-=this; linstance--; m.Decrement(); } } CEntryTracker::CEntryTracker() { functions=(void **)DLXMalloc(0); names=(char **)DLXMalloc(0); numentries=0; } CEntryTracker::~CEntryTracker() { DLXFree(functions); for(long a=0; aFinalPass(); } long CDLXListedLibraries::Exist(CDLX* l) { for(long l2=0; l20) { DLXUnload((hdlx_t)*_dlxlist[currentdlx]); currentdlx=currentdlx+1; if(currentdlx>=_numdlx) currentdlx=0; } }