dll.c 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. #include <dll.h>
  2. #include <alloc.h>
  3. #include <vat.h>
  4. #include <string.h>
  5. #include <system.h>
  6. #include <peekpoke.h>
  7. /* These functions are in the same file, so that they
  8. can access their global variables in a pc-relative
  9. fashion. */
  10. __ATTR_LIB_C__ short LoadDLL(const char *DLL_name, long ID, short major, short minor)
  11. {
  12. SYM_ENTRY *entry;
  13. HANDLE h;
  14. unsigned char *bptr,*sptr;
  15. unsigned short len,offset=0,wrongver=0;
  16. unsigned long pc;
  17. unsigned long signature[]={__DLL_SIGNATURE,ID};
  18. asm volatile("bsr 0f; 0:move.l (%%sp)+,%0":"=g"(pc));
  19. if(pc<0x40000) return DLL_NOTINGHOSTSPACE;
  20. if(__DLL_body_ptr) return DLL_ALREADYLOADED;
  21. entry=SymFindFirst(NULL,2);
  22. do
  23. {
  24. if(!strcmp(entry->name,DLL_name)&&entry->handle&&!entry->flags.bits.twin
  25. &&(entry->flags.bits.archived||!HeapGetLock(entry->handle)))
  26. {
  27. len=peek_w(bptr=HeapDeref(entry->handle))+2;
  28. if(!memcmp(bptr+len-5,"DLL\x00\xF8",5))
  29. {
  30. offset=0;
  31. for(sptr=bptr+2;(sptr<bptr+len-1)&&!offset;sptr+=2)
  32. if(!memcmp(sptr,signature,8))
  33. {
  34. if((unsigned short)major!=((__DLL_interface_struct*)sptr)->major
  35. ||(unsigned short)minor>((__DLL_interface_struct*)sptr)->minor)
  36. wrongver=1;
  37. else
  38. offset=sptr-bptr,wrongver=0;
  39. }
  40. if(offset) break;
  41. }
  42. }
  43. } while((entry=SymFindNext()));
  44. if(wrongver) return DLL_WRONGVERSION;
  45. if(!entry) return DLL_NOTFOUND;
  46. if(!HeapLock(h=entry->handle)) return DLL_LOCKFAILED;
  47. if(!(__DLL_body_ptr=malloc(len=peek_w(bptr=HeapDeref(h)+2)+2)))
  48. {
  49. HeapUnlock(h);
  50. return DLL_OUTOFMEM;
  51. }
  52. memcpy(__DLL_body_ptr,bptr,len);
  53. EX_patch((char*)__DLL_body_ptr+0x40000+2,(char*)__DLL_body_ptr+0x40000+len-1);
  54. __DLL_interface_ptr=(__DLL_interface_struct*)((char*)__DLL_body_ptr+offset-2);
  55. HeapUnlock(h);
  56. return DLL_OK;
  57. }
  58. __ATTR_LIB_C__ void UnloadDLL(void)
  59. {
  60. if(!__DLL_body_ptr) return;
  61. free(__DLL_body_ptr);
  62. __DLL_body_ptr=0;
  63. __DLL_interface_ptr=0;
  64. }
  65. __DLL_interface_struct *__DLL_interface_ptr=0;
  66. void *__DLL_body_ptr=0;