Subversion Repositories Kolibri OS

Rev

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

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