Subversion Repositories Kolibri OS

Rev

Rev 3232 | Rev 3555 | 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: 3500 $
  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_protected
  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.         pushad
  442.         mov     ecx, unpack_mutex
  443.         call    mutex_lock
  444.         popad
  445.  
  446.         stdcall unpack, [file], eax
  447.  
  448.         pushad
  449.         mov     ecx, unpack_mutex
  450.         call    mutex_unlock
  451.         popad
  452.  
  453.         stdcall kernel_free, [file]
  454.         mov     eax, [file2]
  455.         mov     ebx, [file_size]
  456. .exit:
  457.         push    eax
  458.         lea     edi, [eax+ebx]    ;cleanup remain space
  459.         mov     ecx, 4096         ;from file end
  460.         and     ebx, 4095
  461.         jz      @f
  462.         sub     ecx, ebx
  463.         xor     eax, eax
  464.         cld
  465.         rep stosb
  466. @@:
  467.         mov     ebx, [file_size]
  468.         pop     eax
  469.         pop     edi
  470.         pop     esi
  471.         ret
  472. .cleanup:
  473.         stdcall kernel_free, [file]
  474. .fail:
  475.         xor     eax, eax
  476.         xor     ebx, ebx
  477.         pop     edi
  478.         pop     esi
  479.         ret
  480. endp
  481.  
  482. uglobal
  483. align 4
  484. unpack_mutex MUTEX
  485. endg
  486.  
  487. align 4
  488. proc get_proc_ex stdcall, proc_name:dword, imports:dword
  489.  
  490. .look_up:
  491.         mov     edx, [imports]
  492.         test    edx, edx
  493.         jz      .end
  494.         mov     edx, [edx]
  495.         test    edx, edx
  496.         jz      .end
  497. .next:
  498.         mov     eax, [edx]
  499.         test    eax, eax
  500.         jz      .next_table
  501.  
  502.         push    edx
  503.         stdcall strncmp, eax, [proc_name], 256
  504.         pop     edx
  505.         test    eax, eax
  506.         jz      .ok
  507.  
  508.         add     edx, 8
  509.         jmp     .next
  510. .next_table:
  511.         add     [imports], 4
  512.         jmp     .look_up
  513. .ok:
  514.         mov     eax, [edx+4]
  515.         ret
  516. .end:
  517.         xor     eax, eax
  518.         ret
  519. endp
  520.  
  521. align 4
  522. proc fix_coff_symbols stdcall uses ebx esi, sec:dword, symbols:dword,\
  523.                       sym_count:dword, strings:dword, imports:dword
  524.            locals
  525.              retval dd ?
  526.            endl
  527.  
  528.         mov     edi, [symbols]
  529.         mov     [retval], 1
  530. .fix:
  531.         movzx   ebx, [edi+COFF_SYM.SectionNumber]
  532.         test    ebx, ebx
  533.         jnz     .internal
  534.         mov     eax, dword [edi+COFF_SYM.Name]
  535.         test    eax, eax
  536.         jnz     @F
  537.  
  538.         mov     edi, [edi+4]
  539.         add     edi, [strings]
  540. @@:
  541.         push    edi
  542.         stdcall get_proc_ex, edi, [imports]
  543.         pop     edi
  544.  
  545.         xor     ebx, ebx
  546.         test    eax, eax
  547.         jnz     @F
  548.  
  549.         mov     esi, msg_unresolved
  550.         call    sys_msg_board_str
  551.         mov     esi, edi
  552.         call    sys_msg_board_str
  553.         mov     esi, msg_CR
  554.         call    sys_msg_board_str
  555.  
  556.         mov     [retval], 0
  557. @@:
  558.         mov     edi, [symbols]
  559.         mov     [edi+COFF_SYM.Value], eax
  560.         jmp     .next
  561. .internal:
  562.         cmp     bx, -1
  563.         je      .next
  564.         cmp     bx, -2
  565.         je      .next
  566.  
  567.         dec     ebx
  568.         shl     ebx, 3
  569.         lea     ebx, [ebx+ebx*4]
  570.         add     ebx, [sec]
  571.  
  572.         mov     eax, [ebx+COFF_SECTION.VirtualAddress]
  573.         add     [edi+COFF_SYM.Value], eax
  574. .next:
  575.         add     edi, sizeof.COFF_SYM
  576.         mov     [symbols], edi
  577.         dec     [sym_count]
  578.         jnz     .fix
  579.         mov     eax, [retval]
  580.         ret
  581. endp
  582.  
  583. align 4
  584. proc fix_coff_relocs stdcall uses ebx esi, coff:dword, sym:dword, \
  585.         delta:dword
  586.            locals
  587.              n_sec     dd ?
  588.            endl
  589.  
  590.         mov     eax, [coff]
  591.         movzx   ebx, [eax+COFF_HEADER.nSections]
  592.         mov     [n_sec], ebx
  593.         lea     esi, [eax+20]
  594. .fix_sec:
  595.         mov     edi, [esi+COFF_SECTION.PtrReloc]
  596.         add     edi, [coff]
  597.  
  598.         movzx   ecx, [esi+COFF_SECTION.NumReloc]
  599.         test    ecx, ecx
  600.         jz      .next
  601. .reloc_loop:
  602.         mov     ebx, [edi+COFF_RELOC.SymIndex]
  603.         add     ebx, ebx
  604.         lea     ebx, [ebx+ebx*8]
  605.         add     ebx, [sym]
  606.  
  607.         mov     edx, [ebx+COFF_SYM.Value]
  608.  
  609.         cmp     [edi+COFF_RELOC.Type], 6
  610.         je      .dir_32
  611.  
  612.         cmp     [edi+COFF_RELOC.Type], 20
  613.         jne     .next_reloc
  614. .rel_32:
  615.         mov     eax, [edi+COFF_RELOC.VirtualAddress]
  616.         add     eax, [esi+COFF_SECTION.VirtualAddress]
  617.         sub     edx, eax
  618.         sub     edx, 4
  619.         jmp     .fix
  620. .dir_32:
  621.         mov     eax, [edi+COFF_RELOC.VirtualAddress]
  622.         add     eax, [esi+COFF_SECTION.VirtualAddress]
  623. .fix:
  624.         add     eax, [delta]
  625.         add     [eax], edx
  626. .next_reloc:
  627.         add     edi, 10
  628.         dec     ecx
  629.         jnz     .reloc_loop
  630. .next:
  631.         add     esi, sizeof.COFF_SECTION
  632.         dec     [n_sec]
  633.         jnz     .fix_sec
  634. .exit:
  635.         ret
  636. endp
  637.  
  638. align 4
  639. proc rebase_coff stdcall uses ebx esi, coff:dword, sym:dword, \
  640.         delta:dword
  641.            locals
  642.              n_sec     dd ?
  643.            endl
  644.  
  645.         mov     eax, [coff]
  646.         movzx   ebx, [eax+COFF_HEADER.nSections]
  647.         mov     [n_sec], ebx
  648.         lea     esi, [eax+20]
  649.         mov     edx, [delta]
  650. .fix_sec:
  651.         mov     edi, [esi+COFF_SECTION.PtrReloc]
  652.         add     edi, [coff]
  653.  
  654.         movzx   ecx, [esi+COFF_SECTION.NumReloc]
  655.         test    ecx, ecx
  656.         jz      .next
  657. .reloc_loop:
  658.         cmp     [edi+COFF_RELOC.Type], 6
  659.         jne     .next_reloc
  660. .dir_32:
  661.         mov     eax, [edi+COFF_RELOC.VirtualAddress]
  662.         add     eax, [esi+COFF_SECTION.VirtualAddress]
  663.         add     [eax+edx], edx
  664. .next_reloc:
  665.         add     edi, 10
  666.         dec     ecx
  667.         jnz     .reloc_loop
  668. .next:
  669.         add     esi, sizeof.COFF_SECTION
  670.         dec     [n_sec]
  671.         jnz     .fix_sec
  672. .exit:
  673.         ret
  674. endp
  675.  
  676. align 4
  677. proc load_driver stdcall, driver_name:dword
  678.            locals
  679.              coff      dd ?
  680.              sym       dd ?
  681.              strings   dd ?
  682.              img_size  dd ?
  683.              img_base  dd ?
  684.              start     dd ?
  685.  
  686.              exports   dd ?   ;fake exports table
  687.                        dd ?
  688.              file_name rb 13+16+4+1      ; '/sys/drivers/<up-to-16-chars>.obj'
  689.            endl
  690.  
  691.         lea     edx, [file_name]
  692.         mov     dword [edx], '/sys'
  693.         mov     dword [edx+4], '/dri'
  694.         mov     dword [edx+8], 'vers'
  695.         mov     byte [edx+12], '/'
  696.         mov     esi, [driver_name]
  697. .redo:
  698.         lea     edx, [file_name]
  699.         lea     edi, [edx+13]
  700.         mov     ecx, 16
  701. @@:
  702.         lodsb
  703.         test    al, al
  704.         jz      @f
  705.         stosb
  706.         loop    @b
  707. @@:
  708.         mov     dword [edi], '.obj'
  709.         mov     byte [edi+4], 0
  710.         stdcall load_file, edx
  711.  
  712.         test    eax, eax
  713.         jz      .exit
  714.  
  715.         mov     [coff], eax
  716.  
  717.         movzx   ecx, [eax+COFF_HEADER.nSections]
  718.         xor     ebx, ebx
  719.  
  720.         lea     edx, [eax+20]
  721. @@:
  722.         add     ebx, [edx+COFF_SECTION.SizeOfRawData]
  723.         add     ebx, 15
  724.         and     ebx, not 15
  725.         add     edx, sizeof.COFF_SECTION
  726.         dec     ecx
  727.         jnz     @B
  728.         mov     [img_size], ebx
  729.  
  730.         stdcall kernel_alloc, ebx
  731.         test    eax, eax
  732.         jz      .fail
  733.         mov     [img_base], eax
  734.  
  735.         mov     edi, eax
  736.         xor     eax, eax
  737.         mov     ecx, [img_size]
  738.         add     ecx, 4095
  739.         and     ecx, not 4095
  740.         shr     ecx, 2
  741.         cld
  742.         rep stosd
  743.  
  744.         mov     edx, [coff]
  745.         movzx   ebx, [edx+COFF_HEADER.nSections]
  746.         mov     edi, [img_base]
  747.         lea     eax, [edx+20]
  748. @@:
  749.         mov     [eax+COFF_SECTION.VirtualAddress], edi
  750.         mov     esi, [eax+COFF_SECTION.PtrRawData]
  751.         test    esi, esi
  752.         jnz     .copy
  753.         add     edi, [eax+COFF_SECTION.SizeOfRawData]
  754.         jmp     .next
  755. .copy:
  756.         add     esi, edx
  757.         mov     ecx, [eax+COFF_SECTION.SizeOfRawData]
  758.         cld
  759.         rep movsb
  760. .next:
  761.         add     edi, 15
  762.         and     edi, not 15
  763.         add     eax, sizeof.COFF_SECTION
  764.         dec     ebx
  765.         jnz     @B
  766.  
  767.         mov     ebx, [edx+COFF_HEADER.pSymTable]
  768.         add     ebx, edx
  769.         mov     [sym], ebx
  770.         mov     ecx, [edx+COFF_HEADER.nSymbols]
  771.         add     ecx, ecx
  772.         lea     ecx, [ecx+ecx*8];ecx*=18 = nSymbols*CSYM_SIZE
  773.         add     ecx, [sym]
  774.         mov     [strings], ecx
  775.  
  776.         lea     ebx, [exports]
  777.         mov     dword [ebx], kernel_export
  778.         mov     dword [ebx+4], 0
  779.         lea     eax, [edx+20]
  780.  
  781.         stdcall fix_coff_symbols, eax, [sym], [edx+COFF_HEADER.nSymbols], \
  782.                 [strings], ebx
  783.         test    eax, eax
  784.         jz      .link_fail
  785.  
  786.         mov     ebx, [coff]
  787.         stdcall fix_coff_relocs, ebx, [sym], 0
  788.  
  789.         stdcall get_coff_sym, [sym], [ebx+COFF_HEADER.nSymbols], szVersion
  790.         test    eax, eax
  791.         jz      .link_fail
  792.  
  793.         mov     eax, [eax]
  794.         shr     eax, 16
  795.         cmp     eax, DRV_COMPAT
  796.         jb      .ver_fail
  797.  
  798.         cmp     eax, DRV_CURRENT
  799.         ja      .ver_fail
  800.  
  801.         mov     ebx, [coff]
  802.         stdcall get_coff_sym, [sym], [ebx+COFF_HEADER.nSymbols], szSTART
  803.         mov     [start], eax
  804.  
  805.         stdcall kernel_free, [coff]
  806.  
  807.         mov     ebx, [start]
  808.         stdcall ebx, DRV_ENTRY
  809.         test    eax, eax
  810.         jnz     .ok
  811.  
  812.         stdcall kernel_free, [img_base]
  813.  
  814.         xor     eax, eax
  815.         ret
  816. .ok:
  817.         mov     ebx, [img_base]
  818.         mov     [eax+SRV.base], ebx
  819.         mov     ecx, [start]
  820.         mov     [eax+SRV.entry], ecx
  821.         ret
  822.  
  823. .ver_fail:
  824.         mov     esi, msg_CR
  825.         call    sys_msg_board_str
  826.         mov     esi, [driver_name]
  827.         call    sys_msg_board_str
  828.         mov     esi, msg_CR
  829.         call    sys_msg_board_str
  830.         mov     esi, msg_version
  831.         call    sys_msg_board_str
  832.         mov     esi, msg_www
  833.         call    sys_msg_board_str
  834.         jmp     .cleanup
  835.  
  836. .link_fail:
  837.         mov     esi, msg_module
  838.         call    sys_msg_board_str
  839.         mov     esi, [driver_name]
  840.         call    sys_msg_board_str
  841.         mov     esi, msg_CR
  842.         call    sys_msg_board_str
  843. .cleanup:
  844.         stdcall kernel_free, [img_base]
  845. .fail:
  846.         stdcall kernel_free, [coff]
  847. .exit:
  848.         xor     eax, eax
  849.         ret
  850. endp
  851.  
  852. ; in: edx -> COFF_SECTION struct
  853. ; out: eax = alignment as mask for bits to drop
  854. coff_get_align:
  855. ; Rules:
  856. ; - if alignment is not given, use default = 4K;
  857. ; - if alignment is given and is no more than 4K, use it;
  858. ; - if alignment is more than 4K, revert to 4K.
  859.         push    ecx
  860.         mov     cl, byte [edx+COFF_SECTION.Characteristics+2]
  861.         mov     eax, 1
  862.         shr     cl, 4
  863.         dec     cl
  864.         js      .default
  865.         cmp     cl, 12
  866.         jbe     @f
  867. .default:
  868.         mov     cl, 12
  869. @@:
  870.         shl     eax, cl
  871.         pop     ecx
  872.         dec     eax
  873.         ret
  874.  
  875. align 4
  876. proc load_library stdcall, file_name:dword
  877.            locals
  878.              fullname  rb 260
  879.              fileinfo  rb 40
  880.              coff      dd ?
  881.              img_base  dd ?
  882.            endl
  883.  
  884.         cli
  885.  
  886. ; resolve file name
  887.         mov     ebx, [file_name]
  888.         lea     edi, [fullname+1]
  889.         mov     byte [edi-1], '/'
  890.         stdcall get_full_file_name, edi, 259
  891.         test    al, al
  892.         jz      .fail
  893.  
  894. ; scan for required DLL in list of already loaded for this process,
  895. ; ignore timestamp
  896.         mov     esi, [CURRENT_TASK]
  897.         shl     esi, 8
  898.         lea     edi, [fullname]
  899.         mov     ebx, [esi+SLOT_BASE+APPDATA.dlls_list_ptr]
  900.         test    ebx, ebx
  901.         jz      .not_in_process
  902.         mov     esi, [ebx+HDLL.fd]
  903. .scan_in_process:
  904.         cmp     esi, ebx
  905.         jz      .not_in_process
  906.         mov     eax, [esi+HDLL.parent]
  907.         add     eax, DLLDESCR.name
  908.         stdcall strncmp, eax, edi, -1
  909.         test    eax, eax
  910.         jnz     .next_in_process
  911. ; simple variant: load DLL which is already loaded in this process
  912. ; just increment reference counters and return address of exports table
  913.         inc     [esi+HDLL.refcount]
  914.         mov     ecx, [esi+HDLL.parent]
  915.         inc     [ecx+DLLDESCR.refcount]
  916.         mov     eax, [ecx+DLLDESCR.exports]
  917.         sub     eax, [ecx+DLLDESCR.defaultbase]
  918.         add     eax, [esi+HDLL.base]
  919.         ret
  920. .next_in_process:
  921.         mov     esi, [esi+HDLL.fd]
  922.         jmp     .scan_in_process
  923. .not_in_process:
  924.  
  925. ; scan in full list, compare timestamp
  926.         lea     eax, [fileinfo]
  927.         stdcall get_fileinfo, edi, eax
  928.         test    eax, eax
  929.         jnz     .fail
  930.         mov     esi, [dll_list.fd]
  931. .scan_for_dlls:
  932.         cmp     esi, dll_list
  933.         jz      .load_new
  934.         lea     eax, [esi+DLLDESCR.name]
  935.         stdcall strncmp, eax, edi, -1
  936.         test    eax, eax
  937.         jnz     .continue_scan
  938. .test_prev_dll:
  939.         mov     eax, dword [fileinfo+24]; last modified time
  940.         mov     edx, dword [fileinfo+28]; last modified date
  941.         cmp     dword [esi+DLLDESCR.timestamp], eax
  942.         jnz     .continue_scan
  943.         cmp     dword [esi+DLLDESCR.timestamp+4], edx
  944.         jz      .dll_already_loaded
  945. .continue_scan:
  946.         mov     esi, [esi+DLLDESCR.fd]
  947.         jmp     .scan_for_dlls
  948.  
  949. ; new DLL
  950. .load_new:
  951. ; load file
  952.         stdcall load_file, edi
  953.         test    eax, eax
  954.         jz      .fail
  955.         mov     [coff], eax
  956.         mov     dword [fileinfo+32], ebx
  957.  
  958. ; allocate DLLDESCR struct; size is DLLDESCR.sizeof plus size of DLL name
  959.         mov     esi, edi
  960.         mov     ecx, -1
  961.         xor     eax, eax
  962.         repnz scasb
  963.         not     ecx
  964.         lea     eax, [ecx+sizeof.DLLDESCR]
  965.         push    ecx
  966.         call    malloc
  967.         pop     ecx
  968.         test    eax, eax
  969.         jz      .fail_and_free_coff
  970. ; save timestamp
  971.         lea     edi, [eax+DLLDESCR.name]
  972.         rep movsb
  973.         mov     esi, eax
  974.         mov     eax, dword [fileinfo+24]
  975.         mov     dword [esi+DLLDESCR.timestamp], eax
  976.         mov     eax, dword [fileinfo+28]
  977.         mov     dword [esi+DLLDESCR.timestamp+4], eax
  978. ; initialize DLLDESCR struct
  979.         and     dword [esi+DLLDESCR.refcount], 0; no HDLLs yet; later it will be incremented
  980.         mov     [esi+DLLDESCR.fd], dll_list
  981.         mov     eax, [dll_list.bk]
  982.         mov     [dll_list.bk], esi
  983.         mov     [esi+DLLDESCR.bk], eax
  984.         mov     [eax+DLLDESCR.fd], esi
  985.  
  986. ; calculate size of loaded DLL
  987.         mov     edx, [coff]
  988.         movzx   ecx, [edx+COFF_HEADER.nSections]
  989.         xor     ebx, ebx
  990.  
  991.         add     edx, 20
  992. @@:
  993.         call    coff_get_align
  994.         add     ebx, eax
  995.         not     eax
  996.         and     ebx, eax
  997.         add     ebx, [edx+COFF_SECTION.SizeOfRawData]
  998.         add     edx, sizeof.COFF_SECTION
  999.         dec     ecx
  1000.         jnz     @B
  1001. ; it must be nonzero and not too big
  1002.         mov     [esi+DLLDESCR.size], ebx
  1003.         test    ebx, ebx
  1004.         jz      .fail_and_free_dll
  1005.         cmp     ebx, MAX_DEFAULT_DLL_ADDR-MIN_DEFAULT_DLL_ADDR
  1006.         ja      .fail_and_free_dll
  1007. ; allocate memory for kernel-side image
  1008.         stdcall kernel_alloc, ebx
  1009.         test    eax, eax
  1010.         jz      .fail_and_free_dll
  1011.         mov     [esi+DLLDESCR.data], eax
  1012. ; calculate preferred base address
  1013.         add     ebx, 0x1FFF
  1014.         and     ebx, not 0xFFF
  1015.         mov     ecx, [dll_cur_addr]
  1016.         lea     edx, [ecx+ebx]
  1017.         cmp     edx, MAX_DEFAULT_DLL_ADDR
  1018.         jb      @f
  1019.         mov     ecx, MIN_DEFAULT_DLL_ADDR
  1020.         lea     edx, [ecx+ebx]
  1021. @@:
  1022.         mov     [esi+DLLDESCR.defaultbase], ecx
  1023.         mov     [dll_cur_addr], edx
  1024.  
  1025. ; copy sections and set correct values for VirtualAddress'es in headers
  1026.         push    esi
  1027.         mov     edx, [coff]
  1028.         movzx   ebx, [edx+COFF_HEADER.nSections]
  1029.         mov     edi, eax
  1030.         add     edx, 20
  1031.         cld
  1032. @@:
  1033.         call    coff_get_align
  1034.         add     ecx, eax
  1035.         add     edi, eax
  1036.         not     eax
  1037.         and     ecx, eax
  1038.         and     edi, eax
  1039.         mov     [edx+COFF_SECTION.VirtualAddress], ecx
  1040.         add     ecx, [edx+COFF_SECTION.SizeOfRawData]
  1041.         mov     esi, [edx+COFF_SECTION.PtrRawData]
  1042.         push    ecx
  1043.         mov     ecx, [edx+COFF_SECTION.SizeOfRawData]
  1044.         test    esi, esi
  1045.         jnz     .copy
  1046.         xor     eax, eax
  1047.         rep stosb
  1048.         jmp     .next
  1049. .copy:
  1050.         add     esi, [coff]
  1051.         rep movsb
  1052. .next:
  1053.         pop     ecx
  1054.         add     edx, sizeof.COFF_SECTION
  1055.         dec     ebx
  1056.         jnz     @B
  1057.         pop     esi
  1058.  
  1059. ; save some additional data from COFF file
  1060. ; later we will use COFF header, headers for sections and symbol table
  1061. ; and also relocations table for all sections
  1062.         mov     edx, [coff]
  1063.         mov     ebx, [edx+COFF_HEADER.pSymTable]
  1064.         mov     edi, dword [fileinfo+32]
  1065.         sub     edi, ebx
  1066.         jc      .fail_and_free_data
  1067.         mov     [esi+DLLDESCR.symbols_lim], edi
  1068.         add     ebx, edx
  1069.         movzx   ecx, [edx+COFF_HEADER.nSections]
  1070.         lea     ecx, [ecx*5]
  1071.         lea     edi, [edi+ecx*8+20]
  1072.         add     edx, 20
  1073. @@:
  1074.         movzx   eax, [edx+COFF_SECTION.NumReloc]
  1075.         lea     eax, [eax*5]
  1076.         lea     edi, [edi+eax*2]
  1077.         add     edx, sizeof.COFF_SECTION
  1078.         sub     ecx, 5
  1079.         jnz     @b
  1080.         stdcall kernel_alloc, edi
  1081.         test    eax, eax
  1082.         jz      .fail_and_free_data
  1083.         mov     edx, [coff]
  1084.         movzx   ecx, [edx+COFF_HEADER.nSections]
  1085.         lea     ecx, [ecx*5]
  1086.         lea     ecx, [ecx*2+5]
  1087.         mov     [esi+DLLDESCR.coff_hdr], eax
  1088.         push    esi
  1089.         mov     esi, edx
  1090.         mov     edi, eax
  1091.         rep movsd
  1092.         pop     esi
  1093.         mov     [esi+DLLDESCR.symbols_ptr], edi
  1094.         push    esi
  1095.         mov     ecx, [edx+COFF_HEADER.nSymbols]
  1096.         mov     [esi+DLLDESCR.symbols_num], ecx
  1097.         mov     ecx, [esi+DLLDESCR.symbols_lim]
  1098.         mov     esi, ebx
  1099.         rep movsb
  1100.         pop     esi
  1101.         mov     ebx, [esi+DLLDESCR.coff_hdr]
  1102.         push    esi
  1103.         movzx   eax, [edx+COFF_HEADER.nSections]
  1104.         lea     edx, [ebx+20]
  1105. @@:
  1106.         movzx   ecx, [edx+COFF_SECTION.NumReloc]
  1107.         lea     ecx, [ecx*5]
  1108.         mov     esi, [edx+COFF_SECTION.PtrReloc]
  1109.         mov     [edx+COFF_SECTION.PtrReloc], edi
  1110.         sub     [edx+COFF_SECTION.PtrReloc], ebx
  1111.         add     esi, [coff]
  1112.         shr     ecx, 1
  1113.         rep movsd
  1114.         adc     ecx, ecx
  1115.         rep movsw
  1116.         add     edx, sizeof.COFF_SECTION
  1117.         dec     eax
  1118.         jnz     @b
  1119.         pop     esi
  1120.  
  1121. ; fixup symbols
  1122.         mov     edx, ebx
  1123.         mov     eax, [ebx+COFF_HEADER.nSymbols]
  1124.         add     edx, 20
  1125.         mov     ecx, [esi+DLLDESCR.symbols_num]
  1126.         lea     ecx, [ecx*9]
  1127.         add     ecx, ecx
  1128.         add     ecx, [esi+DLLDESCR.symbols_ptr]
  1129.  
  1130.         stdcall fix_coff_symbols, edx, [esi+DLLDESCR.symbols_ptr], eax, \
  1131.                 ecx, 0
  1132. ;          test eax, eax
  1133. ;          jnz @F
  1134. ;
  1135. ;@@:
  1136.  
  1137.         stdcall get_coff_sym, [esi+DLLDESCR.symbols_ptr], [ebx+COFF_HEADER.nSymbols], szEXPORTS
  1138.         test    eax, eax
  1139.         jnz     @F
  1140.  
  1141.         stdcall get_coff_sym, [esi+DLLDESCR.symbols_ptr], [ebx+COFF_HEADER.nSymbols], sz_EXPORTS
  1142. @@:
  1143.         mov     [esi+DLLDESCR.exports], eax
  1144.  
  1145. ; fix relocs in the hidden copy in kernel memory to default address
  1146. ; it is first fix; usually this will be enough, but second fix
  1147. ; can be necessary if real load address will not equal assumption
  1148.         mov     eax, [esi+DLLDESCR.data]
  1149.         sub     eax, [esi+DLLDESCR.defaultbase]
  1150.         stdcall fix_coff_relocs, ebx, [esi+DLLDESCR.symbols_ptr], eax
  1151.  
  1152.         stdcall kernel_free, [coff]
  1153.  
  1154. .dll_already_loaded:
  1155.         inc     [esi+DLLDESCR.refcount]
  1156.         push    esi
  1157.         call    init_heap
  1158.         pop     esi
  1159.  
  1160.         mov     edi, [esi+DLLDESCR.size]
  1161.         stdcall user_alloc_at, [esi+DLLDESCR.defaultbase], edi
  1162.         test    eax, eax
  1163.         jnz     @f
  1164.         stdcall user_alloc, edi
  1165.         test    eax, eax
  1166.         jz      .fail_and_dereference
  1167. @@:
  1168.         mov     [img_base], eax
  1169.         mov     eax, sizeof.HDLL
  1170.         call    malloc
  1171.         test    eax, eax
  1172.         jz      .fail_and_free_user
  1173.         mov     ebx, [CURRENT_TASK]
  1174.         shl     ebx, 5
  1175.         mov     edx, [CURRENT_TASK+ebx+TASKDATA.pid]
  1176.         mov     [eax+HDLL.pid], edx
  1177.         push    eax
  1178.         call    init_dlls_in_thread
  1179.         pop     ebx
  1180.         test    eax, eax
  1181.         jz      .fail_and_free_user
  1182.         mov     edx, [eax+HDLL.fd]
  1183.         mov     [ebx+HDLL.fd], edx
  1184.         mov     [ebx+HDLL.bk], eax
  1185.         mov     [eax+HDLL.fd], ebx
  1186.         mov     [edx+HDLL.bk], ebx
  1187.         mov     eax, ebx
  1188.         mov     ebx, [img_base]
  1189.         mov     [eax+HDLL.base], ebx
  1190.         mov     [eax+HDLL.size], edi
  1191.         mov     [eax+HDLL.refcount], 1
  1192.         mov     [eax+HDLL.parent], esi
  1193.         mov     edx, ebx
  1194.         shr     edx, 12
  1195.         or      dword [page_tabs+(edx-1)*4], DONT_FREE_BLOCK
  1196. ; copy entries of page table from kernel-side image to usermode
  1197. ; use copy-on-write for user-mode image, so map as readonly
  1198.         xor     edi, edi
  1199.         mov     ecx, [esi+DLLDESCR.data]
  1200.         shr     ecx, 12
  1201. .map_pages_loop:
  1202.         mov     eax, [page_tabs+ecx*4]
  1203.         and     eax, not 0xFFF
  1204.         or      al, PG_USER
  1205.         xchg    eax, [page_tabs+edx*4]
  1206.         test    al, 1
  1207.         jz      @f
  1208.         call    free_page
  1209. @@:
  1210.         invlpg  [ebx+edi]
  1211.         inc     ecx
  1212.         inc     edx
  1213.         add     edi, 0x1000
  1214.         cmp     edi, [esi+DLLDESCR.size]
  1215.         jb      .map_pages_loop
  1216.  
  1217. ; if real user-mode base is not equal to preferred base, relocate image
  1218.         sub     ebx, [esi+DLLDESCR.defaultbase]
  1219.         jz      @f
  1220.         stdcall rebase_coff, [esi+DLLDESCR.coff_hdr], [esi+DLLDESCR.symbols_ptr], ebx
  1221. @@:
  1222.  
  1223.         mov     eax, [esi+DLLDESCR.exports]
  1224.         sub     eax, [esi+DLLDESCR.defaultbase]
  1225.         add     eax, [img_base]
  1226.         ret
  1227. .fail_and_free_data:
  1228.         stdcall kernel_free, [esi+DLLDESCR.data]
  1229. .fail_and_free_dll:
  1230.         mov     eax, esi
  1231.         call    free
  1232. .fail_and_free_coff:
  1233.         stdcall kernel_free, [coff]
  1234. .fail:
  1235.         xor     eax, eax
  1236.         ret
  1237. .fail_and_free_user:
  1238.         stdcall user_free, [img_base]
  1239. .fail_and_dereference:
  1240.         mov     eax, 1  ; delete 1 reference
  1241.         call    dereference_dll
  1242.         xor     eax, eax
  1243.         ret
  1244. endp
  1245.  
  1246. ; initialize [APPDATA.dlls_list_ptr] for given thread
  1247. ; DLL is per-process object, so APPDATA.dlls_list_ptr must be
  1248. ; kept in sync for all threads of one process.
  1249. ; out: eax = APPDATA.dlls_list_ptr if all is OK,
  1250. ; NULL if memory allocation failed
  1251. init_dlls_in_thread:
  1252.         mov     ebx, [current_slot]
  1253.         mov     eax, [ebx+APPDATA.dlls_list_ptr]
  1254.         test    eax, eax
  1255.         jnz     .ret
  1256.         push    [ebx+APPDATA.dir_table]
  1257.         mov     eax, 8
  1258.         call    malloc
  1259.         pop     edx
  1260.         test    eax, eax
  1261.         jz      .ret
  1262.         mov     [eax], eax
  1263.         mov     [eax+4], eax
  1264.         mov     ecx, [TASK_COUNT]
  1265.         mov     ebx, SLOT_BASE+256
  1266. .set:
  1267.         cmp     [ebx+APPDATA.dir_table], edx
  1268.         jnz     @f
  1269.         mov     [ebx+APPDATA.dlls_list_ptr], eax
  1270. @@:
  1271.         add     ebx, 256
  1272.         dec     ecx
  1273.         jnz     .set
  1274. .ret:
  1275.         ret
  1276.  
  1277. ; in: eax = number of references to delete, esi -> DLLDESCR struc
  1278. dereference_dll:
  1279.         sub     [esi+DLLDESCR.refcount], eax
  1280.         jnz     .ret
  1281.         mov     eax, [esi+DLLDESCR.fd]
  1282.         mov     edx, [esi+DLLDESCR.bk]
  1283.         mov     [eax+DLLDESCR.bk], edx
  1284.         mov     [edx+DLLDESCR.fd], eax
  1285.         stdcall kernel_free, [esi+DLLDESCR.coff_hdr]
  1286.         stdcall kernel_free, [esi+DLLDESCR.data]
  1287.         mov     eax, esi
  1288.         call    free
  1289. .ret:
  1290.         ret
  1291.  
  1292. destroy_hdll:
  1293.         push    ebx ecx esi edi
  1294.         push    eax
  1295.         mov     ebx, [eax+HDLL.base]
  1296.         mov     esi, [eax+HDLL.parent]
  1297.         mov     edx, [esi+DLLDESCR.size]
  1298. ; The following actions require the context of application where HDLL is mapped.
  1299. ; However, destroy_hdll can be called in the context of OS thread when
  1300. ; cleaning up objects created by the application which is destroyed.
  1301. ; So remember current cr3 and set it to page table of target.
  1302.         mov     eax, [ecx+APPDATA.dir_table]
  1303. ; Because we cheat with cr3, disable interrupts: task switch would restore
  1304. ; page table from APPDATA of current thread.
  1305. ; Also set [current_slot] because it is used by user_free.
  1306.         pushf
  1307.         cli
  1308.         push    [current_slot]
  1309.         mov     [current_slot], ecx
  1310.         mov     ecx, cr3
  1311.         push    ecx
  1312.         mov     cr3, eax
  1313.         push    ebx     ; argument for user_free
  1314.         mov     eax, ebx
  1315.         shr     ebx, 12
  1316.         push    ebx
  1317.         mov     esi, [esi+DLLDESCR.data]
  1318.         shr     esi, 12
  1319. .unmap_loop:
  1320.         push    eax
  1321.         mov     eax, 2
  1322.         xchg    eax, [page_tabs+ebx*4]
  1323.         mov     ecx, [page_tabs+esi*4]
  1324.         and     eax, not 0xFFF
  1325.         and     ecx, not 0xFFF
  1326.         cmp     eax, ecx
  1327.         jz      @f
  1328.         call    free_page
  1329. @@:
  1330.         pop     eax
  1331.         invlpg  [eax]
  1332.         add     eax, 0x1000
  1333.         inc     ebx
  1334.         inc     esi
  1335.         sub     edx, 0x1000
  1336.         ja      .unmap_loop
  1337.         pop     ebx
  1338.         and     dword [page_tabs+(ebx-1)*4], not DONT_FREE_BLOCK
  1339.         call    user_free
  1340. ; Restore context.
  1341.         pop     eax
  1342.         mov     cr3, eax
  1343.         pop     [current_slot]
  1344.         popf
  1345. ; Ok, cheating is done.
  1346.         pop     eax
  1347.         push    eax
  1348.         mov     esi, [eax+HDLL.parent]
  1349.         mov     eax, [eax+HDLL.refcount]
  1350.         call    dereference_dll
  1351.         pop     eax
  1352.         mov     edx, [eax+HDLL.bk]
  1353.         mov     ebx, [eax+HDLL.fd]
  1354.         mov     [ebx+HDLL.bk], edx
  1355.         mov     [edx+HDLL.fd], ebx
  1356.         call    free
  1357.         pop     edi esi ecx ebx
  1358.         ret
  1359.  
  1360. ; ecx -> APPDATA for slot, esi = dlls_list_ptr
  1361. destroy_all_hdlls:
  1362.         test    esi, esi
  1363.         jz      .ret
  1364. .loop:
  1365.         mov     eax, [esi+HDLL.fd]
  1366.         cmp     eax, esi
  1367.         jz      free
  1368.         call    destroy_hdll
  1369.         jmp     .loop
  1370. .ret:
  1371.         ret
  1372.  
  1373. align 4
  1374. stop_all_services:
  1375.         push    ebp
  1376.         mov     edx, [srv.fd]
  1377. .next:
  1378.         cmp     edx, srv.fd-SRV.fd
  1379.         je      .done
  1380.         cmp     [edx+SRV.magic], ' SRV'
  1381.         jne     .next
  1382.         cmp     [edx+SRV.size], sizeof.SRV
  1383.         jne     .next
  1384.  
  1385.         mov     ebx, [edx+SRV.entry]
  1386.         mov     edx, [edx+SRV.fd]
  1387.         test    ebx, ebx
  1388.         jz      .next
  1389.  
  1390.         push    edx
  1391.         mov     ebp, esp
  1392.         push    0
  1393.         push    -1
  1394.         call    ebx
  1395.         mov     esp, ebp
  1396.         pop     edx
  1397.         jmp     .next
  1398. .done:
  1399.         pop     ebp
  1400.         ret
  1401.  
  1402. ; param
  1403. ;  eax= size
  1404. ;  ebx= pid
  1405.  
  1406. align 4
  1407. create_kernel_object:
  1408.  
  1409.         push    ebx
  1410.         call    malloc
  1411.         pop     ebx
  1412.         test    eax, eax
  1413.         jz      .fail
  1414.  
  1415.         mov     ecx, [current_slot]
  1416.         add     ecx, APP_OBJ_OFFSET
  1417.  
  1418.         pushfd
  1419.         cli
  1420.         mov     edx, [ecx+APPOBJ.fd]
  1421.         mov     [eax+APPOBJ.fd], edx
  1422.         mov     [eax+APPOBJ.bk], ecx
  1423.         mov     [eax+APPOBJ.pid], ebx
  1424.  
  1425.         mov     [ecx+APPOBJ.fd], eax
  1426.         mov     [edx+APPOBJ.bk], eax
  1427.         popfd
  1428. .fail:
  1429.         ret
  1430.  
  1431. ; param
  1432. ;  eax= object
  1433.  
  1434. align 4
  1435. destroy_kernel_object:
  1436.  
  1437.         pushfd
  1438.         cli
  1439.         mov     ebx, [eax+APPOBJ.fd]
  1440.         mov     ecx, [eax+APPOBJ.bk]
  1441.         mov     [ebx+APPOBJ.bk], ecx
  1442.         mov     [ecx+APPOBJ.fd], ebx
  1443.         popfd
  1444.  
  1445.         xor     edx, edx       ;clear common header
  1446.         mov     [eax], edx
  1447.         mov     [eax+4], edx
  1448.         mov     [eax+8], edx
  1449.         mov     [eax+12], edx
  1450.         mov     [eax+16], edx
  1451.  
  1452.         call    free           ;release object memory
  1453.         ret
  1454.