Subversion Repositories Kolibri OS

Rev

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