dll.c 2.3 KB

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