Subversion Repositories Kolibri OS

Rev

Rev 2050 | Rev 2465 | 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: 2106 $
  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.