Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 2489 $
  9.  
  10.  
  11. DRV_COMPAT   equ  5  ;minimal required drivers version
  12. DRV_CURRENT  equ  6  ;current drivers model version
  13.  
  14. DRV_VERSION equ (DRV_COMPAT shl 16) or DRV_CURRENT
  15. PID_KERNEL  equ 1    ;os_idle thread
  16.  
  17.  
  18.  
  19. align 4
  20. proc get_notify stdcall, p_ev:dword
  21.  
  22. .wait:
  23.         mov     ebx, [current_slot]
  24.         test    dword [ebx+APPDATA.event_mask], EVENT_NOTIFY
  25.         jz      @f
  26.         and     dword [ebx+APPDATA.event_mask], not EVENT_NOTIFY
  27.         mov     edi, [p_ev]
  28.         mov     dword [edi], EV_INTR
  29.         mov     eax, [ebx+APPDATA.event]
  30.         mov     dword [edi+4], eax
  31.         ret
  32. @@:
  33.         call    change_task
  34.         jmp     .wait
  35. endp
  36.  
  37. align 4
  38. proc pci_read32 stdcall, bus:dword, devfn:dword, reg:dword
  39.         push    ebx
  40.         xor     eax, eax
  41.         xor     ebx, ebx
  42.         mov     ah, byte [bus]
  43.         mov     al, 6
  44.         mov     bh, byte [devfn]
  45.         mov     bl, byte [reg]
  46.         call    pci_read_reg
  47.         pop     ebx
  48.         ret
  49. endp
  50.  
  51. align 4
  52. proc pci_read16 stdcall, bus:dword, devfn:dword, reg:dword
  53.         push    ebx
  54.         xor     eax, eax
  55.         xor     ebx, ebx
  56.         mov     ah, byte [bus]
  57.         mov     al, 5
  58.         mov     bh, byte [devfn]
  59.         mov     bl, byte [reg]
  60.         call    pci_read_reg
  61.         pop     ebx
  62.         ret
  63. endp
  64.  
  65. align 4
  66. proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword
  67.         push    ebx
  68.         xor     eax, eax
  69.         xor     ebx, ebx
  70.         mov     ah, byte [bus]
  71.         mov     al, 4
  72.         mov     bh, byte [devfn]
  73.         mov     bl, byte [reg]
  74.         call    pci_read_reg
  75.         pop     ebx
  76.         ret
  77. endp
  78.  
  79. align 4
  80. proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
  81.         push    ebx
  82.         xor     eax, eax
  83.         xor     ebx, ebx
  84.         mov     ah, byte [bus]
  85.         mov     al, 8
  86.         mov     bh, byte [devfn]
  87.         mov     bl, byte [reg]
  88.         mov     ecx, [val]
  89.         call    pci_write_reg
  90.         pop     ebx
  91.         ret
  92. endp
  93.  
  94. align 4
  95. proc pci_write16 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
  96.         push    ebx
  97.         xor     eax, eax
  98.         xor     ebx, ebx
  99.         mov     ah, byte [bus]
  100.         mov     al, 9
  101.         mov     bh, byte [devfn]
  102.         mov     bl, byte [reg]
  103.         mov     ecx, [val]
  104.         call    pci_write_reg
  105.         pop     ebx
  106.         ret
  107. endp
  108.  
  109. align 4
  110. proc pci_write32 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
  111.         push    ebx
  112.         xor     eax, eax
  113.         xor     ebx, ebx
  114.         mov     ah, byte [bus]
  115.         mov     al, 10
  116.         mov     bh, byte [devfn]
  117.         mov     bl, byte [reg]
  118.         mov     ecx, [val]
  119.         call    pci_write_reg
  120.         pop     ebx
  121.         ret
  122. endp
  123.  
  124. handle     equ  IOCTL.handle
  125. io_code    equ  IOCTL.io_code
  126. input      equ  IOCTL.input
  127. inp_size   equ  IOCTL.inp_size
  128. output     equ  IOCTL.output
  129. out_size   equ  IOCTL.out_size
  130.  
  131.  
  132. align 4
  133. proc srv_handler stdcall, ioctl:dword
  134.         mov     esi, [ioctl]
  135.         test    esi, esi
  136.         jz      .err
  137.  
  138.         mov     edi, [esi+handle]
  139.         cmp     [edi+SRV.magic], ' SRV'
  140.         jne     .fail
  141.  
  142.         cmp     [edi+SRV.size], sizeof.SRV
  143.         jne     .fail
  144.  
  145.         stdcall [edi+SRV.srv_proc], esi
  146.         ret
  147. .fail:
  148.         xor     eax, eax
  149.         not     eax
  150.         mov     [esi+output], eax
  151.         mov     [esi+out_size], 4
  152.         ret
  153. .err:
  154.         xor     eax, eax
  155.         not     eax
  156.         ret
  157. endp
  158.  
  159. ; param
  160. ;  ecx= io_control
  161. ;
  162. ; retval
  163. ;  eax= error code
  164.  
  165. align 4
  166. srv_handlerEx:
  167.         cmp     ecx, OS_BASE
  168.         jae     .fail
  169.  
  170.         mov     eax, [ecx+handle]
  171.         cmp     [eax+SRV.magic], ' SRV'
  172.         jne     .fail
  173.  
  174.         cmp     [eax+SRV.size], sizeof.SRV
  175.         jne     .fail
  176.  
  177.         stdcall [eax+SRV.srv_proc], ecx
  178.         ret
  179. .fail:
  180.         or      eax, -1
  181.         ret
  182.  
  183. restore  handle
  184. restore  io_code
  185. restore  input
  186. restore  inp_size
  187. restore  output
  188. restore  out_size
  189.  
  190. align 4
  191. proc get_service stdcall, sz_name:dword
  192.         mov     eax, [sz_name]
  193.         test    eax, eax
  194.         jnz     @F
  195.         ret
  196. @@:
  197.         mov     edx, [srv.fd]
  198. @@:
  199.         cmp     edx, srv.fd-SRV.fd
  200.         je      .not_load
  201.  
  202.         stdcall strncmp, edx, [sz_name], 16
  203.         test    eax, eax
  204.         je      .ok
  205.  
  206.         mov     edx, [edx+SRV.fd]
  207.         jmp     @B
  208. .not_load:
  209.         pop     ebp
  210.         jmp     load_driver
  211. .ok:
  212.         mov     eax, edx
  213.         ret
  214. endp
  215.  
  216. align 4
  217. proc reg_service stdcall, name:dword, handler:dword
  218.  
  219.         push    ebx
  220.  
  221.         xor     eax, eax
  222.  
  223.         cmp     [name], eax
  224.         je      .fail
  225.  
  226.         cmp     [handler], eax
  227.         je      .fail
  228.  
  229.         mov     eax, sizeof.SRV
  230.         call    malloc
  231.         test    eax, eax
  232.         jz      .fail
  233.  
  234.         push    esi
  235.         push    edi
  236.         mov     edi, eax
  237.         mov     esi, [name]
  238.         movsd
  239.         movsd
  240.         movsd
  241.         movsd
  242.         pop     edi
  243.         pop     esi
  244.  
  245.         mov     [eax+SRV.magic], ' SRV'
  246.         mov     [eax+SRV.size], sizeof.SRV
  247.  
  248.         mov     ebx, srv.fd-SRV.fd
  249.         mov     edx, [ebx+SRV.fd]
  250.         mov     [eax+SRV.fd], edx
  251.         mov     [eax+SRV.bk], ebx
  252.         mov     [ebx+SRV.fd], eax
  253.         mov     [edx+SRV.bk], eax
  254.  
  255.         mov     ecx, [handler]
  256.         mov     [eax+SRV.srv_proc], ecx
  257.         pop     ebx
  258.         ret
  259. .fail:
  260.         xor     eax, eax
  261.         pop     ebx
  262.         ret
  263. endp
  264.  
  265. align 4
  266. proc get_proc stdcall, exp:dword, sz_name:dword
  267.  
  268.         mov     edx, [exp]
  269. .next:
  270.         mov     eax, [edx]
  271.         test    eax, eax
  272.         jz      .end
  273.  
  274.         push    edx
  275.         stdcall strncmp, eax, [sz_name], 16
  276.         pop     edx
  277.         test    eax, eax
  278.         jz      .ok
  279.  
  280.         add     edx, 8
  281.         jmp     .next
  282. .ok:
  283.         mov     eax, [edx+4]
  284. .end:
  285.         ret
  286. endp
  287.  
  288. align 4
  289. proc get_coff_sym stdcall, pSym:dword,count:dword, sz_sym:dword
  290.  
  291. @@:
  292.         stdcall strncmp, [pSym], [sz_sym], 8
  293.         test    eax, eax
  294.         jz      .ok
  295.         add     [pSym], 18
  296.         dec     [count]
  297.         jnz     @b
  298.         xor     eax, eax
  299.         ret
  300. .ok:
  301.         mov     eax, [pSym]
  302.         mov     eax, [eax+8]
  303.         ret
  304. endp
  305.  
  306. align 4
  307. proc get_curr_task
  308.         mov     eax, [CURRENT_TASK]
  309.         shl     eax, 8
  310.         ret
  311. endp
  312.  
  313. align 4
  314. proc get_fileinfo stdcall, file_name:dword, info:dword
  315.            locals
  316.              cmd     dd ?
  317.              offset  dd ?
  318.                      dd ?
  319.              count   dd ?
  320.              buff    dd ?
  321.                      db ?
  322.              name    dd ?
  323.            endl
  324.  
  325.         xor     eax, eax
  326.         mov     ebx, [file_name]
  327.         mov     ecx, [info]
  328.  
  329.         mov     [cmd], 5
  330.         mov     [offset], eax
  331.         mov     [offset+4], eax
  332.         mov     [count], eax
  333.         mov     [buff], ecx
  334.         mov     byte [buff+4], al
  335.         mov     [name], ebx
  336.  
  337.         mov     eax, 70
  338.         lea     ebx, [cmd]
  339.         int     0x40
  340.         ret
  341. endp
  342.  
  343. align 4
  344. proc read_file stdcall,file_name:dword, buffer:dword, off:dword,\
  345.                                      bytes:dword
  346.            locals
  347.              cmd     dd ?
  348.              offset  dd ?
  349.                      dd ?
  350.              count   dd ?
  351.              buff    dd ?
  352.                      db ?
  353.              name    dd ?
  354.            endl
  355.  
  356.         xor     eax, eax
  357.         mov     ebx, [file_name]
  358.         mov     ecx, [off]
  359.         mov     edx, [bytes]
  360.         mov     esi, [buffer]
  361.  
  362.         mov     [cmd], eax
  363.         mov     [offset], ecx
  364.         mov     [offset+4], eax
  365.         mov     [count], edx
  366.         mov     [buff], esi
  367.         mov     byte [buff+4], al
  368.         mov     [name], ebx
  369.  
  370.         pushad
  371.         lea     ebx, [cmd]
  372.         call    file_system_lfn
  373.         popad
  374.         ret
  375. endp
  376.  
  377. ; description
  378. ;  allocate kernel memory and loads the specified file
  379. ;
  380. ; param
  381. ;  file_name= full path to file
  382. ;
  383. ; retval
  384. ;  eax= file image in kernel memory
  385. ;  ebx= size of file
  386. ;
  387. ; warging
  388. ;  You mast call kernel_free() to delete each file
  389. ;  loaded by the load_file() function
  390.  
  391. align 4
  392. proc load_file stdcall, file_name:dword
  393.            locals
  394.              attr       dd ?
  395.              flags      dd ?
  396.              cr_time    dd ?
  397.              cr_date    dd ?
  398.              acc_time   dd ?
  399.              acc_date   dd ?
  400.              mod_time   dd ?
  401.              mod_date   dd ?
  402.              file_size  dd ?
  403.  
  404.              file       dd ?
  405.              file2      dd ?
  406.            endl
  407.  
  408.         push    esi
  409.         push    edi
  410.  
  411.         lea     eax, [attr]
  412.         stdcall get_fileinfo, [file_name], eax
  413.         test    eax, eax
  414.         jnz     .fail
  415.  
  416.         mov     eax, [file_size]
  417.         cmp     eax, 1024*1024*16
  418.         ja      .fail
  419.  
  420.         stdcall kernel_alloc, [file_size]
  421.         mov     [file], eax
  422.         test    eax, eax
  423.         jz      .fail
  424.  
  425.         stdcall read_file, [file_name], eax, dword 0, [file_size]
  426.         cmp     ebx, [file_size]
  427.         jne     .cleanup
  428.  
  429.         mov     eax, [file]
  430.         cmp     dword [eax], 0x4B43504B
  431.         jne     .exit
  432.         mov     ebx, [eax+4]
  433.         mov     [file_size], ebx
  434.         stdcall kernel_alloc, ebx
  435.  
  436.         test    eax, eax
  437.         jz      .cleanup
  438.  
  439.         mov     [file2], eax
  440.  
  441.         mov     ecx, unpack_mutex
  442.         call    mutex_lock
  443.  
  444.         stdcall unpack, [file], eax
  445.  
  446.         call    mutex_unlock
  447.  
  448.         stdcall kernel_free, [file]
  449.         mov     eax, [file2]
  450.         mov     ebx, [file_size]
  451. .exit:
  452.         push    eax
  453.         lea     edi, [eax+ebx]    ;cleanup remain space
  454.         mov     ecx, 4096         ;from file end
  455.         and     ebx, 4095
  456.         jz      @f
  457.         sub     ecx, ebx
  458.         xor     eax, eax
  459.         cld
  460.         rep stosb
  461. @@:
  462.         mov     ebx, [file_size]
  463.         pop     eax
  464.         pop     edi
  465.         pop     esi
  466.         ret
  467. .cleanup:
  468.         stdcall kernel_free, [file]
  469. .fail:
  470.         xor     eax, eax
  471.         xor     ebx, ebx
  472.         pop     edi
  473.         pop     esi
  474.         ret
  475. endp
  476.  
  477. uglobal
  478. align 4
  479. unpack_mutex MUTEX
  480. endg
  481.  
  482. align 4
  483. proc get_proc_ex stdcall, proc_name:dword, imports:dword
  484.  
  485. .look_up:
  486.         mov     edx, [imports]
  487.         test    edx, edx
  488.         jz      .end
  489.         mov     edx, [edx]
  490.         test    edx, edx
  491.         jz      .end
  492. .next:
  493.         mov     eax, [edx]
  494.         test    eax, eax
  495.         jz      .next_table
  496.  
  497.         push    edx
  498.         stdcall strncmp, eax, [proc_name], 256
  499.         pop     edx
  500.         test    eax, eax
  501.         jz      .ok
  502.  
  503.         add     edx, 8
  504.         jmp     .next
  505. .next_table:
  506.         add     [imports], 4
  507.         jmp     .look_up
  508. .ok:
  509.         mov     eax, [edx+4]
  510.         ret
  511. .end:
  512.         xor     eax, eax
  513.         ret
  514. endp
  515.  
  516. align 4
  517. proc fix_coff_symbols stdcall uses ebx esi, sec:dword, symbols:dword,\
  518.                       sym_count:dword, strings:dword, imports:dword
  519.            locals
  520.              retval dd ?
  521.            endl
  522.  
  523.         mov     edi, [symbols]
  524.         mov     [retval], 1
  525. .fix:
  526.         movzx   ebx, [edi+COFF_SYM.SectionNumber]
  527.         test    ebx, ebx
  528.         jnz     .internal
  529.         mov     eax, dword [edi+COFF_SYM.Name]
  530.         test    eax, eax
  531.         jnz     @F
  532.  
  533.         mov     edi, [edi+4]
  534.         add     edi, [strings]
  535. @@:
  536.         push    edi
  537.         stdcall get_proc_ex, edi, [imports]
  538.         pop     edi
  539.  
  540.         xor     ebx, ebx
  541.         test    eax, eax
  542.         jnz     @F
  543.  
  544.         mov     esi, msg_unresolved
  545.         call    sys_msg_board_str
  546.         mov     esi, edi
  547.         call    sys_msg_board_str
  548.         mov     esi, msg_CR
  549.         call    sys_msg_board_str
  550.  
  551.         mov     [retval], 0
  552. @@:
  553.         mov     edi, [symbols]
  554.         mov     [edi+COFF_SYM.Value], eax
  555.         jmp     .next
  556. .internal:
  557.         cmp     bx, -1
  558.         je      .next
  559.         cmp     bx, -2
  560.         je      .next
  561.  
  562.         dec     ebx
  563.         shl     ebx, 3
  564.         lea     ebx, [ebx+ebx*4]
  565.         add     ebx, [sec]
  566.  
  567.         mov     eax, [ebx+COFF_SECTION.VirtualAddress]
  568.         add     [edi+COFF_SYM.Value], eax
  569. .next:
  570.         add     edi, sizeof.COFF_SYM
  571.         mov     [symbols], edi
  572.         dec     [sym_count]
  573.         jnz     .fix
  574.         mov     eax, [retval]
  575.         ret
  576. endp
  577.  
  578. align 4
  579. proc fix_coff_relocs stdcall uses ebx esi, coff:dword, sym:dword, \
  580.         delta:dword
  581.            locals
  582.              n_sec     dd ?
  583.            endl
  584.  
  585.         mov     eax, [coff]
  586.         movzx   ebx, [eax+COFF_HEADER.nSections]
  587.         mov     [n_sec], ebx
  588.         lea     esi, [eax+20]
  589. .fix_sec:
  590.         mov     edi, [esi+COFF_SECTION.PtrReloc]
  591.         add     edi, [coff]
  592.  
  593.         movzx   ecx, [esi+COFF_SECTION.NumReloc]
  594.         test    ecx, ecx
  595.         jz      .next
  596. .reloc_loop:
  597.         mov     ebx, [edi+COFF_RELOC.SymIndex]
  598.         add     ebx, ebx
  599.         lea     ebx, [ebx+ebx*8]
  600.         add     ebx, [sym]
  601.  
  602.         mov     edx, [ebx+COFF_SYM.Value]
  603.  
  604.         cmp     [edi+COFF_RELOC.Type], 6
  605.         je      .dir_32
  606.  
  607.         cmp     [edi+COFF_RELOC.Type], 20
  608.         jne     .next_reloc
  609. .rel_32:
  610.         mov     eax, [edi+COFF_RELOC.VirtualAddress]
  611.         add     eax, [esi+COFF_SECTION.VirtualAddress]
  612.         sub     edx, eax
  613.         sub     edx, 4
  614.         jmp     .fix
  615. .dir_32:
  616.         mov     eax, [edi+COFF_RELOC.VirtualAddress]
  617.         add     eax, [esi+COFF_SECTION.VirtualAddress]
  618. .fix:
  619.         add     eax, [delta]
  620.         add     [eax], edx
  621. .next_reloc:
  622.         add     edi, 10
  623.         dec     ecx
  624.         jnz     .reloc_loop
  625. .next:
  626.         add     esi, sizeof.COFF_SECTION
  627.         dec     [n_sec]
  628.         jnz     .fix_sec
  629. .exit:
  630.         ret
  631. endp
  632.  
  633. align 4
  634. proc rebase_coff stdcall uses ebx esi, coff:dword, sym:dword, \
  635.         delta:dword
  636.            locals
  637.              n_sec     dd ?
  638.            endl
  639.  
  640.         mov     eax, [coff]
  641.         movzx   ebx, [eax+COFF_HEADER.nSections]
  642.         mov     [n_sec], ebx
  643.         lea     esi, [eax+20]
  644.         mov     edx, [delta]
  645. .fix_sec:
  646.         mov     edi, [esi+COFF_SECTION.PtrReloc]
  647.         add     edi, [coff]
  648.  
  649.         movzx   ecx, [esi+COFF_SECTION.NumReloc]
  650.         test    ecx, ecx
  651.         jz      .next
  652. .reloc_loop:
  653.         cmp     [edi+COFF_RELOC.Type], 6
  654.         jne     .next_reloc
  655. .dir_32:
  656.         mov     eax, [edi+COFF_RELOC.VirtualAddress]
  657.         add     eax, [esi+COFF_SECTION.VirtualAddress]
  658.         add     [eax+edx], edx
  659. .next_reloc:
  660.         add     edi, 10
  661.         dec     ecx
  662.         jnz     .reloc_loop
  663. .next:
  664.         add     esi, sizeof.COFF_SECTION
  665.         dec     [n_sec]
  666.         jnz     .fix_sec
  667. .exit:
  668.         ret
  669. endp
  670.  
  671. align 4
  672. proc load_driver stdcall, driver_name:dword
  673.            locals
  674.              coff      dd ?
  675.              sym       dd ?
  676.              strings   dd ?
  677.              img_size  dd ?
  678.              img_base  dd ?
  679.              start     dd ?
  680.  
  681.              exports   dd ?   ;fake exports table
  682.                        dd ?
  683.              file_name rb 13+16+4+1      ; '/sys/drivers/<up-to-16-chars>.obj'
  684.            endl
  685.  
  686.         lea     edx, [file_name]
  687.         mov     dword [edx], '/sys'
  688.         mov     dword [edx+4], '/dri'
  689.         mov     dword [edx+8], 'vers'
  690.         mov     byte [edx+12], '/'
  691.         mov     esi, [driver_name]
  692. .redo:
  693.         lea     edx, [file_name]
  694.         lea     edi, [edx+13]
  695.         mov     ecx, 16
  696. @@:
  697.         lodsb
  698.         test    al, al
  699.         jz      @f
  700.         stosb
  701.         loop    @b
  702. @@:
  703.         mov     dword [edi], '.obj'
  704.         mov     byte [edi+4], 0
  705.         stdcall load_file, edx
  706.  
  707.         test    eax, eax
  708.         jz      .exit
  709.  
  710.         mov     [coff], eax
  711.  
  712.         movzx   ecx, [eax+COFF_HEADER.nSections]
  713.         xor     ebx, ebx
  714.  
  715.         lea     edx, [eax+20]
  716. @@:
  717.         add     ebx, [edx+COFF_SECTION.SizeOfRawData]
  718.         add     ebx, 15
  719.         and     ebx, not 15
  720.         add     edx, sizeof.COFF_SECTION
  721.         dec     ecx
  722.         jnz     @B
  723.         mov     [img_size], ebx
  724.  
  725.         stdcall kernel_alloc, ebx
  726.         test    eax, eax
  727.         jz      .fail
  728.         mov     [img_base], eax
  729.  
  730.         mov     edi, eax
  731.         xor     eax, eax
  732.         mov     ecx, [img_size]
  733.         add     ecx, 4095
  734.         and     ecx, not 4095
  735.         shr     ecx, 2
  736.         cld
  737.         rep stosd
  738.  
  739.         mov     edx, [coff]
  740.         movzx   ebx, [edx+COFF_HEADER.nSections]
  741.         mov     edi, [img_base]
  742.         lea     eax, [edx+20]
  743. @@:
  744.         mov     [eax+COFF_SECTION.VirtualAddress], edi
  745.         mov     esi, [eax+COFF_SECTION.PtrRawData]
  746.         test    esi, esi
  747.         jnz     .copy
  748.         add     edi, [eax+COFF_SECTION.SizeOfRawData]
  749.         jmp     .next
  750. .copy:
  751.         add     esi, edx
  752.         mov     ecx, [eax+COFF_SECTION.SizeOfRawData]
  753.         cld
  754.         rep movsb
  755. .next:
  756.         add     edi, 15
  757.         and     edi, not 15
  758.         add     eax, sizeof.COFF_SECTION
  759.         dec     ebx
  760.         jnz     @B
  761.  
  762.         mov     ebx, [edx+COFF_HEADER.pSymTable]
  763.         add     ebx, edx
  764.         mov     [sym], ebx
  765.         mov     ecx, [edx+COFF_HEADER.nSymbols]
  766.         add     ecx, ecx
  767.         lea     ecx, [ecx+ecx*8];ecx*=18 = nSymbols*CSYM_SIZE
  768.         add     ecx, [sym]
  769.         mov     [strings], ecx
  770.  
  771.         lea     ebx, [exports]
  772.         mov     dword [ebx], kernel_export
  773.         mov     dword [ebx+4], 0
  774.         lea     eax, [edx+20]
  775.  
  776.         stdcall fix_coff_symbols, eax, [sym], [edx+COFF_HEADER.nSymbols], \
  777.                 [strings], ebx
  778.         test    eax, eax
  779.         jz      .link_fail
  780.  
  781.         mov     ebx, [coff]
  782.         stdcall fix_coff_relocs, ebx, [sym], 0
  783.  
  784.         stdcall get_coff_sym, [sym], [ebx+COFF_HEADER.nSymbols], szVersion
  785.         test    eax, eax
  786.         jz      .link_fail
  787.  
  788.         mov     eax, [eax]
  789.         shr     eax, 16
  790.         cmp     eax, DRV_COMPAT
  791.         jb      .ver_fail
  792.  
  793.         cmp     eax, DRV_CURRENT
  794.         ja      .ver_fail
  795.  
  796.         mov     ebx, [coff]
  797.         stdcall get_coff_sym, [sym], [ebx+COFF_HEADER.nSymbols], szSTART
  798.         mov     [start], eax
  799.  
  800.         stdcall kernel_free, [coff]
  801.  
  802.         mov     ebx, [start]
  803.         stdcall ebx, DRV_ENTRY
  804.         test    eax, eax
  805.         jnz     .ok
  806.  
  807.         stdcall kernel_free, [img_base]
  808.         cmp     dword [file_name+13], 'SOUN'
  809.         jnz     @f
  810.         cmp     dword [file_name+17], 'D.ob'
  811.         jnz     @f
  812.         cmp     word [file_name+21], 'j'
  813.         jnz     @f
  814.         mov     esi, aHDA
  815.         jmp     .redo
  816. @@:
  817.         xor     eax, eax
  818.         ret
  819. .ok:
  820.         mov     ebx, [img_base]
  821.         mov     [eax+SRV.base], ebx
  822.         mov     ecx, [start]
  823.         mov     [eax+SRV.entry], ecx
  824.         ret
  825.  
  826. .ver_fail:
  827.         mov     esi, msg_CR
  828.         call    sys_msg_board_str
  829.         mov     esi, [driver_name]
  830.         call    sys_msg_board_str
  831.         mov     esi, msg_CR
  832.         call    sys_msg_board_str
  833.         mov     esi, msg_version
  834.         call    sys_msg_board_str
  835.         mov     esi, msg_www
  836.         call    sys_msg_board_str
  837.         jmp     .cleanup
  838.  
  839. .link_fail:
  840.         mov     esi, msg_module
  841.         call    sys_msg_board_str
  842.         mov     esi, [driver_name]
  843.         call    sys_msg_board_str
  844.         mov     esi, msg_CR
  845.         call    sys_msg_board_str
  846. .cleanup:
  847.         stdcall kernel_free, [img_base]
  848. .fail:
  849.         stdcall kernel_free, [coff]
  850. .exit:
  851.         xor     eax, eax
  852.         ret
  853. endp
  854.  
  855. ; in: edx -> COFF_SECTION struct
  856. ; out: eax = alignment as mask for bits to drop
  857. coff_get_align:
  858. ; Rules:
  859. ; - if alignment is not given, use default = 4K;
  860. ; - if alignment is given and is no more than 4K, use it;
  861. ; - if alignment is more than 4K, revert to 4K.
  862.         push    ecx
  863.         mov     cl, byte [edx+COFF_SECTION.Characteristics+2]
  864.         mov     eax, 1
  865.         shr     cl, 4
  866.         dec     cl
  867.         js      .default
  868.         cmp     cl, 12
  869.         jbe     @f
  870. .default:
  871.         mov     cl, 12
  872. @@:
  873.         shl     eax, cl
  874.         pop     ecx
  875.         dec     eax
  876.         ret
  877.  
  878. align 4
  879. proc load_library stdcall, file_name:dword
  880.            locals
  881.              fullname  rb 260
  882.              fileinfo  rb 40
  883.              coff      dd ?
  884.              img_base  dd ?
  885.            endl
  886.  
  887.         cli
  888.  
  889. ; resolve file name
  890.         mov     ebx, [file_name]
  891.         lea     edi, [fullname+1]
  892.         mov     byte [edi-1], '/'
  893.         stdcall get_full_file_name, edi, 259
  894.         test    al, al
  895.         jz      .fail
  896.  
  897. ; scan for required DLL in list of already loaded for this process,
  898. ; ignore timestamp
  899.         mov     esi, [CURRENT_TASK]
  900.         shl     esi, 8
  901.         lea     edi, [fullname]
  902.         mov     ebx, [esi+SLOT_BASE+APPDATA.dlls_list_ptr]
  903.         test    ebx, ebx
  904.         jz      .not_in_process
  905.         mov     esi, [ebx+HDLL.fd]
  906. .scan_in_process:
  907.         cmp     esi, ebx
  908.         jz      .not_in_process
  909.         mov     eax, [esi+HDLL.parent]
  910.         add     eax, DLLDESCR.name
  911.         stdcall strncmp, eax, edi, -1
  912.         test    eax, eax
  913.         jnz     .next_in_process
  914. ; simple variant: load DLL which is already loaded in this process
  915. ; just increment reference counters and return address of exports table
  916.         inc     [esi+HDLL.refcount]
  917.         mov     ecx, [esi+HDLL.parent]
  918.         inc     [ecx+DLLDESCR.refcount]
  919.         mov     eax, [ecx+DLLDESCR.exports]
  920.         sub     eax, [ecx+DLLDESCR.defaultbase]
  921.         add     eax, [esi+HDLL.base]
  922.         ret
  923. .next_in_process:
  924.         mov     esi, [esi+HDLL.fd]
  925.         jmp     .scan_in_process
  926. .not_in_process:
  927.  
  928. ; scan in full list, compare timestamp
  929.         lea     eax, [fileinfo]
  930.         stdcall get_fileinfo, edi, eax
  931.         test    eax, eax
  932.         jnz     .fail
  933.         mov     esi, [dll_list.fd]
  934. .scan_for_dlls:
  935.         cmp     esi, dll_list
  936.         jz      .load_new
  937.         lea     eax, [esi+DLLDESCR.name]
  938.         stdcall strncmp, eax, edi, -1
  939.         test    eax, eax
  940.         jnz     .continue_scan
  941. .test_prev_dll:
  942.         mov     eax, dword [fileinfo+24]; last modified time
  943.         mov     edx, dword [fileinfo+28]; last modified date
  944.         cmp     dword [esi+DLLDESCR.timestamp], eax
  945.         jnz     .continue_scan
  946.         cmp     dword [esi+DLLDESCR.timestamp+4], edx
  947.         jz      .dll_already_loaded
  948. .continue_scan:
  949.         mov     esi, [esi+DLLDESCR.fd]
  950.         jmp     .scan_for_dlls
  951.  
  952. ; new DLL
  953. .load_new:
  954. ; load file
  955.         stdcall load_file, edi
  956.         test    eax, eax
  957.         jz      .fail
  958.         mov     [coff], eax
  959.         mov     dword [fileinfo+32], ebx
  960.  
  961. ; allocate DLLDESCR struct; size is DLLDESCR.sizeof plus size of DLL name
  962.         mov     esi, edi
  963.         mov     ecx, -1
  964.         xor     eax, eax
  965.         repnz scasb
  966.         not     ecx
  967.         lea     eax, [ecx+sizeof.DLLDESCR]
  968.         push    ecx
  969.         call    malloc
  970.         pop     ecx
  971.         test    eax, eax
  972.         jz      .fail_and_free_coff
  973. ; save timestamp
  974.         lea     edi, [eax+DLLDESCR.name]
  975.         rep movsb
  976.         mov     esi, eax
  977.         mov     eax, dword [fileinfo+24]
  978.         mov     dword [esi+DLLDESCR.timestamp], eax
  979.         mov     eax, dword [fileinfo+28]
  980.         mov     dword [esi+DLLDESCR.timestamp+4], eax
  981. ; initialize DLLDESCR struct
  982.         and     dword [esi+DLLDESCR.refcount], 0; no HDLLs yet; later it will be incremented
  983.         mov     [esi+DLLDESCR.fd], dll_list
  984.         mov     eax, [dll_list.bk]
  985.         mov     [dll_list.bk], esi
  986.         mov     [esi+DLLDESCR.bk], eax
  987.         mov     [eax+DLLDESCR.fd], esi
  988.  
  989. ; calculate size of loaded DLL
  990.         mov     edx, [coff]
  991.         movzx   ecx, [edx+COFF_HEADER.nSections]
  992.         xor     ebx, ebx
  993.  
  994.         add     edx, 20
  995. @@:
  996.         call    coff_get_align
  997.         add     ebx, eax
  998.         not     eax
  999.         and     ebx, eax
  1000.         add     ebx, [edx+COFF_SECTION.SizeOfRawData]
  1001.         add     edx, sizeof.COFF_SECTION
  1002.         dec     ecx
  1003.         jnz     @B
  1004. ; it must be nonzero and not too big
  1005.         mov     [esi+DLLDESCR.size], ebx
  1006.         test    ebx, ebx
  1007.         jz      .fail_and_free_dll
  1008.         cmp     ebx, MAX_DEFAULT_DLL_ADDR-MIN_DEFAULT_DLL_ADDR
  1009.         ja      .fail_and_free_dll
  1010. ; allocate memory for kernel-side image
  1011.         stdcall kernel_alloc, ebx
  1012.         test    eax, eax
  1013.         jz      .fail_and_free_dll
  1014.         mov     [esi+DLLDESCR.data], eax
  1015. ; calculate preferred base address
  1016.         add     ebx, 0x1FFF
  1017.         and     ebx, not 0xFFF
  1018.         mov     ecx, [dll_cur_addr]
  1019.         lea     edx, [ecx+ebx]
  1020.         cmp     edx, MAX_DEFAULT_DLL_ADDR
  1021.         jb      @f
  1022.         mov     ecx, MIN_DEFAULT_DLL_ADDR
  1023.         lea     edx, [ecx+ebx]
  1024. @@:
  1025.         mov     [esi+DLLDESCR.defaultbase], ecx
  1026.         mov     [dll_cur_addr], edx
  1027.  
  1028. ; copy sections and set correct values for VirtualAddress'es in headers
  1029.         push    esi
  1030.         mov     edx, [coff]
  1031.         movzx   ebx, [edx+COFF_HEADER.nSections]
  1032.         mov     edi, eax
  1033.         add     edx, 20
  1034.         cld
  1035. @@:
  1036.         call    coff_get_align
  1037.         add     ecx, eax
  1038.         add     edi, eax
  1039.         not     eax
  1040.         and     ecx, eax
  1041.         and     edi, eax
  1042.         mov     [edx+COFF_SECTION.VirtualAddress], ecx
  1043.         add     ecx, [edx+COFF_SECTION.SizeOfRawData]
  1044.         mov     esi, [edx+COFF_SECTION.PtrRawData]
  1045.         push    ecx
  1046.         mov     ecx, [edx+COFF_SECTION.SizeOfRawData]
  1047.         test    esi, esi
  1048.         jnz     .copy
  1049.         xor     eax, eax
  1050.         rep stosb
  1051.         jmp     .next
  1052. .copy:
  1053.         add     esi, [coff]
  1054.         rep movsb
  1055. .next:
  1056.         pop     ecx
  1057.         add     edx, sizeof.COFF_SECTION
  1058.         dec     ebx
  1059.         jnz     @B
  1060.         pop     esi
  1061.  
  1062. ; save some additional data from COFF file
  1063. ; later we will use COFF header, headers for sections and symbol table
  1064. ; and also relocations table for all sections
  1065.         mov     edx, [coff]
  1066.         mov     ebx, [edx+COFF_HEADER.pSymTable]
  1067.         mov     edi, dword [fileinfo+32]
  1068.         sub     edi, ebx
  1069.         jc      .fail_and_free_data
  1070.         mov     [esi+DLLDESCR.symbols_lim], edi
  1071.         add     ebx, edx
  1072.         movzx   ecx, [edx+COFF_HEADER.nSections]
  1073.         lea     ecx, [ecx*5]
  1074.         lea     edi, [edi+ecx*8+20]
  1075.         add     edx, 20
  1076. @@:
  1077.         movzx   eax, [edx+COFF_SECTION.NumReloc]
  1078.         lea     eax, [eax*5]
  1079.         lea     edi, [edi+eax*2]
  1080.         add     edx, sizeof.COFF_SECTION
  1081.         sub     ecx, 5
  1082.         jnz     @b
  1083.         stdcall kernel_alloc, edi
  1084.         test    eax, eax
  1085.         jz      .fail_and_free_data
  1086.         mov     edx, [coff]
  1087.         movzx   ecx, [edx+COFF_HEADER.nSections]
  1088.         lea     ecx, [ecx*5]
  1089.         lea     ecx, [ecx*2+5]
  1090.         mov     [esi+DLLDESCR.coff_hdr], eax
  1091.         push    esi
  1092.         mov     esi, edx
  1093.         mov     edi, eax
  1094.         rep movsd
  1095.         pop     esi
  1096.         mov     [esi+DLLDESCR.symbols_ptr], edi
  1097.         push    esi
  1098.         mov     ecx, [edx+COFF_HEADER.nSymbols]
  1099.         mov     [esi+DLLDESCR.symbols_num], ecx
  1100.         mov     ecx, [esi+DLLDESCR.symbols_lim]
  1101.         mov     esi, ebx
  1102.         rep movsb
  1103.         pop     esi
  1104.         mov     ebx, [esi+DLLDESCR.coff_hdr]
  1105.         push    esi
  1106.         movzx   eax, [edx+COFF_HEADER.nSections]
  1107.         lea     edx, [ebx+20]
  1108. @@:
  1109.         movzx   ecx, [edx+COFF_SECTION.NumReloc]
  1110.         lea     ecx, [ecx*5]
  1111.         mov     esi, [edx+COFF_SECTION.PtrReloc]
  1112.         mov     [edx+COFF_SECTION.PtrReloc], edi
  1113.         sub     [edx+COFF_SECTION.PtrReloc], ebx
  1114.         add     esi, [coff]
  1115.         shr     ecx, 1
  1116.         rep movsd
  1117.         adc     ecx, ecx
  1118.         rep movsw
  1119.         add     edx, sizeof.COFF_SECTION
  1120.         dec     eax
  1121.         jnz     @b
  1122.         pop     esi
  1123.  
  1124. ; fixup symbols
  1125.         mov     edx, ebx
  1126.         mov     eax, [ebx+COFF_HEADER.nSymbols]
  1127.         add     edx, 20
  1128.         mov     ecx, [esi+DLLDESCR.symbols_num]
  1129.         lea     ecx, [ecx*9]
  1130.         add     ecx, ecx
  1131.         add     ecx, [esi+DLLDESCR.symbols_ptr]
  1132.  
  1133.         stdcall fix_coff_symbols, edx, [esi+DLLDESCR.symbols_ptr], eax, \
  1134.                 ecx, 0
  1135. ;          test eax, eax
  1136. ;          jnz @F
  1137. ;
  1138. ;@@:
  1139.  
  1140.         stdcall get_coff_sym, [esi+DLLDESCR.symbols_ptr], [ebx+COFF_HEADER.nSymbols], szEXPORTS
  1141.         test    eax, eax
  1142.         jnz     @F
  1143.  
  1144.         stdcall get_coff_sym, [esi+DLLDESCR.symbols_ptr], [ebx+COFF_HEADER.nSymbols], sz_EXPORTS
  1145. @@:
  1146.         mov     [esi+DLLDESCR.exports], eax
  1147.  
  1148. ; fix relocs in the hidden copy in kernel memory to default address
  1149. ; it is first fix; usually this will be enough, but second fix
  1150. ; can be necessary if real load address will not equal assumption
  1151.         mov     eax, [esi+DLLDESCR.data]
  1152.         sub     eax, [esi+DLLDESCR.defaultbase]
  1153.         stdcall fix_coff_relocs, ebx, [esi+DLLDESCR.symbols_ptr], eax
  1154.  
  1155.         stdcall kernel_free, [coff]
  1156.  
  1157. .dll_already_loaded:
  1158.         inc     [esi+DLLDESCR.refcount]
  1159.         push    esi
  1160.         call    init_heap
  1161.         pop     esi
  1162.  
  1163.         mov     edi, [esi+DLLDESCR.size]
  1164.         stdcall user_alloc_at, [esi+DLLDESCR.defaultbase], edi
  1165.         test    eax, eax
  1166.         jnz     @f
  1167.         stdcall user_alloc, edi
  1168.         test    eax, eax
  1169.         jz      .fail_and_dereference
  1170. @@:
  1171.         mov     [img_base], eax
  1172.         mov     eax, sizeof.HDLL
  1173.         call    malloc
  1174.         test    eax, eax
  1175.         jz      .fail_and_free_user
  1176.         mov     ebx, [CURRENT_TASK]
  1177.         shl     ebx, 5
  1178.         mov     edx, [CURRENT_TASK+ebx+TASKDATA.pid]
  1179.         mov     [eax+HDLL.pid], edx
  1180.         push    eax
  1181.         call    init_dlls_in_thread
  1182.         pop     ebx
  1183.         test    eax, eax
  1184.         jz      .fail_and_free_user
  1185.         mov     edx, [eax+HDLL.fd]
  1186.         mov     [ebx+HDLL.fd], edx
  1187.         mov     [ebx+HDLL.bk], eax
  1188.         mov     [eax+HDLL.fd], ebx
  1189.         mov     [edx+HDLL.bk], ebx
  1190.         mov     eax, ebx
  1191.         mov     ebx, [img_base]
  1192.         mov     [eax+HDLL.base], ebx
  1193.         mov     [eax+HDLL.size], edi
  1194.         mov     [eax+HDLL.refcount], 1
  1195.         mov     [eax+HDLL.parent], esi
  1196.         mov     edx, ebx
  1197.         shr     edx, 12
  1198.         or      dword [page_tabs+(edx-1)*4], DONT_FREE_BLOCK
  1199. ; copy entries of page table from kernel-side image to usermode
  1200. ; use copy-on-write for user-mode image, so map as readonly
  1201.         xor     edi, edi
  1202.         mov     ecx, [esi+DLLDESCR.data]
  1203.         shr     ecx, 12
  1204. .map_pages_loop:
  1205.         mov     eax, [page_tabs+ecx*4]
  1206.         and     eax, not 0xFFF
  1207.         or      al, PG_USER
  1208.         xchg    eax, [page_tabs+edx*4]
  1209.         test    al, 1
  1210.         jz      @f
  1211.         call    free_page
  1212. @@:
  1213.         invlpg  [ebx+edi]
  1214.         inc     ecx
  1215.         inc     edx
  1216.         add     edi, 0x1000
  1217.         cmp     edi, [esi+DLLDESCR.size]
  1218.         jb      .map_pages_loop
  1219.  
  1220. ; if real user-mode base is not equal to preferred base, relocate image
  1221.         sub     ebx, [esi+DLLDESCR.defaultbase]
  1222.         jz      @f
  1223.         stdcall rebase_coff, [esi+DLLDESCR.coff_hdr], [esi+DLLDESCR.symbols_ptr], ebx
  1224. @@:
  1225.  
  1226.         mov     eax, [esi+DLLDESCR.exports]
  1227.         sub     eax, [esi+DLLDESCR.defaultbase]
  1228.         add     eax, [img_base]
  1229.         ret
  1230. .fail_and_free_data:
  1231.         stdcall kernel_free, [esi+DLLDESCR.data]
  1232. .fail_and_free_dll:
  1233.         mov     eax, esi
  1234.         call    free
  1235. .fail_and_free_coff:
  1236.         stdcall kernel_free, [coff]
  1237. .fail:
  1238.         xor     eax, eax
  1239.         ret
  1240. .fail_and_free_user:
  1241.         stdcall user_free, [img_base]
  1242. .fail_and_dereference:
  1243.         mov     eax, 1  ; delete 1 reference
  1244.         call    dereference_dll
  1245.         xor     eax, eax
  1246.         ret
  1247. endp
  1248.  
  1249. ; initialize [APPDATA.dlls_list_ptr] for given thread
  1250. ; DLL is per-process object, so APPDATA.dlls_list_ptr must be
  1251. ; kept in sync for all threads of one process.
  1252. ; out: eax = APPDATA.dlls_list_ptr if all is OK,
  1253. ; NULL if memory allocation failed
  1254. init_dlls_in_thread:
  1255.         mov     ebx, [current_slot]
  1256.         mov     eax, [ebx+APPDATA.dlls_list_ptr]
  1257.         test    eax, eax
  1258.         jnz     .ret
  1259.         push    [ebx+APPDATA.dir_table]
  1260.         mov     eax, 8
  1261.         call    malloc
  1262.         pop     edx
  1263.         test    eax, eax
  1264.         jz      .ret
  1265.         mov     [eax], eax
  1266.         mov     [eax+4], eax
  1267.         mov     ecx, [TASK_COUNT]
  1268.         mov     ebx, SLOT_BASE+256
  1269. .set:
  1270.         cmp     [ebx+APPDATA.dir_table], edx
  1271.         jnz     @f
  1272.         mov     [ebx+APPDATA.dlls_list_ptr], eax
  1273. @@:
  1274.         add     ebx, 256
  1275.         dec     ecx
  1276.         jnz     .set
  1277. .ret:
  1278.         ret
  1279.  
  1280. ; in: eax = number of references to delete, esi -> DLLDESCR struc
  1281. dereference_dll:
  1282.         sub     [esi+DLLDESCR.refcount], eax
  1283.         jnz     .ret
  1284.         mov     eax, [esi+DLLDESCR.fd]
  1285.         mov     edx, [esi+DLLDESCR.bk]
  1286.         mov     [eax+DLLDESCR.bk], edx
  1287.         mov     [edx+DLLDESCR.fd], eax
  1288.         stdcall kernel_free, [esi+DLLDESCR.coff_hdr]
  1289.         stdcall kernel_free, [esi+DLLDESCR.data]
  1290.         mov     eax, esi
  1291.         call    free
  1292. .ret:
  1293.         ret
  1294.  
  1295. destroy_hdll:
  1296.         push    ebx ecx esi edi
  1297.         push    eax
  1298.         mov     ebx, [eax+HDLL.base]
  1299.         mov     esi, [eax+HDLL.parent]
  1300.         mov     edx, [esi+DLLDESCR.size]
  1301. ; The following actions require the context of application where HDLL is mapped.
  1302. ; However, destroy_hdll can be called in the context of OS thread when
  1303. ; cleaning up objects created by the application which is destroyed.
  1304. ; So remember current cr3 and set it to page table of target.
  1305.         mov     eax, [ecx+APPDATA.dir_table]
  1306. ; Because we cheat with cr3, disable interrupts: task switch would restore
  1307. ; page table from APPDATA of current thread.
  1308. ; Also set [current_slot] because it is used by user_free.
  1309.         pushf
  1310.         cli
  1311.         push    [current_slot]
  1312.         mov     [current_slot], ecx
  1313.         mov     ecx, cr3
  1314.         push    ecx
  1315.         mov     cr3, eax
  1316.         push    ebx     ; argument for user_free
  1317.         mov     eax, ebx
  1318.         shr     ebx, 12
  1319.         push    ebx
  1320.         mov     esi, [esi+DLLDESCR.data]
  1321.         shr     esi, 12
  1322. .unmap_loop:
  1323.         push    eax
  1324.         mov     eax, 2
  1325.         xchg    eax, [page_tabs+ebx*4]
  1326.         mov     ecx, [page_tabs+esi*4]
  1327.         and     eax, not 0xFFF
  1328.         and     ecx, not 0xFFF
  1329.         cmp     eax, ecx
  1330.         jz      @f
  1331.         call    free_page
  1332. @@:
  1333.         pop     eax
  1334.         invlpg  [eax]
  1335.         add     eax, 0x1000
  1336.         inc     ebx
  1337.         inc     esi
  1338.         sub     edx, 0x1000
  1339.         ja      .unmap_loop
  1340.         pop     ebx
  1341.         and     dword [page_tabs+(ebx-1)*4], not DONT_FREE_BLOCK
  1342.         call    user_free
  1343. ; Restore context.
  1344.         pop     eax
  1345.         mov     cr3, eax
  1346.         pop     [current_slot]
  1347.         popf
  1348. ; Ok, cheating is done.
  1349.         pop     eax
  1350.         push    eax
  1351.         mov     esi, [eax+HDLL.parent]
  1352.         mov     eax, [eax+HDLL.refcount]
  1353.         call    dereference_dll
  1354.         pop     eax
  1355.         mov     edx, [eax+HDLL.bk]
  1356.         mov     ebx, [eax+HDLL.fd]
  1357.         mov     [ebx+HDLL.bk], edx
  1358.         mov     [edx+HDLL.fd], ebx
  1359.         call    free
  1360.         pop     edi esi ecx ebx
  1361.         ret
  1362.  
  1363. ; ecx -> APPDATA for slot, esi = dlls_list_ptr
  1364. destroy_all_hdlls:
  1365.         test    esi, esi
  1366.         jz      .ret
  1367. .loop:
  1368.         mov     eax, [esi+HDLL.fd]
  1369.         cmp     eax, esi
  1370.         jz      free
  1371.         call    destroy_hdll
  1372.         jmp     .loop
  1373. .ret:
  1374.         ret
  1375.  
  1376. align 4
  1377. stop_all_services:
  1378.         push    ebp
  1379.         mov     edx, [srv.fd]
  1380. .next:
  1381.         cmp     edx, srv.fd-SRV.fd
  1382.         je      .done
  1383.         cmp     [edx+SRV.magic], ' SRV'
  1384.         jne     .next
  1385.         cmp     [edx+SRV.size], sizeof.SRV
  1386.         jne     .next
  1387.  
  1388.         mov     ebx, [edx+SRV.entry]
  1389.         mov     edx, [edx+SRV.fd]
  1390.         test    ebx, ebx
  1391.         jz      .next
  1392.  
  1393.         push    edx
  1394.         mov     ebp, esp
  1395.         push    0
  1396.         push    -1
  1397.         call    ebx
  1398.         mov     esp, ebp
  1399.         pop     edx
  1400.         jmp     .next
  1401. .done:
  1402.         pop     ebp
  1403.         ret
  1404.  
  1405. ; param
  1406. ;  eax= size
  1407. ;  ebx= pid
  1408.  
  1409. align 4
  1410. create_kernel_object:
  1411.  
  1412.         push    ebx
  1413.         call    malloc
  1414.         pop     ebx
  1415.         test    eax, eax
  1416.         jz      .fail
  1417.  
  1418.         mov     ecx, [current_slot]
  1419.         add     ecx, APP_OBJ_OFFSET
  1420.  
  1421.         pushfd
  1422.         cli
  1423.         mov     edx, [ecx+APPOBJ.fd]
  1424.         mov     [eax+APPOBJ.fd], edx
  1425.         mov     [eax+APPOBJ.bk], ecx
  1426.         mov     [eax+APPOBJ.pid], ebx
  1427.  
  1428.         mov     [ecx+APPOBJ.fd], eax
  1429.         mov     [edx+APPOBJ.bk], eax
  1430.         popfd
  1431. .fail:
  1432.         ret
  1433.  
  1434. ; param
  1435. ;  eax= object
  1436.  
  1437. align 4
  1438. destroy_kernel_object:
  1439.  
  1440.         pushfd
  1441.         cli
  1442.         mov     ebx, [eax+APPOBJ.fd]
  1443.         mov     ecx, [eax+APPOBJ.bk]
  1444.         mov     [ebx+APPOBJ.bk], ecx
  1445.         mov     [ecx+APPOBJ.fd], ebx
  1446.         popfd
  1447.  
  1448.         xor     edx, edx       ;clear common header
  1449.         mov     [eax], edx
  1450.         mov     [eax+4], edx
  1451.         mov     [eax+8], edx
  1452.         mov     [eax+12], edx
  1453.         mov     [eax+16], edx
  1454.  
  1455.         call    free           ;release object memory
  1456.         ret
  1457.