Subversion Repositories Kolibri OS

Rev

Rev 1635 | Rev 2138 | 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: 2130 $
  9.  
  10.  
  11. struc MEM_BLOCK
  12. {  .next_block  dd ?
  13.    .prev_block  dd ? ;+4
  14.    .list_fd     dd ? ;+8
  15.    .list_bk     dd ? ;+12
  16.    .base        dd ? ;+16
  17.    .size        dd ? ;+20
  18.    .flags       dd ? ;+24
  19.    .handle      dd ? ;+28
  20. }
  21.  
  22. MEM_LIST_OFFSET equ  8
  23. FREE_BLOCK      equ  4
  24. USED_BLOCK      equ  8
  25. DONT_FREE_BLOCK equ  10h
  26.  
  27. virtual at 0
  28.   MEM_BLOCK MEM_BLOCK
  29. end virtual
  30.  
  31. MEM_BLOCK_SIZE equ 8*4
  32.  
  33. block_next   equ MEM_BLOCK.next_block
  34. block_prev   equ MEM_BLOCK.prev_block
  35. list_fd      equ MEM_BLOCK.list_fd
  36. list_bk      equ MEM_BLOCK.list_bk
  37. block_base   equ MEM_BLOCK.base
  38. block_size   equ MEM_BLOCK.size
  39. block_flags  equ MEM_BLOCK.flags
  40.  
  41. macro calc_index op
  42. {          shr op, 12
  43.            dec op
  44.            cmp op, 63
  45.            jna @f
  46.            mov op, 63
  47. @@:
  48. }
  49.  
  50. macro remove_from_list op
  51. {          mov edx, [op+list_fd]
  52.            mov ecx, [op+list_bk]
  53.            test edx, edx
  54.            jz @f
  55.            mov [edx+list_bk], ecx
  56. @@:
  57.            test ecx, ecx
  58.            jz @f
  59.            mov [ecx+list_fd], edx
  60. @@:
  61.            mov [op+list_fd],0
  62.            mov [op+list_bk],0
  63. }
  64.  
  65. macro remove_from_free op
  66. {
  67.            remove_from_list op
  68.  
  69.            mov eax, [op+block_size]
  70.            calc_index eax
  71.            cmp [mem_block_list+eax*4], op
  72.            jne @f
  73.            mov [mem_block_list+eax*4], edx
  74. @@:
  75.            cmp [mem_block_list+eax*4], 0
  76.            jne @f
  77.            btr [mem_block_mask], eax
  78. @@:
  79. }
  80.  
  81. macro remove_from_used op
  82. {
  83.            mov edx, [op+list_fd]
  84.            mov ecx, [op+list_bk]
  85.            mov [edx+list_bk], ecx
  86.            mov [ecx+list_fd], edx
  87.            mov [op+list_fd], 0
  88.            mov [op+list_bk], 0
  89. }
  90.  
  91. align 4
  92. proc init_kernel_heap
  93.  
  94.            mov ecx, 64
  95.            mov edi, mem_block_list
  96.            xor eax, eax
  97.            cld
  98.            rep stosd
  99.  
  100.            mov ecx, 512/4
  101.            mov edi, mem_block_map
  102.            not eax
  103.            rep stosd
  104.  
  105.            mov [mem_block_start], mem_block_map
  106.            mov [mem_block_end], mem_block_map+512
  107.            mov [mem_block_arr], HEAP_BASE
  108.  
  109.            mov eax, mem_used.fd-MEM_LIST_OFFSET
  110.            mov [mem_used.fd], eax
  111.            mov [mem_used.bk], eax
  112.  
  113.            stdcall alloc_pages, dword 32
  114.            mov ecx, 32
  115.            mov edx, eax
  116.            mov edi, HEAP_BASE
  117. .l1:
  118.            stdcall map_page,edi,edx,PG_SW
  119.            add edi, 0x1000
  120.            add edx, 0x1000
  121.            dec ecx
  122.            jnz .l1
  123.  
  124.            mov edi, HEAP_BASE
  125.            mov ebx, HEAP_BASE+MEM_BLOCK_SIZE
  126.            xor eax, eax
  127.            mov [edi+block_next], ebx
  128.            mov [edi+block_prev], eax
  129.            mov [edi+list_fd], eax
  130.            mov [edi+list_bk], eax
  131.            mov [edi+block_base], HEAP_BASE
  132.            mov [edi+block_size], 4096*MEM_BLOCK_SIZE
  133.            mov [edi+block_flags], USED_BLOCK
  134.  
  135.            mov [ebx+block_next], eax
  136.            mov [ebx+block_prev], eax
  137.            mov [ebx+list_fd], eax
  138.            mov [ebx+list_bk], eax
  139.            mov [ebx+block_base], HEAP_BASE+4096*MEM_BLOCK_SIZE
  140.  
  141.            mov ecx, [pg_data.kernel_pages]
  142.            shl ecx, 12
  143.            sub ecx, HEAP_BASE-OS_BASE+4096*MEM_BLOCK_SIZE
  144.            mov [heap_size], ecx
  145.            mov [heap_free], ecx
  146.            mov [ebx+block_size], ecx
  147.            mov [ebx+block_flags], FREE_BLOCK
  148.  
  149.            mov [mem_block_mask], eax
  150.            mov [mem_block_mask+4],0x80000000
  151.  
  152.            mov [mem_block_list+63*4], ebx
  153.            mov byte [mem_block_map], 0xFC
  154.            mov ecx, heap_mutex
  155.            call mutex_init
  156.            mov [heap_blocks], 4095
  157.            mov [free_blocks], 4094
  158.            ret
  159. endp
  160.  
  161. ; param
  162. ;  eax= required size
  163. ;
  164. ; retval
  165. ;  edi= memory block descriptor
  166. ;  ebx= descriptor index
  167.  
  168. align 4
  169. get_small_block:
  170.            mov ecx, eax
  171.            shr ecx, 12
  172.            dec ecx
  173.            cmp ecx, 63
  174.            jle .get_index
  175.            mov ecx, 63
  176. .get_index:
  177.            lea esi, [mem_block_mask]
  178.            xor ebx, ebx
  179.            or edx, -1
  180.  
  181.            cmp ecx, 32
  182.            jb .bit_test
  183.  
  184.            sub ecx, 32
  185.            add ebx, 32
  186.            add esi, 4
  187. .bit_test:
  188.            shl edx, cl
  189.            and edx, [esi]
  190. .find:
  191.            bsf edi, edx
  192.            jz .high_mask
  193.            add ebx, edi
  194.            mov edi, [mem_block_list+ebx*4]
  195. .check_size:
  196.            cmp eax, [edi+block_size]
  197.            ja .next
  198.            ret
  199.  
  200. .high_mask:
  201.            add esi, 4
  202.            cmp esi, mem_block_mask+8
  203.            jae .err
  204.            add ebx, 32
  205.            mov edx, [esi]
  206.            jmp .find
  207. .next:
  208.            mov edi, [edi+list_fd]
  209.            test edi, edi
  210.            jnz .check_size
  211. .err:
  212.            xor edi, edi
  213.            ret
  214.  
  215. align 4
  216. alloc_mem_block:
  217.  
  218.            mov ebx, [mem_block_start]
  219.            mov ecx, [mem_block_end]
  220. .l1:
  221.            bsf eax,[ebx];
  222.            jnz found
  223.            add ebx,4
  224.            cmp ebx, ecx
  225.            jb .l1
  226.            xor eax,eax
  227.            ret
  228.  
  229. found:
  230.            btr [ebx], eax
  231.            mov [mem_block_start],ebx
  232.            sub ebx, mem_block_map
  233.            lea eax,[eax+ebx*8]
  234.            shl eax, 5
  235.            add eax, [mem_block_arr]
  236.            dec [free_blocks]
  237.            ret
  238. align 4
  239. free_mem_block:
  240.            mov dword [eax], 0
  241.            mov dword [eax+4], 0
  242.            mov dword [eax+8], 0
  243.            mov dword [eax+12], 0
  244.            mov dword [eax+16], 0
  245. ;           mov dword [eax+20], 0
  246.            mov dword [eax+24], 0
  247.            mov dword [eax+28], 0
  248.  
  249.            sub eax, [mem_block_arr]
  250.            shr eax, 5
  251.  
  252.            mov ebx, mem_block_map
  253.            bts [ebx], eax
  254.            inc [free_blocks]
  255.            shr eax, 3
  256.            and eax, not 3
  257.            add eax, ebx
  258.            cmp [mem_block_start], eax
  259.            ja @f
  260.            ret
  261. @@:
  262.            mov [mem_block_start], eax
  263.            ret
  264. .err:
  265.            xor eax, eax
  266.            ret
  267.  
  268. align 4
  269. proc alloc_kernel_space stdcall, size:dword
  270.            local block_ind:DWORD
  271.  
  272.            push ebx
  273.            push esi
  274.            push edi
  275.  
  276.            mov ecx, heap_mutex
  277.            call mutex_lock
  278.  
  279.            mov eax, [size]
  280.            add eax, 4095
  281.            and eax, not 4095
  282.            mov [size], eax
  283.  
  284.            cmp eax, [heap_free]
  285.            ja .error
  286.  
  287.            call get_small_block ; eax
  288.            test edi, edi
  289.            jz .error
  290.  
  291.            cmp [edi+block_flags], FREE_BLOCK
  292.            jne .error
  293.  
  294.            mov [block_ind], ebx   ;index of allocated block
  295.  
  296.            mov eax, [edi+block_size]
  297.            cmp eax, [size]
  298.            je .m_eq_size
  299.  
  300.            call alloc_mem_block
  301.            and eax, eax
  302.            jz .error
  303.  
  304.            mov esi, eax           ;esi - splitted block
  305.  
  306.            mov [esi+block_next], edi
  307.            mov eax, [edi+block_prev]
  308.            mov [esi+block_prev], eax
  309.            mov [edi+block_prev], esi
  310.            mov [esi+list_fd], 0
  311.            mov [esi+list_bk], 0
  312.            and eax, eax
  313.            jz @f
  314.            mov [eax+block_next], esi
  315. @@:
  316.            mov ebx, [edi+block_base]
  317.            mov [esi+block_base], ebx
  318.            mov edx, [size]
  319.            mov [esi+block_size], edx
  320.            add [edi+block_base], edx
  321.            sub [edi+block_size], edx
  322.  
  323.            mov eax, [edi+block_size]
  324.            shr eax, 12
  325.            sub eax, 1
  326.            cmp eax, 63
  327.            jna @f
  328.            mov eax, 63
  329. @@:
  330.            cmp eax, [block_ind]
  331.            je .m_eq_ind
  332.  
  333.            remove_from_list edi
  334.  
  335.            mov ecx, [block_ind]
  336.            mov [mem_block_list+ecx*4], edx
  337.  
  338.            test edx, edx
  339.            jnz @f
  340.            btr [mem_block_mask], ecx
  341. @@:
  342.            mov edx, [mem_block_list+eax*4]
  343.            mov [edi+list_fd], edx
  344.            test edx, edx
  345.            jz @f
  346.            mov [edx+list_bk], edi
  347. @@:
  348.            mov [mem_block_list+eax*4], edi
  349.            bts [mem_block_mask], eax
  350. .m_eq_ind:
  351.            mov ecx, mem_used.fd-MEM_LIST_OFFSET
  352.            mov edx, [ecx+list_fd]
  353.            mov [esi+list_fd], edx
  354.            mov [esi+list_bk], ecx
  355.            mov [ecx+list_fd], esi
  356.            mov [edx+list_bk], esi
  357.  
  358.            mov [esi+block_flags], USED_BLOCK
  359.            mov ebx, [size]
  360.            sub [heap_free], ebx
  361.            mov ecx, heap_mutex
  362.            call mutex_unlock
  363.            mov eax, [esi+block_base]
  364.            pop edi
  365.            pop esi
  366.            pop ebx
  367.            ret
  368. .m_eq_size:
  369.            remove_from_list edi
  370.            mov [mem_block_list+ebx*4], edx
  371.            and edx, edx
  372.            jnz @f
  373.            btr [mem_block_mask], ebx
  374. @@:
  375.            mov ecx, mem_used.fd-MEM_LIST_OFFSET
  376.            mov edx, [ecx+list_fd]
  377.            mov [edi+list_fd], edx
  378.            mov [edi+list_bk], ecx
  379.            mov [ecx+list_fd], edi
  380.            mov [edx+list_bk], edi
  381.  
  382.            mov [edi+block_flags], USED_BLOCK
  383.            mov ebx, [size]
  384.            sub [heap_free], ebx
  385.            mov ecx, heap_mutex
  386.            call mutex_unlock
  387.            mov eax, [edi+block_base]
  388.            pop edi
  389.            pop esi
  390.            pop ebx
  391.            ret
  392. .error:
  393.            mov ecx, heap_mutex
  394.            call mutex_unlock
  395.            xor eax, eax
  396.            pop edi
  397.            pop esi
  398.            pop ebx
  399.            ret
  400. endp
  401.  
  402. align 4
  403. proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
  404.            push ebx
  405.            push esi
  406.            push edi
  407.  
  408.            mov ecx, heap_mutex
  409.            call mutex_lock
  410.  
  411.            mov eax, [base]
  412.            mov esi, [mem_used.fd]
  413. @@:
  414.            cmp esi, mem_used.fd-MEM_LIST_OFFSET
  415.            je .fail
  416.  
  417.            cmp [esi+block_base], eax
  418.            je .found
  419.            mov esi, [esi+list_fd]
  420.            jmp @b
  421. .found:
  422.            cmp [esi+block_flags], USED_BLOCK
  423.            jne .fail
  424.  
  425.            mov eax, [esi+block_size]
  426.            add [heap_free], eax
  427.  
  428.            mov edi, [esi+block_next]
  429.            test edi, edi
  430.            jz .prev
  431.  
  432.            cmp [edi+block_flags], FREE_BLOCK
  433.            jne .prev
  434.  
  435.            remove_from_free edi
  436.  
  437.            mov edx, [edi+block_next]
  438.            mov [esi+block_next], edx
  439.            test edx, edx
  440.            jz @f
  441.  
  442.            mov [edx+block_prev], esi
  443. @@:
  444.            mov ecx, [edi+block_size]
  445.            add [esi+block_size], ecx
  446.  
  447.            mov eax, edi
  448.            call free_mem_block
  449. .prev:
  450.            mov edi, [esi+block_prev]
  451.            test edi, edi
  452.            jz .insert
  453.  
  454.            cmp [edi+block_flags], FREE_BLOCK
  455.            jne .insert
  456.  
  457.            remove_from_used esi
  458.  
  459.            mov edx, [esi+block_next]
  460.            mov [edi+block_next], edx
  461.            test edx, edx
  462.            jz @f
  463.            mov [edx+block_prev], edi
  464. @@:
  465.            mov eax, esi
  466.            call free_mem_block
  467.  
  468.            mov ecx, [edi+block_size]
  469.            mov eax, [esi+block_size]
  470.            add eax, ecx
  471.            mov [edi+block_size], eax
  472.  
  473.            calc_index eax
  474.            calc_index ecx
  475.            cmp eax, ecx
  476.            je .m_eq
  477.  
  478.            push ecx
  479.            remove_from_list edi
  480.            pop ecx
  481.  
  482.            cmp [mem_block_list+ecx*4], edi
  483.            jne @f
  484.            mov [mem_block_list+ecx*4], edx
  485. @@:
  486.            cmp [mem_block_list+ecx*4], 0
  487.            jne @f
  488.            btr [mem_block_mask], ecx
  489. @@:
  490.            mov esi, [mem_block_list+eax*4]
  491.            mov [mem_block_list+eax*4], edi
  492.            mov [edi+list_fd], esi
  493.            test esi, esi
  494.            jz @f
  495.            mov [esi+list_bk], edi
  496. @@:
  497.            bts [mem_block_mask], eax
  498. .m_eq:
  499.            mov ecx, heap_mutex
  500.            call mutex_unlock
  501.            xor eax, eax
  502.            not eax
  503.            pop edi
  504.            pop esi
  505.            pop ebx
  506.            ret
  507. .insert:
  508.            remove_from_used esi
  509.  
  510.            mov eax, [esi+block_size]
  511.            calc_index eax
  512.  
  513.            mov edi, [mem_block_list+eax*4]
  514.            mov [mem_block_list+eax*4], esi
  515.            mov [esi+list_fd], edi
  516.            test edi, edi
  517.            jz @f
  518.            mov [edi+list_bk], esi
  519. @@:
  520.            bts [mem_block_mask], eax
  521.            mov [esi+block_flags],FREE_BLOCK
  522.            mov ecx, heap_mutex
  523.            call mutex_unlock
  524.            xor eax, eax
  525.            not eax
  526.            pop edi
  527.            pop esi
  528.            pop ebx
  529.            ret
  530. .fail:
  531.            mov ecx, heap_mutex
  532.            call mutex_unlock
  533.            xor eax, eax
  534.            pop edi
  535.            pop esi
  536.            pop ebx
  537.            ret
  538. endp
  539.  
  540. align 4
  541. proc kernel_alloc stdcall, size:dword
  542.            locals
  543.              lin_addr    dd ?
  544.              pages_count dd ?
  545.            endl
  546.  
  547.            push ebx
  548.            push edi
  549.  
  550.            mov eax, [size]
  551.            add eax, 4095
  552.            and eax, not 4095;
  553.            mov [size], eax
  554.            and eax, eax
  555.            jz .err
  556.            mov ebx, eax
  557.            shr ebx, 12
  558.            mov [pages_count], ebx
  559.  
  560.            stdcall alloc_kernel_space, eax
  561.            test eax, eax
  562.            jz .err
  563.            mov [lin_addr], eax
  564.  
  565.            mov ecx, [pages_count]
  566.            mov edx, eax
  567.            mov ebx, ecx
  568.  
  569.            shr ecx, 3
  570.            jz .next
  571.  
  572.            and ebx, not 7
  573.            push ebx
  574.            stdcall alloc_pages, ebx
  575.            pop ecx                   ; yes ecx!!!
  576.            and eax, eax
  577.            jz .err
  578.  
  579.            mov edi, eax
  580.            mov edx, [lin_addr]
  581. @@:
  582.            stdcall map_page,edx,edi,dword PG_SW
  583.            add edx, 0x1000
  584.            add edi, 0x1000
  585.            dec ecx
  586.            jnz @B
  587. .next:
  588.            mov ecx, [pages_count]
  589.            and ecx, 7
  590.            jz .end
  591. @@:
  592.            push ecx
  593.            call alloc_page
  594.            pop ecx
  595.            test eax, eax
  596.            jz .err
  597.  
  598.            stdcall map_page,edx,eax,dword PG_SW
  599.            add edx, 0x1000
  600.            dec ecx
  601.            jnz @B
  602. .end:
  603.            mov eax, [lin_addr]
  604.            pop edi
  605.            pop ebx
  606.            ret
  607. .err:
  608.            xor eax, eax
  609.            pop edi
  610.            pop ebx
  611.            ret
  612. endp
  613.  
  614. align 4
  615. proc kernel_free stdcall, base:dword
  616.            push ebx esi
  617.  
  618.            mov ecx, heap_mutex
  619.            call mutex_lock
  620.  
  621.            mov eax, [base]
  622.            mov esi, [mem_used.fd]
  623. @@:
  624.            cmp esi, mem_used.fd-MEM_LIST_OFFSET
  625.            je .fail
  626.  
  627.            cmp [esi+block_base], eax
  628.            je .found
  629.            mov esi, [esi+list_fd]
  630.            jmp @b
  631. .found:
  632.            cmp [esi+block_flags], USED_BLOCK
  633.            jne .fail
  634.  
  635.            call mutex_unlock
  636.  
  637.            mov ecx, [esi+block_size];
  638.            shr ecx, 12
  639.            call release_pages   ;eax, ecx
  640.            stdcall free_kernel_space, [base]
  641.            pop esi ebx
  642.            ret
  643. .fail:
  644.            call mutex_unlock
  645.            xor eax, eax
  646.            pop esi ebx
  647.            ret
  648. endp
  649.  
  650. restore block_next
  651. restore block_prev
  652. restore block_list
  653. restore block_base
  654. restore block_size
  655. restore block_flags
  656.  
  657. ;;;;;;;;;;;;;;      USER     ;;;;;;;;;;;;;;;;;
  658.  
  659. HEAP_TOP  equ 0x5FC00000
  660.  
  661. align 4
  662. proc init_heap
  663.  
  664.            mov ebx,[current_slot]
  665.            mov eax, [ebx+APPDATA.heap_top]
  666.            test eax, eax
  667.            jz @F
  668.            sub eax,[ebx+APPDATA.heap_base]
  669.            sub eax, 4096
  670.            ret
  671. @@:
  672.            mov esi, [ebx+APPDATA.mem_size]
  673.            add esi, 4095
  674.            and esi, not 4095
  675.            mov [ebx+APPDATA.mem_size], esi
  676.            mov eax, HEAP_TOP
  677.            mov [ebx+APPDATA.heap_base], esi
  678.            mov [ebx+APPDATA.heap_top], eax
  679.  
  680.            sub eax, esi
  681.            shr esi, 10
  682.            mov ecx, eax
  683.            sub eax, 4096
  684.            or ecx, FREE_BLOCK
  685.            mov [page_tabs+esi], ecx
  686.            ret
  687. endp
  688.  
  689. align 4
  690. proc user_alloc stdcall, alloc_size:dword
  691.  
  692.            push ebx
  693.            push esi
  694.            push edi
  695.  
  696.            mov ecx, [alloc_size]
  697.            add ecx, (4095+4096)
  698.            and ecx, not 4095
  699.  
  700.            mov ebx, [current_slot]
  701.            mov esi, dword [ebx+APPDATA.heap_base]  ; heap_base
  702.            mov edi, dword [ebx+APPDATA.heap_top]   ; heap_top
  703. l_0:
  704.            cmp esi, edi
  705.            jae m_exit
  706.  
  707.            mov ebx, esi
  708.            shr ebx, 12
  709.            mov eax, [page_tabs+ebx*4]
  710.            test al, FREE_BLOCK
  711.            jz test_used
  712.            and eax, 0xFFFFF000
  713.            cmp eax, ecx    ;alloc_size
  714.            jb  m_next
  715.            jz  @f
  716.  
  717.            lea edx, [esi+ecx]
  718.            sub eax, ecx
  719.            or al, FREE_BLOCK
  720.            shr edx, 12
  721.            mov [page_tabs+edx*4], eax
  722. @@:
  723.            or ecx, USED_BLOCK
  724.            mov [page_tabs+ebx*4], ecx
  725.            shr ecx, 12
  726.            inc ebx
  727.            dec ecx
  728.            jz  .no
  729. @@:
  730.            mov dword [page_tabs+ebx*4], 2
  731.            inc ebx
  732.            dec ecx
  733.            jnz @B
  734. .no:
  735.  
  736.            mov     edx, [current_slot]
  737.            mov     ebx, [alloc_size]
  738.            add     ebx, 0xFFF
  739.            and     ebx, not 0xFFF
  740.            add     ebx, [edx+APPDATA.mem_size]
  741.            call    update_mem_size
  742.  
  743.            lea eax, [esi+4096]
  744.  
  745.            pop edi
  746.            pop esi
  747.            pop ebx
  748.            ret
  749. test_used:
  750.            test al, USED_BLOCK
  751.            jz m_exit
  752.  
  753.            and eax, 0xFFFFF000
  754. m_next:
  755.            add esi, eax
  756.            jmp l_0
  757. m_exit:
  758.            xor eax, eax
  759.            pop edi
  760.            pop esi
  761.            pop ebx
  762.            ret
  763. endp
  764.  
  765. align 4
  766. proc user_alloc_at stdcall, address:dword, alloc_size:dword
  767.  
  768.            push ebx
  769.            push esi
  770.            push edi
  771.  
  772.            mov ebx, [current_slot]
  773.            mov edx, [address]
  774.            and edx, not 0xFFF
  775.            mov [address], edx
  776.            sub edx, 0x1000
  777.            jb  .error
  778.            mov esi, [ebx+APPDATA.heap_base]
  779.            mov edi, [ebx+APPDATA.heap_top]
  780.            cmp edx, esi
  781.            jb  .error
  782. .scan:
  783.            cmp esi, edi
  784.            jae .error
  785.            mov ebx, esi
  786.            shr ebx, 12
  787.            mov eax, [page_tabs+ebx*4]
  788.            mov ecx, eax
  789.            and ecx, 0xFFFFF000
  790.            add ecx, esi
  791.            cmp edx, ecx
  792.            jb  .found
  793.            mov esi, ecx
  794.            jmp .scan
  795. .error:
  796.            xor eax, eax
  797.            pop edi
  798.            pop esi
  799.            pop ebx
  800.            ret
  801. .found:
  802.            test al, FREE_BLOCK
  803.            jz  .error
  804.            mov eax, ecx
  805.            sub eax, edx
  806.            sub eax, 0x1000
  807.            cmp eax, [alloc_size]
  808.            jb  .error
  809.  
  810. ; Here we have 1 big free block which includes requested area.
  811. ; In general, 3 other blocks must be created instead:
  812. ; free at [esi, edx);
  813. ; busy at [edx, edx+0x1000+ALIGN_UP(alloc_size,0x1000));
  814. ; free at [edx+0x1000+ALIGN_UP(alloc_size,0x1000), ecx)
  815. ; First or third block (or both) may be absent.
  816.            mov eax, edx
  817.            sub eax, esi
  818.            jz  .nofirst
  819.            or  al, FREE_BLOCK
  820.            mov [page_tabs+ebx*4], eax
  821. .nofirst:
  822.            mov eax, [alloc_size]
  823.            add eax, 0x1FFF
  824.            and eax, not 0xFFF
  825.            mov ebx, edx
  826.            add edx, eax
  827.            shr ebx, 12
  828.            or  al, USED_BLOCK
  829.            mov [page_tabs+ebx*4], eax
  830.            shr eax, 12
  831.            dec eax
  832.            jz  .second_nofill
  833.            inc ebx
  834. .fill:
  835.            mov dword [page_tabs+ebx*4], 2
  836.            inc ebx
  837.            dec eax
  838.            jnz .fill
  839. .second_nofill:
  840.            sub ecx, edx
  841.            jz  .nothird
  842.            or  cl, FREE_BLOCK
  843.            mov [page_tabs+ebx*4], ecx
  844. .nothird:
  845.  
  846.            mov     edx, [current_slot]
  847.            mov     ebx, [alloc_size]
  848.            add     ebx, 0xFFF
  849.            and     ebx, not 0xFFF
  850.            add     ebx, [edx+APPDATA.mem_size]
  851.            call    update_mem_size
  852.  
  853.            mov eax, [address]
  854.  
  855.            pop edi
  856.            pop esi
  857.            pop ebx
  858.            ret
  859. endp
  860.  
  861. align 4
  862. proc user_free stdcall, base:dword
  863.  
  864.            push esi
  865.  
  866.            mov esi, [base]
  867.            test esi, esi
  868.            jz .exit
  869.  
  870.            push ebx
  871.  
  872.            xor ebx, ebx
  873.            shr esi, 12
  874.            mov eax, [page_tabs+(esi-1)*4]
  875.            test al, USED_BLOCK
  876.            jz .cantfree
  877.            test al, DONT_FREE_BLOCK
  878.            jnz .cantfree
  879.  
  880.            and eax, not 4095
  881.            mov ecx, eax
  882.            or al, FREE_BLOCK
  883.            mov [page_tabs+(esi-1)*4], eax
  884.            sub ecx, 4096
  885.            mov ebx, ecx
  886.            shr ecx, 12
  887.            jz .released
  888. .release:
  889.            xor eax, eax
  890.            xchg eax, [page_tabs+esi*4]
  891.            test al, 1
  892.            jz @F
  893.            test eax, PG_SHARED
  894.            jnz @F
  895.            call free_page
  896.            mov eax, esi
  897.            shl eax, 12
  898.            invlpg [eax]
  899. @@:
  900.            inc esi
  901.            dec ecx
  902.            jnz .release
  903. .released:
  904.            push edi
  905.  
  906.            mov edx, [current_slot]
  907.            mov esi, dword [edx+APPDATA.heap_base]
  908.            mov edi, dword [edx+APPDATA.heap_top]
  909.            sub ebx, [edx+APPDATA.mem_size]
  910.            neg ebx
  911.            call update_mem_size
  912.            call user_normalize
  913.            pop edi
  914.            pop ebx
  915.            pop esi
  916.            ret
  917. .exit:
  918.            xor eax, eax
  919.            inc eax
  920.            pop esi
  921.            ret
  922. .cantfree:
  923.            xor eax, eax
  924.            pop ebx
  925.            pop esi
  926.            ret
  927. endp
  928.  
  929. user_normalize:
  930. ; in: esi=heap_base, edi=heap_top
  931. ; out: eax=0 <=> OK
  932. ; destroys: ebx,edx,esi,edi
  933.            shr esi, 12
  934.            shr edi, 12
  935. @@:
  936.            mov eax, [page_tabs+esi*4]
  937.            test al, USED_BLOCK
  938.            jz .test_free
  939.            shr eax, 12
  940.            add esi, eax
  941.            jmp @B
  942. .test_free:
  943.            test al, FREE_BLOCK
  944.            jz .err
  945.            mov edx, eax
  946.            shr edx, 12
  947.            add edx, esi
  948.            cmp edx, edi
  949.            jae .exit
  950.  
  951.            mov ebx, [page_tabs+edx*4]
  952.            test bl, USED_BLOCK
  953.            jz .next_free
  954.  
  955.            shr ebx, 12
  956.            add edx, ebx
  957.            mov esi, edx
  958.            jmp @B
  959. .next_free:
  960.            test bl, FREE_BLOCK
  961.            jz .err
  962.            and dword [page_tabs+edx*4], 0
  963.            add eax, ebx
  964.            and eax, not 4095
  965.            or eax, FREE_BLOCK
  966.            mov [page_tabs+esi*4], eax
  967.            jmp @B
  968. .exit:
  969.            xor eax, eax
  970.            inc eax
  971.            ret
  972. .err:
  973.            xor eax, eax
  974.            ret
  975.  
  976. user_realloc:
  977. ; in: eax = pointer, ebx = new size
  978. ; out: eax = new pointer or NULL
  979.         test    eax, eax
  980.         jnz     @f
  981. ; realloc(NULL,sz) - same as malloc(sz)
  982.         push    ebx
  983.         call    user_alloc
  984.         ret
  985. @@:
  986.         push    ecx edx
  987.         lea     ecx, [eax - 0x1000]
  988.         shr     ecx, 12
  989.         mov     edx, [page_tabs+ecx*4]
  990.         test    dl, USED_BLOCK
  991.         jnz     @f
  992. ; attempt to realloc invalid pointer
  993. .ret0:
  994.         pop     edx ecx
  995.         xor     eax, eax
  996.         ret
  997. @@:
  998.         test    dl, DONT_FREE_BLOCK
  999.         jnz     .ret0
  1000.         add     ebx, 0x1FFF
  1001.         shr     edx, 12
  1002.         shr     ebx, 12
  1003. ; edx = allocated size, ebx = new size
  1004.         add     edx, ecx
  1005.         add     ebx, ecx
  1006.         cmp     edx, ebx
  1007.         jb      .realloc_add
  1008. ; release part of allocated memory
  1009. .loop:
  1010.         cmp     edx, ebx
  1011.         jz      .release_done
  1012.         dec     edx
  1013.         xor     eax, eax
  1014.         xchg    eax, [page_tabs+edx*4]
  1015.         test    al, 1
  1016.         jz      .loop
  1017.         call    free_page
  1018.         mov     eax, edx
  1019.         shl     eax, 12
  1020.         invlpg  [eax]
  1021.         jmp     .loop
  1022. .release_done:
  1023.         sub     ebx, ecx
  1024.         cmp     ebx, 1
  1025.         jnz     .nofreeall
  1026.         mov     eax, [page_tabs+ecx*4]
  1027.         and     eax, not 0xFFF
  1028.         mov     edx, [current_slot]
  1029.         mov     ebx, [APPDATA.mem_size+edx]
  1030.         sub     ebx, eax
  1031.         add     ebx, 0x1000
  1032.         or      al, FREE_BLOCK
  1033.         mov     [page_tabs+ecx*4], eax
  1034.         push    esi edi
  1035.         mov     esi, [APPDATA.heap_base+edx]
  1036.         mov     edi, [APPDATA.heap_top+edx]
  1037.         call    update_mem_size
  1038.         call    user_normalize
  1039.         pop     edi esi
  1040.         jmp     .ret0   ; all freed
  1041. .nofreeall:
  1042.         sub     edx, ecx
  1043.         shl     ebx, 12
  1044.         or      ebx, USED_BLOCK
  1045.         xchg    [page_tabs+ecx*4], ebx
  1046.         shr     ebx, 12
  1047.         sub     ebx, edx
  1048.         push    ebx ecx edx
  1049.         mov     edx, [current_slot]
  1050.         shl     ebx, 12
  1051.         sub     ebx, [APPDATA.mem_size+edx]
  1052.         neg     ebx
  1053.         call    update_mem_size
  1054.         pop     edx ecx ebx
  1055.         lea     eax, [ecx+1]
  1056.         shl     eax, 12
  1057.         push    eax
  1058.         add     ecx, edx
  1059.         lea     edx, [ecx+ebx]
  1060.         shl     ebx, 12
  1061.         jz      .ret
  1062.         push    esi
  1063.         mov     esi, [current_slot]
  1064.         mov     esi, [APPDATA.heap_top+esi]
  1065.         shr     esi, 12
  1066. @@:
  1067.         cmp     edx, esi
  1068.         jae     .merge_done
  1069.         mov     eax, [page_tabs+edx*4]
  1070.         test    al, USED_BLOCK
  1071.         jnz     .merge_done
  1072.         and     dword [page_tabs+edx*4], 0
  1073.         shr     eax, 12
  1074.         add     edx, eax
  1075.         shl     eax, 12
  1076.         add     ebx, eax
  1077.         jmp     @b
  1078. .merge_done:
  1079.         pop     esi
  1080.         or      ebx, FREE_BLOCK
  1081.         mov     [page_tabs+ecx*4], ebx
  1082. .ret:
  1083.         pop     eax edx ecx
  1084.         ret
  1085. .realloc_add:
  1086. ; get some additional memory
  1087.         mov     eax, [current_slot]
  1088.         mov     eax, [APPDATA.heap_top+eax]
  1089.         shr     eax, 12
  1090.         cmp     edx, eax
  1091.         jae     .cant_inplace
  1092.         mov     eax, [page_tabs+edx*4]
  1093.         test    al, FREE_BLOCK
  1094.         jz      .cant_inplace
  1095.         shr     eax, 12
  1096.         add     eax, edx
  1097.         sub     eax, ebx
  1098.         jb      .cant_inplace
  1099.         jz      @f
  1100.         shl     eax, 12
  1101.         or      al, FREE_BLOCK
  1102.         mov     [page_tabs+ebx*4], eax
  1103. @@:
  1104.         mov     eax, ebx
  1105.         sub     eax, ecx
  1106.         shl     eax, 12
  1107.         or      al, USED_BLOCK
  1108.         mov     [page_tabs+ecx*4], eax
  1109.         lea     eax, [ecx+1]
  1110.         shl     eax, 12
  1111.         push    eax
  1112.         push    edi
  1113.         lea     edi, [page_tabs+edx*4]
  1114.         mov     eax, 2
  1115.         sub     ebx, edx
  1116.         mov     ecx, ebx
  1117.         cld
  1118.         rep     stosd
  1119.         pop     edi
  1120.         mov     edx, [current_slot]
  1121.         shl     ebx, 12
  1122.         add     ebx, [APPDATA.mem_size+edx]
  1123.         call    update_mem_size
  1124.         pop     eax edx ecx
  1125.         ret
  1126. .cant_inplace:
  1127.         push    esi edi
  1128.         mov     eax, [current_slot]
  1129.         mov     esi, [APPDATA.heap_base+eax]
  1130.         mov     edi, [APPDATA.heap_top+eax]
  1131.         shr     esi, 12
  1132.         shr     edi, 12
  1133.         sub     ebx, ecx
  1134. .find_place:
  1135.         cmp     esi, edi
  1136.         jae     .place_not_found
  1137.         mov     eax, [page_tabs+esi*4]
  1138.         test    al, FREE_BLOCK
  1139.         jz      .next_place
  1140.         shr     eax, 12
  1141.         cmp     eax, ebx
  1142.         jae     .place_found
  1143.         add     esi, eax
  1144.         jmp     .find_place
  1145. .next_place:
  1146.         shr     eax, 12
  1147.         add     esi, eax
  1148.         jmp     .find_place
  1149. .place_not_found:
  1150.         pop     edi esi
  1151.         jmp     .ret0
  1152. .place_found:
  1153.         sub     eax, ebx
  1154.         jz      @f
  1155.         push    esi
  1156.         add     esi, ebx
  1157.         shl     eax, 12
  1158.         or      al, FREE_BLOCK
  1159.         mov     [page_tabs+esi*4], eax
  1160.         pop     esi
  1161. @@:
  1162.         mov     eax, ebx
  1163.         shl     eax, 12
  1164.         or      al, USED_BLOCK
  1165.         mov     [page_tabs+esi*4], eax
  1166.         inc     esi
  1167.         mov     eax, esi
  1168.         shl     eax, 12
  1169.         push    eax
  1170.         mov     eax, [page_tabs+ecx*4]
  1171.         and     eax, not 0xFFF
  1172.         or      al, FREE_BLOCK
  1173.         sub     edx, ecx
  1174.         mov     [page_tabs+ecx*4], eax
  1175.         inc     ecx
  1176.         dec     ebx
  1177.         dec     edx
  1178.         jz      .no
  1179. @@:
  1180.         xor     eax, eax
  1181.         xchg    eax, [page_tabs+ecx*4]
  1182.         mov     [page_tabs+esi*4], eax
  1183.         mov     eax, ecx
  1184.         shl     eax, 12
  1185.         invlpg  [eax]
  1186.         inc     esi
  1187.         inc     ecx
  1188.         dec     ebx
  1189.         dec     edx
  1190.         jnz     @b
  1191. .no:
  1192.         push    ebx
  1193.         mov     edx, [current_slot]
  1194.         shl     ebx, 12
  1195.         add     ebx, [APPDATA.mem_size+edx]
  1196.         call    update_mem_size
  1197.         pop     ebx
  1198. @@:
  1199.         mov     dword [page_tabs+esi*4], 2
  1200.         inc     esi
  1201.         dec     ebx
  1202.         jnz     @b
  1203.         pop     eax edi esi edx ecx
  1204.         ret
  1205.  
  1206. if 0
  1207. align 4
  1208. proc alloc_dll
  1209.            pushf
  1210.            cli
  1211.            bsf eax, [dll_map]
  1212.            jnz .find
  1213.            popf
  1214.            xor eax, eax
  1215.            ret
  1216. .find:
  1217.            btr [dll_map], eax
  1218.            popf
  1219.            shl eax, 5
  1220.            add eax, dll_tab
  1221.            ret
  1222. endp
  1223.  
  1224. align 4
  1225. proc alloc_service
  1226.            pushf
  1227.            cli
  1228.            bsf eax, [srv_map]
  1229.            jnz .find
  1230.            popf
  1231.            xor eax, eax
  1232.            ret
  1233. .find:
  1234.            btr [srv_map], eax
  1235.            popf
  1236.            shl eax,0x02
  1237.            lea eax,[srv_tab+eax+eax*8]   ;srv_tab+eax*36
  1238.            ret
  1239. endp
  1240.  
  1241. end if
  1242.  
  1243.  
  1244. ;;;;;;;;;;;;;;      SHARED      ;;;;;;;;;;;;;;;;;
  1245.  
  1246.  
  1247. ; param
  1248. ;  eax= shm_map object
  1249.  
  1250. align 4
  1251. destroy_smap:
  1252.  
  1253.            pushfd
  1254.            cli
  1255.  
  1256.            push esi
  1257.            push edi
  1258.  
  1259.            mov edi, eax
  1260.            mov esi, [eax+SMAP.parent]
  1261.            test esi, esi
  1262.            jz .done
  1263.  
  1264.            lock dec [esi+SMEM.refcount]
  1265.            jnz .done
  1266.  
  1267.            mov ecx, [esi+SMEM.bk]
  1268.            mov edx, [esi+SMEM.fd]
  1269.  
  1270.            mov [ecx+SMEM.fd], edx
  1271.            mov [edx+SMEM.bk], ecx
  1272.  
  1273.            stdcall kernel_free, [esi+SMEM.base]
  1274.            mov eax, esi
  1275.            call free
  1276. .done:
  1277.            mov eax, edi
  1278.            call destroy_kernel_object
  1279.  
  1280.            pop edi
  1281.            pop esi
  1282.            popfd
  1283.  
  1284.            ret
  1285.  
  1286. E_NOTFOUND      equ  5
  1287. E_ACCESS        equ 10
  1288. E_NOMEM         equ 30
  1289. E_PARAM         equ 33
  1290.  
  1291. SHM_READ        equ 0
  1292. SHM_WRITE       equ 1
  1293.  
  1294. SHM_ACCESS_MASK equ 3
  1295.  
  1296. SHM_OPEN        equ (0 shl 2)
  1297. SHM_OPEN_ALWAYS equ (1 shl 2)
  1298. SHM_CREATE      equ (2 shl 2)
  1299.  
  1300. SHM_OPEN_MASK   equ (3 shl 2)
  1301.  
  1302. align 4
  1303. proc shmem_open stdcall name:dword, size:dword, access:dword
  1304.            locals
  1305.               action         dd ?
  1306.               owner_access   dd ?
  1307.               mapped         dd ?
  1308.            endl
  1309.  
  1310.            push ebx
  1311.            push esi
  1312.            push edi
  1313.  
  1314.            mov [mapped], 0
  1315.            mov [owner_access], 0
  1316.  
  1317.            pushfd                      ;mutex required
  1318.            cli
  1319.  
  1320.            mov eax, [access]
  1321.            and eax, SHM_OPEN_MASK
  1322.            mov [action], eax
  1323.  
  1324.            mov ebx, [name]
  1325.            test ebx, ebx
  1326.            mov edx, E_PARAM
  1327.            jz .fail
  1328.  
  1329.            mov esi, [shmem_list.fd]
  1330. align 4
  1331. @@:
  1332.            cmp esi, shmem_list
  1333.            je .not_found
  1334.  
  1335.            lea edx, [esi+SMEM.name] ; link , base, size
  1336.            stdcall strncmp, edx, ebx, 32
  1337.            test eax, eax
  1338.            je .found
  1339.  
  1340.            mov esi, [esi+SMEM.fd]
  1341.            jmp @B
  1342.  
  1343. .not_found:
  1344.            mov eax, [action]
  1345.  
  1346.            cmp eax, SHM_OPEN
  1347.            mov edx, E_NOTFOUND
  1348.            je .fail
  1349.  
  1350.            cmp eax, SHM_CREATE
  1351.            mov edx, E_PARAM
  1352.            je .create_shm
  1353.  
  1354.            cmp eax, SHM_OPEN_ALWAYS
  1355.            jne .fail
  1356.  
  1357. .create_shm:
  1358.  
  1359.            mov ecx, [size]
  1360.            test ecx, ecx
  1361.            jz .fail
  1362.  
  1363.            add ecx, 4095
  1364.            and ecx, -4096
  1365.            mov [size], ecx
  1366.  
  1367.            mov eax, SMEM.sizeof
  1368.            call malloc
  1369.            test eax, eax
  1370.            mov esi, eax
  1371.            mov edx, E_NOMEM
  1372.            jz .fail
  1373.  
  1374.            stdcall kernel_alloc, [size]
  1375.            test eax, eax
  1376.            mov [mapped], eax
  1377.            mov edx, E_NOMEM
  1378.            jz .cleanup
  1379.  
  1380.            mov ecx, [size]
  1381.            mov edx, [access]
  1382.            and edx, SHM_ACCESS_MASK
  1383.  
  1384.            mov [esi+SMEM.base], eax
  1385.            mov [esi+SMEM.size], ecx
  1386.            mov [esi+SMEM.access], edx
  1387.            mov [esi+SMEM.refcount], 0
  1388.            mov [esi+SMEM.name+28], 0
  1389.  
  1390.            lea eax, [esi+SMEM.name]
  1391.            stdcall strncpy, eax, [name], 31
  1392.  
  1393.            mov eax, [shmem_list.fd]
  1394.            mov [esi+SMEM.bk], shmem_list
  1395.            mov [esi+SMEM.fd], eax
  1396.  
  1397.            mov [eax+SMEM.bk], esi
  1398.            mov [shmem_list.fd], esi
  1399.  
  1400.            mov [action], SHM_OPEN
  1401.            mov [owner_access], SHM_WRITE
  1402.  
  1403. .found:
  1404.            mov eax, [action]
  1405.  
  1406.            cmp eax, SHM_CREATE
  1407.            mov edx, E_ACCESS
  1408.            je .exit
  1409.  
  1410.            cmp eax, SHM_OPEN
  1411.            mov edx, E_PARAM
  1412.            je .create_map
  1413.  
  1414.            cmp eax, SHM_OPEN_ALWAYS
  1415.            jne .fail
  1416.  
  1417. .create_map:
  1418.  
  1419.            mov eax, [access]
  1420.            and eax, SHM_ACCESS_MASK
  1421.            cmp eax, [esi+SMEM.access]
  1422.            mov [access], eax
  1423.            mov edx, E_ACCESS
  1424.            ja .fail
  1425.  
  1426.            mov ebx, [CURRENT_TASK]
  1427.            shl ebx, 5
  1428.            mov ebx, [CURRENT_TASK+ebx+4]
  1429.            mov eax, SMAP.sizeof
  1430.  
  1431.            call create_kernel_object
  1432.            test eax, eax
  1433.            mov edi, eax
  1434.            mov edx, E_NOMEM
  1435.            jz .fail
  1436.  
  1437.            inc [esi+SMEM.refcount]
  1438.  
  1439.            mov [edi+SMAP.magic], 'SMAP'
  1440.            mov [edi+SMAP.destroy], destroy_smap
  1441.            mov [edi+SMAP.parent], esi
  1442.            mov [edi+SMAP.base], 0
  1443.  
  1444.            stdcall user_alloc, [esi+SMEM.size]
  1445.            test eax, eax
  1446.            mov [mapped], eax
  1447.            mov edx, E_NOMEM
  1448.            jz .cleanup2
  1449.  
  1450.            mov [edi+SMAP.base], eax
  1451.  
  1452.            mov ecx, [esi+SMEM.size]
  1453.            mov [size], ecx
  1454.  
  1455.            shr ecx, 12
  1456.            shr eax, 10
  1457.  
  1458.            mov esi, [esi+SMEM.base]
  1459.            shr esi, 10
  1460.            lea edi, [page_tabs+eax]
  1461.            add esi, page_tabs
  1462.  
  1463.            mov edx, [access]
  1464.            or edx, [owner_access]
  1465.            shl edx, 1
  1466.            or edx, PG_USER+PG_SHARED
  1467. @@:
  1468.            lodsd
  1469.            and eax, 0xFFFFF000
  1470.            or eax, edx
  1471.            stosd
  1472.            loop @B
  1473.  
  1474.            xor edx, edx
  1475.  
  1476.            cmp [owner_access], 0
  1477.            jne .fail
  1478. .exit:
  1479.            mov edx, [size]
  1480. .fail:
  1481.            mov eax, [mapped]
  1482.  
  1483.            popfd
  1484.            pop edi
  1485.            pop esi
  1486.            pop ebx
  1487.            ret
  1488. .cleanup:
  1489.            mov [size], edx
  1490.            mov eax, esi
  1491.            call free
  1492.            jmp .exit
  1493.  
  1494. .cleanup2:
  1495.            mov [size], edx
  1496.            mov eax, edi
  1497.            call destroy_smap
  1498.            jmp .exit
  1499. endp
  1500.  
  1501. align 4
  1502. proc shmem_close stdcall, name:dword
  1503.  
  1504.            mov eax, [name]
  1505.            test eax, eax
  1506.            jz .fail
  1507.  
  1508.            push esi
  1509.            push edi
  1510.            pushfd
  1511.            cli
  1512.  
  1513.            mov esi, [current_slot]
  1514.            add esi, APP_OBJ_OFFSET
  1515. .next:
  1516.            mov eax, [esi+APPOBJ.fd]
  1517.            test eax, eax
  1518.            jz @F
  1519.  
  1520.            cmp eax, esi
  1521.            mov esi, eax
  1522.            je @F
  1523.  
  1524.            cmp [eax+SMAP.magic], 'SMAP'
  1525.            jne .next
  1526.  
  1527.            mov edi, [eax+SMAP.parent]
  1528.            test edi, edi
  1529.            jz .next
  1530.  
  1531.            lea edi, [edi+SMEM.name]
  1532.            stdcall strncmp, [name], edi, 32
  1533.            test eax, eax
  1534.            jne .next
  1535.  
  1536.            stdcall user_free, [esi+SMAP.base]
  1537.  
  1538.            mov eax,esi
  1539.            call [esi+APPOBJ.destroy]
  1540. @@:
  1541.            popfd
  1542.            pop edi
  1543.            pop esi
  1544. .fail:
  1545.            ret
  1546. endp
  1547.