Subversion Repositories Kolibri OS

Rev

Rev 5690 | Rev 7246 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #ifndef INCLUDE_DLL_H
  2. #define INCLUDE_DLL_H
  3. #print "[include <dll.h>]\n"
  4.  
  5. #ifndef INCLUDE_FILESYSTEM_H
  6. #include "../lib/file_system.h"
  7. #endif
  8.  
  9. #ifdef LANG_RUS
  10.         #define _TEXT_ERROR_ADD "'Žè¨¡ª  ¯à¨ § £à㧪¥ ¡¨¡«¨®â¥ª¨"
  11. #elif LANG_EST
  12.         #define _TEXT_ERROR_ADD "'Viga teegi laadimisel"
  13. #else
  14.         #define _TEXT_ERROR_ADD "'Error while loading library"
  15. #endif
  16.  
  17. char a_libdir[43]  = "/sys/lib/\0";
  18.  
  19. dword GLOBAL_FUNC_LIB = 0;
  20. dword G_FUNC_LOAD = 0;
  21. dword G_FUNC_GET = 0;
  22. dword PATH_LIBRARY_LOADING = "/rd/1/lib/library.obj";
  23.  
  24. :inline void error_init(dword text)
  25. {
  26.         dword TEXT_ERROR = malloc(1024);
  27.         sprintf(TEXT_ERROR, "%s `%s`' -E",_TEXT_ERROR_ADD,text);
  28.         notify(TEXT_ERROR);
  29.         free(TEXT_ERROR);
  30. }
  31.  
  32. // stdcall with 1 parameter
  33. :void dll_Load() {
  34. asm {
  35.         push    ebp
  36.         mov     ebp, esp
  37.         mov     esi, SSDWORD[EBP+8]
  38.                 @next_lib:    
  39.         mov     edx, DSDWORD[ESI]
  40.         or      edx, edx
  41.         jz      exit
  42.         push    esi
  43.         mov     esi, DSDWORD[ESI+4]
  44.         mov     edi, #a_libdir+9
  45.  
  46. @loc01:
  47.         lodsb
  48.         stosb
  49.         or      al, al
  50.         jnz     loc01
  51.  
  52.         mov     eax, 68
  53.         mov     ebx, 19
  54.         mov     ecx, #a_libdir
  55.         int     0x40
  56.         or      eax, eax
  57.         jz      fail
  58.  
  59.         push    edx
  60.         push    eax
  61.         call    dll_Link
  62.  
  63.         push    eax
  64.         mov     eax, DSDWORD[eax]
  65.         cmp     DSDWORD[EAX], '_bil'    // somehow this needs to be reversed..
  66.         pop     eax
  67.         jnz     loc02
  68.  
  69.         push    DSDWORD[EAX+4]
  70.         call    dll_Init
  71. @loc02:
  72.  
  73.         pop     esi
  74.         add     esi, 8
  75.         jmp     next_lib
  76. @exit:
  77.         xor     eax, eax
  78.         leave
  79.         ret     4
  80.        
  81. @fail:        
  82.         add     esp, 4
  83.         xor     eax, eax
  84.         inc     eax
  85.         leave
  86.         ret     4
  87.     }
  88. }
  89.  
  90. //stdcall with 2 parameters
  91. :void dll_Link() {
  92. asm {
  93.         push    ebp
  94.         mov     ebp, esp
  95.         push    eax
  96.         mov     esi, SSDWORD[EBP+12]
  97.         test    esi, esi
  98.         jz      done
  99. @next:        
  100.         lodsd
  101.         test    eax, eax
  102.         jz      done
  103.         push    eax
  104.         push    SSDWORD[EBP+8]
  105.         call    dll_GetProcAddress
  106.         or      eax, eax
  107.         jz      loc03
  108.         mov     DSDWORD[esi-4], eax
  109.         jmp     next
  110. @loc03:
  111.         mov     SSDWORD[esp], 0
  112. @done:
  113.         pop     eax
  114.         leave
  115.         ret     8
  116.     }
  117. }
  118.  
  119.  
  120. //stdcall with 1 parameter
  121. :void dll_Init() {
  122. asm {
  123.         push    ebp
  124.         mov     ebp, esp
  125.         pushad
  126.         mov     eax, #malloc
  127.         mov     ebx, #free;
  128.         mov     ecx, #realloc;
  129.         mov     edx, #dll_Load;
  130.         call    SSDWORD[EBP+8]
  131.         popad
  132.         leave
  133.         ret     4
  134.     }
  135. }
  136.  
  137.  
  138. // stdcall with 2 parameters
  139. :void dll_GetProcAddress(){
  140. asm {
  141.         push    ebp
  142.         mov     ebp, esp
  143.         mov     edx, CSDWORD[EBP+8]
  144.         xor     eax, eax
  145.  
  146. @next:        
  147.         or      edx, edx
  148.         jz      end
  149.         cmp     CSDWORD[edx], 0
  150.         jz      end
  151.  
  152.         push    CSDWORD[EBP+12]
  153.         push    CSDWORD[EDX]
  154.         call    dll_StrCmp
  155.         test    eax, eax
  156.         jz      ok
  157.         add     edx, 8
  158.         jmp     next
  159. @ok:
  160.         mov     eax, DSDWORD[EDX+4]
  161. @end:
  162.         leave
  163.         ret     8
  164.     }
  165. }
  166.  
  167.  
  168. // stdcall with 2 parameters
  169. :void dll_StrCmp() {
  170. asm {
  171.         push    ebp
  172.         mov     ebp, esp
  173.         push    esi
  174.         push    edi
  175.         mov     esi, CSDWORD[EBP+8]
  176.         mov     edi, CSDWORD[EBP+12]
  177.         xor     eax, eax
  178. @label1:
  179.         lodsb
  180.         scasb
  181.         jne     fail
  182.         or      al, al
  183.         jnz     label1
  184.         jmp     label_ok
  185. @fail:
  186.         or      eax, -1
  187. @label_ok:
  188.         pop     edi
  189.         pop     esi
  190.         leave
  191.         ret     8
  192.     }
  193. }
  194.  
  195. :int load_dll2(dword dllname, import_table, byte need_init)
  196. {
  197.    //dword dllentry=0;
  198. // load DLL
  199.         $mov     eax, 68
  200.         $mov     ebx, 19
  201.         ECX=dllname;
  202.         $int     0x40
  203.         $test    eax, eax
  204.         $jz      exit01
  205.  
  206. // initialize import
  207.         $mov     edx,eax
  208.         ESI=import_table;
  209.  
  210. @import_loop01:
  211.         $lodsd
  212.         $test    eax,eax
  213.         $jz      import_done01
  214.         $push    edx
  215. @import_find01:
  216.         $mov     ebx,DSDWORD[EDX]
  217.         $test    ebx, ebx
  218.         $jz      exit01
  219.         $push    eax
  220. @nex101:
  221.         $mov     cl,DSBYTE[EAX];
  222.         $cmp     cl,DSBYTE[EBX];
  223.         $jnz     import_find_next01
  224.         $test    cl,cl
  225.         $jz      import_found01
  226.         $inc     eax
  227.         $inc     ebx
  228.         $jmp     nex101
  229. @import_find_next01:
  230.         $pop     eax
  231.         $add     edx, 8
  232.         $jmp     import_find01
  233. @import_found01:
  234.         $pop     eax
  235.         $mov     eax,DSDWORD[edx+4]
  236.         $mov     DSDWORD[esi-4],eax
  237.         $pop     edx
  238.        
  239.         $jmp     import_loop01
  240. @import_done01:
  241.         IF (need_init) dll_Init (DSDWORD[EDX+4]);
  242.         return 0;
  243. @exit01:
  244.         return -1;
  245. }
  246.  
  247. :byte load_dll(dword dllname, import_table, byte need_init)
  248. {
  249.         if (load_dll2(dllname, import_table, need_init))
  250.         {
  251.                 error_init(dllname);
  252.                 return false;
  253.         }
  254.         return true;
  255. }
  256.  
  257. :struct OBJECT
  258. {
  259.         void load(dword dllname);
  260.         dword get(dword fname);
  261. } library;
  262.  
  263. :void OBJECT::load(dword dllname)
  264. {
  265.         dword tmp;
  266.         IF(!GLOBAL_FUNC_LIB)
  267.         {
  268.                 $mov eax, 68
  269.                 $mov ebx, 19
  270.                 ECX=#PATH_LIBRARY_LOADING;
  271.                 $int 0x40
  272.                 tmp = EAX;
  273.                 GLOBAL_FUNC_LIB = tmp;
  274.                 tmp+=4;
  275.                 G_FUNC_LOAD = DSDWORD[tmp];
  276.                 tmp+=8;
  277.                 G_FUNC_GET = DSDWORD[tmp];
  278.         }
  279.         G_FUNC_LOAD stdcall(dllname);
  280. }
  281.  
  282. :dword OBJECT::get(dword fname)
  283. {
  284.         dword tmp=fname;
  285.         G_FUNC_GET stdcall(tmp);
  286.         return EAX;
  287. }
  288.  
  289. /*
  290. #define INIT_(name) byte init_#name(){object.load(name);
  291. #define IMPORT(name) name = object.get(name);
  292. #define _INIT return 1;}
  293. */
  294.  
  295. #endif