Subversion Repositories Kolibri OS

Rev

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