Subversion Repositories Kolibri OS

Rev

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