/* ** This file contains the runtime usable DLL functions, like LoadLibrary, GetProcAddress etc. */ #define DEBUG 1 #include #define __DLL_LIB_BUILD #include "dll.h" #include #include #include #include #include #include #include void dllInternalFreeLibrary(int); #define DLLOPENDLLS_MAX 20 static int dllsopened = 0; struct dllOpenedDLL { struct dll_sInstance *inst; int usecount; char name[100]; }; struct dllOpenedDLL dllOpenedDLLs[DLLOPENDLLS_MAX]; //Maybe better use a linked list, but should work for now void dllCleanup() { int i; bug("[DynLink] %s()\n", __PRETTY_FUNCTION__); for(i=0;idllPort=dllport; inst->StackType=DLLSTACK_DEFAULT; bzero(&msg, sizeof(msg)); msg.dllMessageType=DLLMTYPE_Open; msg.dllMessageData.dllOpen.StackType = inst->StackType; msg.Message.mn_ReplyPort = myport; PutMsg(dllport, (struct Message *)&msg); WaitPort(myport); reply=(dll_tMessage *)GetMsg(myport); if (reply) { if(reply->dllMessageData.dllOpen.ErrorCode!=DLLERR_NoError) { DeleteMsgPort(myport); free(inst); return 0L; } //Obligatory symbol exports inst->FindResource = dllGetProcAddress(inst,"dllFindResource"); inst->LoadResource = dllGetProcAddress(inst,"dllLoadResource"); inst->FreeResource = dllGetProcAddress(inst,"dllFreeResource"); if((inst->FindResource==0L)|| (inst->LoadResource==0L)|| (inst->FreeResource==0L)) { DeleteMsgPort(myport); dllOpenedDLLs[i].inst=inst; dllInternalFreeLibrary(i); return 0L; } } else { //FIXME: Must/Can I send a Close message here ?? DeleteMsgPort(myport); free(inst); return 0L; } DeleteMsgPort(myport); dllOpenedDLLs[i].inst=inst; dllOpenedDLLs[i].usecount=1; strcpy(dllOpenedDLLs[i].name,portname); return inst; } void dllFreeLibrary(void *hinst) { int i; bug("[DynLink] %s(0x%p)\n", __PRETTY_FUNCTION__, hinst); for(i=0;idllPort) { PutMsg(inst->dllPort, (struct Message *)&msg); /*WaitPort(myport);*/ while(!(reply=(dll_tMessage *)GetMsg(myport))) { Delay(2); if(FindPort(dllOpenedDLLs[i].name)!=inst->dllPort) break; } } DeleteMsgPort(myport); free(inst); bzero(&dllOpenedDLLs[i],sizeof(dllOpenedDLLs[i])); return; } void *dllGetProcAddress(void *hinst,char *name) { dll_tMessage msg,*reply; struct MsgPort *myport; struct dll_sInstance *inst=(struct dll_sInstance *) hinst; void *sym; bug("[DynLink] %s(0x%p, '%s')\n", __PRETTY_FUNCTION__, hinst, name); if(!hinst) return 0L; if(!(myport=CreateMsgPort())) { return 0L; } bzero(&msg, sizeof(msg)); msg.dllMessageType=DLLMTYPE_SymbolQuery; msg.dllMessageData.dllSymbolQuery.StackType=inst->StackType; msg.dllMessageData.dllSymbolQuery.SymbolName=name; msg.dllMessageData.dllSymbolQuery.SymbolPointer=&sym; msg.Message.mn_ReplyPort = myport; PutMsg(inst->dllPort, (struct Message *)&msg); WaitPort(myport); reply=(dll_tMessage *)GetMsg(myport); DeleteMsgPort(myport); if(reply) return(sym); return 0L; } int dllKillLibrary(char *portname) { dll_tMessage msg,*reply; struct MsgPort *myport; struct MsgPort *dllport; bug("[DynLink] %s('%s')\n", __PRETTY_FUNCTION__, portname); if(!(myport=CreateMsgPort())) exit(0L); //Arghh bzero(&msg, sizeof(msg)); msg.dllMessageType=DLLMTYPE_Kill; msg.Message.mn_ReplyPort = myport; if((dllport=FindPort(portname))) { PutMsg(dllport, (struct Message *)&msg); /*WaitPort(myport);*/ while(!(reply=(dll_tMessage *)GetMsg(myport))) { Delay(2); if(FindPort(portname)!=dllport) break; } } DeleteMsgPort(myport); return (dllport?1:0); }