Subversion Repositories Kolibri OS

Rev

Rev 9047 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2021. All rights reserved. ;;
  4. ;;  Distributed under terms of the GNU General Public License.  ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 9048 $
  9.  
  10.  
  11. GREEDY_KERNEL  = 0
  12.  
  13. struct  APP_HEADER_00_
  14.         banner          dq ?
  15.         version         dd ?    ;+8
  16.         start           dd ?    ;+12
  17.         i_end           dd ?    ;+16
  18.         mem_size        dd ?    ;+20
  19.         i_param         dd ?    ;+24
  20. ends
  21.  
  22. struct  APP_HEADER_01_
  23.         banner          dq ?
  24.         version         dd ?    ;+8
  25.         start           dd ?    ;+12
  26.         i_end           dd ?    ;+16
  27.         mem_size        dd ?    ;+20
  28.         stack_top       dd ?    ;+24
  29.         i_param         dd ?    ;+28
  30.         i_icon          dd ?    ;+32
  31. ends
  32.  
  33. struct  APP_HDR
  34.         cmdline         rd 1    ;0x00
  35.         path            rd 1    ;0x04
  36.         eip             rd 1    ;0x08
  37.         esp             rd 1    ;0x0C
  38.         _edata          rd 1    ;0x10
  39.         _emem           rd 1    ;0x14
  40.         img_base        rd 1    ;0x18
  41.         img_size        rd 1
  42.         filename_size   rd 1
  43.         cmdline_size    rd 1
  44.         path_string     rd 1
  45.         pedescr         rd 1
  46. ends
  47.  
  48. ; Pointer to this structure is passed as the third argument
  49. ; to usermode PE loader by the kernel.
  50. struct kernel_init_data
  51. version         dw      ?
  52. flags           dw      ?
  53. syscall_method  dd      ?
  54. ; either one of SYSCALL_METHOD_xxx or pointer to procedure
  55. exe_base        dd      ?
  56. stack_base      dd      ?
  57. stack_size      dd      ?
  58. exe_path        dd      ?
  59. command_line    dd      ?
  60. environment     dd      ?
  61. ends
  62. SYSCALL_METHOD_I40 = 1
  63. SYSCALL_METHOD_SYSENTER = 2
  64. SYSCALL_METHOD_SYSCALL = 3
  65.  
  66. macro _clear_ op
  67. {
  68.         mov     ecx, op/4
  69.         xor     eax, eax
  70.         cld
  71.         rep stosd
  72. }
  73.  
  74. align 4
  75. _strnlen:
  76.         mov     edx, ecx
  77.         xor     eax, eax
  78.         repne scasb
  79.         jne     @F
  80.         inc     ecx
  81. @@:
  82.         mov     eax, edx
  83.         sub     eax, ecx
  84.         retn
  85.  
  86. fs_execute_from_sysdir:
  87.         xor     ebx, ebx
  88. fs_execute_from_sysdir_param:
  89.         stdcall kernel_alloc, maxPathLength
  90.         push    eax ebx
  91.         mov     esi, ebp
  92.         mov     edi, eax
  93.         xor     eax, eax
  94.         call    getFullPath
  95.         pop     ecx ebx
  96.         xor     edx, edx
  97. ; @brief Executes a program
  98. ; @param edx Flags
  99. ; @param ecx Commandline
  100. ; @param ebx Absolute file path
  101. ; @param eax String length
  102. ; @returns Negated error code or new process number
  103. proc fs_execute
  104.     locals
  105.         cmdline         rd  1
  106.         flags           rd  1
  107.         slot            rd  1  ; index of new thread slot
  108.         slot_base       rd  1  ; base address of it
  109. ; app header data
  110.         hdr_cmdline     rd  1
  111.         hdr_path        rd  1
  112.         hdr_eip         rd  1
  113.         hdr_esp         rd  1
  114.         hdr_edata       rd  1
  115.         hdr_emem        rd  1
  116.         file_base       rd  1
  117.         file_size       rd  1
  118.         filename_size   rd  1
  119.         cmdline_size    rd  1
  120.         path_string     rd  1
  121.         pedescr         rd  1
  122.     endl
  123.  
  124.         mov     [flags], edx
  125.         mov     [cmdline], ecx
  126.         mov     [path_string], ebx
  127.         mov     [filename_size], eax
  128.         mov     edi, -ERROR_FILE_NOT_FOUND
  129.         test    eax, eax
  130.         jz      .err_file
  131.         stdcall load_file, ebx
  132.         test    eax, eax
  133.         jz      .err_file
  134.         stdcall load_file_maybe_pe, [path_string]
  135.         mov     [pedescr], esi
  136.         mov     [file_base], eax
  137.         mov     [file_size], ebx
  138.  
  139.         test    esi, esi
  140.         jnz     .file_ok
  141.  
  142.         mov     edi, eax
  143.         cmp     eax, -0x1000
  144.         ja      .err_file
  145.  
  146.         lea     ebx, [hdr_cmdline]
  147.         call    test_app_header  ; fill our app header data locals with values from header of given program (if its correct)
  148.         mov     edi, -TASKMAN_ERROR_NOT_A_EXECUTABLE
  149.         test    eax, eax
  150.         jz      .err_hdr
  151.  
  152. .file_ok:
  153.         call    lock_application_table
  154.         call    alloc_thread_slot   ; create a slot for new thread
  155.         mov     edi, -TASKMAN_ERROR_TOO_MANY_PROCESSES
  156.         test    eax, eax
  157.         jz      .err_0
  158.  
  159.         mov     [slot], eax
  160.         shl     eax, 8
  161.         lea     edi, [SLOT_BASE+eax]
  162.         mov     [slot_base], edi
  163. ; clean extended information about process
  164.         mov     ecx, sizeof.APPDATA/4
  165.         xor     eax, eax
  166.         cld
  167.         rep stosd
  168. ; write application name ( APPDATA.appname )
  169.         stdcall strrchr, [path_string], '/'
  170.         lea     esi, [eax+1]    ; -> name without path
  171.         mov     ecx, 11
  172.         mov     edi, [slot_base]
  173. @@:
  174.         call    utf8to16
  175.         call    uni2ansi_char
  176.         cmp     al, '.'
  177.         jz      @f
  178.         test    al, al
  179.         jz      @f
  180.         stosb
  181.         loop    @b
  182. @@:
  183.         mov     edi, [cmdline]
  184.         xor     eax, eax
  185.         test    edi, edi
  186.         jz      @f
  187.         mov     ecx, 65535
  188.         call    _strnlen
  189.         cmp     eax, 256
  190.         jb      @f
  191. ; if cmdline length >= 256 then increase needed memory size by this length
  192.         lea     ebx, [eax+1]
  193.         add     [hdr_emem], ebx
  194. @@:
  195.         mov     [cmdline_size], eax
  196.         xor     eax, eax
  197.         cmp     [pedescr], eax
  198.         jz      @f
  199.         mov     [hdr_eip], eax
  200.         mov     [hdr_esp], eax
  201.         mov     [hdr_emem], eax
  202. @@:
  203.         stdcall create_process, [hdr_emem]  ; create a new process
  204.         mov     edi, -TASKMAN_ERROR_OUT_OF_MEMORY
  205.         test    eax, eax
  206.         jz      .err_hdr
  207.  
  208. ; add new process to the list
  209.         mov     ebx, [sys_proc+LHEAD.prev]
  210.         __list_add eax, ebx, sys_proc
  211. ; fill the structure fields:
  212.         mov     ebx, [hdr_emem]
  213.         mov     [eax+PROC.mem_used], ebx
  214.  
  215. ; write that main thread of app belongs to new process
  216.         mov     ebx, [slot_base]
  217.         mov     [ebx+APPDATA.process], eax
  218.  
  219. ; initialize the thread list of process: at this moment it consists only of one main thread
  220.         lea     edx, [ebx+APPDATA.list]
  221.         lea     ecx, [eax+PROC.thr_list]
  222.         list_add_tail edx, ecx
  223.  
  224. ; allocate space and copy app header data locals and cmdline string there, put pointer to exec_params of new thread
  225.         mov     eax, [cmdline_size]
  226.         add     eax, sizeof.APP_HDR
  227.         stdcall kernel_alloc, eax
  228.         mov     [ebx+APPDATA.exec_params], eax
  229.         mov     edi, eax
  230.         lea     esi, [hdr_cmdline]
  231.         mov     ecx, sizeof.APP_HDR/4
  232.         rep movsd
  233.         mov     ecx, [cmdline_size]
  234.         mov     esi, [cmdline]
  235.         rep movsb
  236. ; set other parameters of application
  237.         lea     eax, [hdr_cmdline]
  238.         stdcall set_app_params , [slot], eax, [flags]
  239.         mov     eax, [process_number]   ; return process number
  240.         call    unlock_application_table
  241.         ret
  242.  
  243. .err_0:
  244.         mov     esi, [pedescr]
  245.         test    esi, esi
  246.         jz      @f
  247.         call    dereference_pe
  248. @@:
  249.         call    unlock_application_table
  250. .err_hdr:
  251.         stdcall kernel_free, [file_base]
  252. .err_file:
  253.         stdcall kernel_free, [path_string]
  254.         mov     eax, edi
  255.         ret
  256. endp
  257.  
  258. align 4
  259. test_app_header:
  260.        virtual at eax
  261.          APP_HEADER_00 APP_HEADER_00_
  262.        end virtual
  263.        virtual at eax
  264.          APP_HEADER_01 APP_HEADER_01_
  265.        end virtual
  266.  
  267.         cmp     dword [eax], 'MENU'
  268.         jne     .fail
  269.         cmp     word [eax+4], 'ET'
  270.         jne     .fail
  271.  
  272.         cmp     [eax+6], word '00'
  273.         jne     .check_01_header
  274.  
  275.         mov     ecx, [APP_HEADER_00.start]
  276.         mov     [ebx+APP_HDR.eip], ecx
  277.         mov     edx, [APP_HEADER_00.mem_size]
  278.         mov     [ebx+APP_HDR._emem], edx
  279.         shr     edx, 1
  280.         sub     edx, 0x10
  281.         mov     [ebx+APP_HDR.esp], edx
  282.         mov     ecx, [APP_HEADER_00.i_param]
  283.         mov     [ebx+APP_HDR.cmdline], ecx
  284.         mov     [ebx+APP_HDR.path], 0
  285.         mov     edx, [APP_HEADER_00.i_end]
  286.         mov     [ebx+APP_HDR._edata], edx
  287.         ret
  288.  
  289.  .check_01_header:
  290.  
  291.         cmp     [eax+6], word '01'
  292.         je      @f
  293.         cmp     [eax+6], word '02'
  294.         jne     .fail
  295. @@:
  296.         mov     ecx, [APP_HEADER_01.start]
  297.         mov     [ebx+0x08], ecx
  298.         mov     edx, [APP_HEADER_01.mem_size]
  299.  
  300. ; \begin{diamond}[20.08.2006]
  301. ; sanity check (functions 19,58 load app_i_end bytes and that must
  302. ; fit in allocated memory to prevent kernel faults)
  303.         cmp     edx, [APP_HEADER_01.i_end]
  304.         jb      .fail
  305. ; \end{diamond}[20.08.2006]
  306.  
  307.         mov     [ebx+APP_HDR._emem], edx
  308.         mov     ecx, [APP_HEADER_01.stack_top]
  309.         mov     [ebx+APP_HDR.esp], ecx
  310.         mov     edx, [APP_HEADER_01.i_param]
  311.         mov     [ebx+APP_HDR.cmdline], edx
  312.         mov     ecx, [APP_HEADER_01.i_icon]
  313.         mov     [ebx+APP_HDR.path], ecx
  314.         mov     edx, [APP_HEADER_01.i_end]
  315.         mov     [ebx+APP_HDR._edata], edx
  316.         ret
  317. .fail:
  318.         xor     eax, eax
  319.         ret
  320.  
  321. align 4
  322. alloc_thread_slot:
  323. ;input:
  324. ;  none
  325. ;result:
  326. ;  eax=[new_thread_slot]<>0 - ok
  327. ;      0 - failed.
  328. ;This function find least empty slot.
  329. ;It doesn't increase [thread_count]!
  330.  
  331.  
  332.         mov     edx, thr_slot_map
  333.         pushfd
  334.         cli
  335. .l1:
  336.         bsf     eax, [edx]
  337.         jnz     .found
  338.         add     edx, 4
  339.         cmp     edx, thr_slot_map+32
  340.         jb      .l1
  341.  
  342.         popfd
  343.         xor     eax, eax
  344.         ret
  345. .found:
  346.         btr     [edx], eax
  347.         sub     edx, thr_slot_map
  348.         lea     eax, [eax+edx*8]
  349.         popfd
  350.         ret
  351.  
  352. align 4
  353. proc create_process stdcall, app_size:dword
  354.        locals
  355.          process     dd ?
  356.          app_tabs    dd ?
  357.        endl
  358.  
  359.         push    ebx
  360.         push    esi
  361.         push    edi
  362.  
  363.         xor     eax, eax
  364.         mov     [process], eax
  365.  
  366.         mov     eax, [app_size]
  367.         add     eax, 0x3FFFFF
  368.         shr     eax, 22
  369.         mov     [app_tabs], eax
  370.  
  371.         stdcall kernel_alloc, 0x2000
  372.         test    eax, eax
  373.         jz      .fail
  374.         mov     [process], eax
  375.  
  376.         lea     edi, [eax+PROC.heap_base]
  377.  
  378.         list_init eax
  379.         add     eax, PROC.thr_list
  380.         list_init eax
  381.         add     eax, PROC.smap_list - PROC.thr_list
  382.         list_init eax
  383.  
  384.         lea     ecx, [eax+PROC.heap_lock-PROC.smap_list]
  385.         call    mutex_init
  386.  
  387.         mov     ecx, (PROC.ht_free-PROC.heap_base)/4
  388.         xor     eax, eax
  389.         cld
  390.         rep stosd
  391.  
  392.         mov     [edi], dword (PROC.pdt_0 - PROC.htab)/4 - 3
  393.         mov     [edi+4], dword 3           ;reserve handles for stdin stdout and stderr
  394.         mov     ecx, (PROC.pdt_0 - PROC.htab)/4
  395.         add     edi, 8
  396.         inc     eax
  397. @@:
  398.         stosd
  399.         inc     eax
  400.         cmp     eax, ecx
  401.         jbe     @B
  402.  
  403.         mov     eax, edi
  404.         call    get_pg_addr
  405.         mov     [edi-4096+PROC.pdt_0_phys], eax
  406.  
  407.         mov     ecx, (OS_BASE shr 20)/4
  408.         xor     eax, eax
  409.         rep stosd
  410.  
  411.         mov     ecx, (OS_BASE shr 20)/4
  412.         mov     esi, sys_proc+PROC.pdt_0+(OS_BASE shr 20)
  413.         rep movsd
  414.  
  415.         mov     eax, [edi-8192+PROC.pdt_0_phys]
  416.         or      eax, PG_SWR
  417.         mov     [edi-4096+(page_tabs shr 20)], eax
  418.  
  419.         lea     edx, [edi-4096]
  420.         mov     esi, [app_tabs]
  421.         test    esi, esi
  422.         jz      .no_page_dirs
  423.  
  424. .alloc_page_dir:
  425.         call    alloc_page
  426.         test    eax, eax
  427.         jz      .fail
  428.         or      eax, PG_UWR
  429.         mov     [edx], eax
  430.  
  431.         mov     edi, [tmp_task_ptab]
  432.         stdcall map_page, edi, eax, PG_SWR
  433.         mov     ecx, 1024
  434.         xor     eax, eax
  435.         rep stosd
  436.  
  437.         add     edx, 4
  438.         dec     esi
  439.         jnz     .alloc_page_dir
  440.  
  441. .no_page_dirs:
  442.         stdcall map_page, [tmp_task_ptab], 0, PG_UNMAP
  443.         mov     eax, [process]
  444.  
  445.         pop     edi
  446.         pop     esi
  447.         pop     ebx
  448.         ret
  449. .fail:
  450.         mov     ecx, [process]
  451.         jecxz   @F
  452.  
  453.         call    destroy_process
  454. @@:
  455.         xor     eax, eax
  456.         pop     edi
  457.         pop     esi
  458.         pop     ebx
  459.         ret
  460. endp
  461.  
  462. align 4
  463. proc destroy_page_table stdcall, pg_tab:dword
  464.  
  465.         push    esi
  466.  
  467.         mov     esi, [pg_tab]
  468.         mov     ecx, 1024
  469. .free:
  470.         mov     eax, [esi]
  471.         test    eax, 1
  472.         jz      .next
  473.         test    eax, 1 shl 9
  474.         jnz     .next                     ;skip shared pages
  475.         call    free_page
  476. .next:
  477.         add     esi, 4
  478.         dec     ecx
  479.         jnz     .free
  480.         pop     esi
  481.         ret
  482. endp
  483.  
  484. align 4
  485. destroy_process: ;fastcall ecx= ptr to process
  486.  
  487.         lea     eax, [ecx+PROC.thr_list]
  488.         cmp     eax, [eax+LHEAD.next]
  489.         jne     .exit
  490.  
  491. align 4
  492. .internal:
  493.         push    ecx
  494.  
  495.         mov     esi, ecx
  496.         list_del esi
  497.  
  498.         lea     ebx, [esi+PROC.smap_list]
  499.         mov     edi, [esi+PROC.smap_list+SMAP.fd]
  500. .smap_list_destroy:
  501.         cmp     edi, ebx
  502.         jz      .smap_list_done
  503.         push    [edi+SMAP.fd]
  504.         stdcall destroy_smap, [esp+4]
  505.         pop     edi
  506.         jmp     .smap_list_destroy
  507. .smap_list_done:
  508.  
  509.         mov     esi, [esp]
  510.         add     esi, PROC.pdt_0
  511.         mov     edi, (0x80000000 shr 20)/4
  512. .destroy:
  513.         mov     eax, [esi]
  514.         test    eax, 1
  515.         jz      .next
  516.         and     eax, not 0xFFF
  517.         stdcall map_page, [tmp_task_ptab], eax, PG_SWR
  518.         stdcall destroy_page_table, [tmp_task_ptab]
  519.         mov     eax, [esi]
  520.         call    free_page
  521. .next:
  522.         add     esi, 4
  523.         dec     edi
  524.         jnz     .destroy
  525.  
  526.         call    kernel_free     ;ecx still in stack
  527.         stdcall map_page, [tmp_task_ptab], 0, PG_UNMAP
  528. .exit:
  529.         ret
  530.  
  531. align 4
  532. get_pid:
  533.         mov     eax, [TASK_BASE]
  534.         mov     eax, [eax+TASKDATA.pid]
  535.         ret
  536.  
  537. pid_to_slot:
  538. ;Input:
  539. ;  eax - pid of process
  540. ;Output:
  541. ;  eax - slot of process or 0 if process don't exists
  542. ;Search process by PID.
  543.         push    ebx
  544.         push    ecx
  545.         mov     ebx, [thread_count]
  546.         shl     ebx, BSF sizeof.TASKDATA ; multiply by size
  547.         ; add 2*32 cause:
  548.         ; [TASK_TABLE; TASK_TABLE + 32) isnt a task actually
  549.         ; skip first process in the task table
  550.         mov     ecx, 2*32
  551.  
  552. .loop:
  553. ;ecx = offset of current process info entry
  554. ;ebx = maximum permitted offset
  555.         cmp     [TASK_TABLE+ecx+TASKDATA.state], TSTATE_FREE
  556.         jz      .endloop ;skip empty slots
  557.         cmp     [TASK_TABLE+ecx+TASKDATA.pid], eax;check PID
  558.         jz      .pid_found
  559. .endloop:
  560.         add     ecx, sizeof.TASKDATA
  561.         cmp     ecx, ebx
  562.         jle     .loop
  563.  
  564.         pop     ecx
  565.         pop     ebx
  566.         xor     eax, eax
  567.         ret
  568.  
  569. .pid_found:
  570.         shr     ecx, BSF sizeof.TASKDATA ; divide by size
  571.         mov     eax, ecx ;convert offset to index of slot
  572.         pop     ecx
  573.         pop     ebx
  574.         ret
  575.  
  576.  
  577. align 4
  578. proc read_process_memory
  579. ;Input:
  580. ;  eax - process slot
  581. ;  ecx - buffer address
  582. ;  edx - buffer size
  583. ;  esi - start address in other process
  584. ;Output:
  585. ;  eax - number of bytes read.
  586.        locals
  587.          slot   dd ?
  588.          buff   dd ?
  589.          r_count    dd ?
  590.          offset dd ?
  591.          tmp_r_cnt  dd ?
  592.          mapped_size dd ?
  593.        endl
  594.  
  595.         mov     [slot], eax
  596.         mov     [buff], ecx
  597.         and     [r_count], 0
  598.         mov     [tmp_r_cnt], edx
  599.         mov     [offset], esi
  600.  
  601.         pushad
  602.         mov     ecx, proc_mem_mutex
  603.         call    mutex_lock
  604. .read_mem:
  605.         mov     edx, [offset]
  606.         mov     ebx, [tmp_r_cnt]
  607.  
  608.         mov     ecx, 0x400000
  609.         and     edx, 0x3FFFFF
  610.         sub     ecx, edx
  611.         cmp     ecx, ebx
  612.         jbe     @f
  613.         mov     ecx, ebx
  614. @@:
  615.         cmp     ecx, 0x8000
  616.         jna     @F
  617.         mov     ecx, 0x8000
  618. @@:
  619.         mov     ebx, [offset]
  620.  
  621.         push    ecx
  622.         stdcall map_memEx, [proc_mem_map], \
  623.                 [slot], ebx, ecx, PG_READ, [proc_mem_tab]
  624.         mov     [mapped_size], eax
  625.         pop     ecx
  626.  
  627.         mov     esi, [offset]
  628.         and     esi, 0xfff
  629.         sub     eax, esi
  630.         jbe     .ret_unmap
  631.         cmp     ecx, eax
  632.         jbe     @f
  633.         mov     ecx, eax
  634.         mov     [tmp_r_cnt], eax
  635. @@:
  636.         add     esi, [proc_mem_map]
  637.         mov     edi, [buff]
  638.         push    ecx
  639.         rep movsb
  640.         stdcall unmap_memEx, [proc_mem_map], \
  641.                 [slot], ebx, [mapped_size], [proc_mem_tab]
  642.         pop     ecx
  643.         add     [r_count], ecx
  644.  
  645.         add     [offset], ecx
  646.         sub     [tmp_r_cnt], ecx
  647.         jnz     .read_mem
  648. .ret:
  649.         mov     ecx, proc_mem_mutex
  650.         call    mutex_unlock
  651.         popad
  652.         mov     eax, [r_count]
  653.         ret
  654. .ret_unmap:
  655.         stdcall unmap_memEx, [proc_mem_map], \
  656.                 [slot], ebx, [mapped_size], [proc_mem_tab]
  657.         jmp     .ret
  658. endp
  659.  
  660. align 4
  661. proc write_process_memory
  662. ;Input:
  663. ;  eax - process slot
  664. ;  ecx - buffer address
  665. ;  edx - buffer size
  666. ;  esi - start address in other process
  667. ;Output:
  668. ;  eax - number of bytes written
  669.  
  670.        locals
  671.          slot   dd ?
  672.          buff   dd ?
  673.          w_count    dd ?
  674.          offset dd ?
  675.          tmp_w_cnt  dd ?
  676.          mapped_size dd ?
  677.        endl
  678.  
  679.         mov     [slot], eax
  680.         mov     [buff], ecx
  681.         and     [w_count], 0
  682.         mov     [tmp_w_cnt], edx
  683.         mov     [offset], esi
  684.  
  685.         pushad
  686.         mov     ecx, proc_mem_mutex
  687.         call    mutex_lock
  688. .write_mem:
  689.         mov     edx, [offset]
  690.         mov     ebx, [tmp_w_cnt]
  691.  
  692.         mov     ecx, 0x400000
  693.         and     edx, 0x3FFFFF
  694.         sub     ecx, edx
  695.         cmp     ecx, ebx
  696.         jbe     @f
  697.         mov     ecx, ebx
  698. @@:
  699.         cmp     ecx, 0x8000
  700.         jna     @F
  701.         mov     ecx, 0x8000
  702. @@:
  703.         mov     ebx, [offset]
  704.         push    ecx
  705.         stdcall map_memEx, [proc_mem_map], \
  706.                 [slot], ebx, ecx, PG_SWR, [proc_mem_tab]
  707.         mov     [mapped_size], eax
  708.         pop     ecx
  709.  
  710.         mov     edi, [offset]
  711.         and     edi, 0xfff
  712.         sub     eax, edi
  713.         jbe     .ret_unmap
  714.         cmp     ecx, eax
  715.         jbe     @f
  716.         mov     ecx, eax
  717.         mov     [tmp_w_cnt], eax
  718. @@:
  719.         add     edi, [proc_mem_map]
  720.         mov     esi, [buff]
  721.         push    ecx
  722.         rep movsb
  723.         stdcall unmap_memEx, [proc_mem_map], \
  724.                 [slot], ebx, [mapped_size], [proc_mem_tab]
  725.         pop     ecx
  726.  
  727.         add     [w_count], ecx
  728.         add     [offset], ecx
  729.         sub     [tmp_w_cnt], ecx
  730.         jnz     .write_mem
  731. .ret:
  732.         mov     ecx, proc_mem_mutex
  733.         call    mutex_unlock
  734.         popad
  735.         mov     eax, [w_count]
  736.         ret
  737. .ret_unmap:
  738.         stdcall unmap_memEx, [proc_mem_map], [slot], ebx, [mapped_size], [proc_mem_tab]
  739.         jmp     .ret
  740. endp
  741.  
  742. ;ebx = 1 - kernel thread
  743. ;ecx=thread entry point
  744. ;edx=thread stack pointer
  745. ;creation flags  0x01 - debugged
  746. ;                0x02 - kernel
  747.  
  748. align 4
  749. proc new_sys_threads
  750.        locals
  751.          slot          dd ?
  752.          flags         dd ?
  753.          app_cmdline   dd ? ;0x00
  754.          app_path      dd ? ;0x04
  755.          app_eip       dd ? ;0x08
  756.          app_esp       dd ? ;0x0C
  757.          app_mem       dd ? ;0x10
  758.        endl
  759.  
  760.         shl     ebx, 1
  761.         mov     [flags], ebx
  762.  
  763.         xor     eax, eax
  764.         mov     [app_eip], ecx
  765.         mov     [app_cmdline], eax
  766.         mov     [app_esp], edx
  767.         mov     [app_path], eax
  768.  
  769.         call    lock_application_table
  770.  
  771.         call    alloc_thread_slot
  772.         test    eax, eax
  773.         jz      .failed
  774.  
  775.         mov     [slot], eax
  776.  
  777.         mov     esi, [current_slot]
  778.         mov     ebx, esi      ;ebx=esi - pointer to extended information about current thread
  779.  
  780.         mov     edi, eax
  781.         shl     edi, 8
  782.         add     edi, SLOT_BASE
  783.         mov     edx, edi      ;edx=edi - pointer to extended infomation about new thread
  784.         mov     ecx, sizeof.APPDATA/4
  785.         xor     eax, eax
  786.         cld
  787.         rep stosd             ;clean extended information about new thread
  788.         mov     esi, ebx
  789.         mov     edi, edx
  790.         mov     ecx, 11
  791.         rep movsb             ;copy process name
  792.  
  793.  
  794.         mov     eax, [ebx+APPDATA.tls_base]
  795.         test    eax, eax
  796.         jz      @F
  797.  
  798.         push    edx
  799.         stdcall user_alloc, 4096
  800.         pop     edx
  801.         test    eax, eax
  802.         jz      .failed1;eax=0
  803. @@:
  804.         mov     [edx+APPDATA.tls_base], eax
  805.  
  806.         mov     eax, [ebx+APPDATA.process]
  807.         mov     [edx+APPDATA.process], eax
  808.  
  809.         lea     ebx, [edx+APPDATA.list]
  810.         lea     ecx, [eax+PROC.thr_list]
  811.         list_add_tail ebx, ecx               ;add thread to process child's list
  812.  
  813.         lea     eax, [app_cmdline]
  814.         stdcall set_app_params , [slot], eax, [flags]
  815.  
  816.         mov     eax, [process_number]           ;set result
  817.         call    unlock_application_table
  818.         ret
  819. .failed:
  820.         xor     eax, eax
  821. .failed1:
  822.         call    unlock_application_table
  823.         dec     eax     ;-1
  824.         ret
  825. endp
  826.  
  827. proc map_process_image stdcall, img_size:dword, file_base:dword, file_size:dword
  828.  
  829.         mov     edx, [img_size]
  830.         mov     esi, [file_base]
  831.         mov     ecx, [file_size]
  832.         add     edx, 4095
  833.         add     ecx, 4095
  834.         shr     edx, 12        ; total pages
  835.         shr     ecx, 12        ; image pages
  836.  
  837.         mov     edi, page_tabs
  838.         shr     esi, 10
  839.         add     esi, edi
  840.  
  841. .map_image:
  842.         lodsd
  843.         and     eax, -4096
  844.         or      eax, PG_UWR
  845.         stosd
  846.         dec     edx
  847.         loop    .map_image
  848.  
  849.         test    edx, edx
  850.         jz      .done
  851. .map_bss:
  852.         call    alloc_page
  853.         test    eax, eax
  854.         jz      .fail
  855.  
  856.         or      eax, PG_UWR
  857.         stosd
  858.         dec     edx
  859.         jnz     .map_bss
  860.  
  861.         mov     edi, [file_size]
  862.         mov     ecx, [img_size]
  863.         add     edi, 4095
  864.         and     edi, -4096
  865.         add     ecx, 4095
  866.         and     ecx, -4096
  867.         sub     ecx, edi
  868.         shr     ecx, 2
  869.         xor     eax, eax
  870.         rep stosd
  871. .done:
  872. .fail:
  873.         ret
  874. endp
  875.  
  876. align 4
  877. common_app_entry:
  878.         mov     ebp, [current_slot]
  879.         mov     ebp, [ebp+APPDATA.exec_params]
  880.         test    ebp, ebp
  881.         jz      .exit
  882. ; APPDATA.exec_params have first thread only,
  883. ; so second and next threads don't get here (they jump to .exit)
  884.         cmp     [ebp+APP_HDR.pedescr], 0
  885.         jz      .init_legacy_app
  886. ; init PE application
  887.         mov     eax, [current_process]
  888.         mov     [eax+PROC.mem_used], 0xF000 ; leave first 64K as unallocatable
  889.         call    init_heap
  890.         mov     eax, [current_process]
  891.         mov     [eax+PROC.mem_used], 0
  892.         stdcall map_pe_usermode, [ebp+APP_HDR.pedescr],\
  893.                 [ebp+APP_HDR.img_base], [ebp+APP_HDR.img_size]
  894.         cmp     eax, -0x1000
  895.         ja      .failed
  896.         push    eax
  897.         stdcall load_file_maybe_pe, pe_loader_usermode
  898.         test    esi, esi
  899.         jz      .pe_loader_notfound
  900.         mov     edx, [esi+PEDESCR.entry]
  901.         mov     [esp+4+20h], edx
  902.         stdcall map_pe_usermode, esi, eax, ebx
  903.         cmp     eax, -0x1000
  904.         ja      .pe_loader_failed
  905.         add     [esp+4+20h], eax
  906.         push    eax
  907.         mov     eax, [ebp+APP_HDR.filename_size]
  908.         add     eax, [ebp+APP_HDR.cmdline_size]
  909.         add     eax, sizeof.kernel_init_data + 2
  910.         stdcall user_alloc, eax
  911.         test    eax, eax
  912.         jz      .failed
  913.         mov     ebx, eax
  914.         mov     dword [eax+kernel_init_data.version], 1 + (0 shl 16) ; version, flags
  915.         mov     [eax+kernel_init_data.syscall_method], SYSCALL_METHOD_I40
  916.         lea     edi, [eax+sizeof.kernel_init_data]
  917.         mov     [eax+kernel_init_data.exe_path], edi
  918.         mov     esi, [ebp+APP_HDR.path_string]
  919.         mov     ecx, [ebp+APP_HDR.filename_size]
  920.         rep movsb
  921.         mov     byte [edi], 0
  922.         inc     edi
  923.         mov     [eax+kernel_init_data.command_line], edi
  924.         lea     esi, [ebp+sizeof.APP_HDR]
  925.         mov     ecx, [ebp+APP_HDR.cmdline_size]
  926.         rep movsb
  927.         mov     byte [edi], 0
  928.         mov     ecx, [ebp+APP_HDR.pedescr]
  929.         mov     ecx, [ecx+PEDESCR.stacksize]
  930.         mov     [eax+kernel_init_data.stack_size], ecx
  931.         stdcall user_alloc, ecx
  932.         test    eax, eax
  933.         jz      .failed
  934.         mov     [ebx+kernel_init_data.stack_base], eax
  935.         add     eax, [ebx+kernel_init_data.stack_size]
  936.         sub     eax, 16
  937.         pop     dword [eax+4]
  938.         pop     [ebx+kernel_init_data.exe_base]
  939.         mov     dword [eax+8], 1 ; DLL_PROCESS_ATTACH
  940.         mov     dword [eax+12], ebx
  941.         mov     [esp+2Ch], eax
  942.         jmp     .common_tls
  943. .pe_loader_notfound:
  944.         cmp     eax, -0x1000
  945.         ja      .pe_loader_failed
  946.         stdcall kernel_free, eax
  947. .pe_loader_failed:
  948.         dbgstr 'Failed to load kolibri.dll'
  949. .failed:
  950.         stdcall kernel_free, [ebp+APP_HDR.path_string]
  951.         jmp     sys_end
  952. .init_legacy_app:
  953. ; init MENUETxx application
  954.         stdcall map_process_image, [ebp+APP_HDR._emem],\
  955.                 [ebp+APP_HDR.img_base], [ebp+APP_HDR.img_size]
  956.         mov     esi, [ebp+APP_HDR.path_string]
  957.         mov     edi, [ebp+APP_HDR.path]
  958.         mov     ecx, [ebp+APP_HDR.filename_size]
  959.         cmp     ecx, 1023
  960.         jc      @f
  961.         mov     ecx, 1022
  962. @@:
  963.         push    esi
  964.         test    edi, edi
  965.         jz      @f
  966.         stdcall is_region_userspace, edi, [ebp+APP_HDR.filename_size]
  967.         jnz     @f
  968.         mov     al, '/'
  969.         stosb
  970.         rep movsb
  971.         mov     byte [edi], 0
  972. @@:
  973.         call    kernel_free
  974.         mov     edi, [ebp+APP_HDR.cmdline]
  975.         test    edi, edi
  976.         jz      .check_tls_header
  977.         lea     esi, [ebp+sizeof.APP_HDR]
  978.         mov     ecx, [ebp+APP_HDR.cmdline_size]
  979.         cmp     ecx, 256
  980.         jb      .copy_cmdline
  981.         mov     edi, [ebp+APP_HDR._emem]
  982.         add     edi, 4095
  983.         and     edi, -4096
  984.         sub     edi, ecx
  985.         dec     edi
  986.         cmp     word [6], '00'
  987.         jne     @f
  988.         mov     [APP_HEADER_00_.i_param], edi
  989.         jmp     .copy_cmdline
  990. @@:
  991.         mov     [APP_HEADER_01_.i_param], edi
  992. .copy_cmdline:
  993.         inc     ecx  ; keep in mind about 0 in the end
  994.         stdcall is_region_userspace, edi, ecx
  995.         jnz     .check_tls_header
  996.         dec     ecx
  997.         rep movsb
  998.         mov     byte [edi], 0
  999. .check_tls_header:
  1000.         cmp     word [6], '02'
  1001.         jne     .try_load_dll ;.common
  1002.         call    init_heap
  1003. .common_tls:
  1004.         stdcall user_alloc, 4096
  1005.         mov     edx, [current_slot]
  1006.         mov     [edx+APPDATA.tls_base], eax
  1007.         mov     [tls_data_l+2], ax
  1008.         shr     eax, 16
  1009.         mov     [tls_data_l+4], al
  1010.         mov     [tls_data_l+7], ah
  1011.         mov     dx, app_tls
  1012.         mov     fs, dx      
  1013. ; { Patch by Coldy, For DLL autoload    
  1014. .try_load_dll:        
  1015. ; Test app header version
  1016.         mov     ecx, dword[ebp+APP_HDR.img_base]
  1017.         cmp     dword[ecx+8], 2
  1018.         jne     .common
  1019. ;if APP_HEADER.version = 2 => load lib/dll.obj & change eip to APP_STARTUP_THUNK
  1020.         DEBUGF 1, 'K : App header version 2\n'
  1021.         stdcall load_library, dll_lib_path, 0
  1022.         cmp     eax, 0
  1023.         jne     @f
  1024. ; Something went wrong (TODO: Next 2 line is code copy after .cleanup)  
  1025.         stdcall free_kernel_space, [ebp+APP_HDR.img_base]
  1026.         stdcall kernel_free, ebp
  1027.         DEBUGF 1, 'K : DLL.OBJ not found! Terminate application!\n'
  1028.         mov     ebx, dll_error_msg
  1029.         mov     ebp, notifyapp
  1030.         call    fs_execute_from_sysdir_param
  1031. ; Terminate process (TODO: Need jump to .cleanup after sys_end ?)
  1032.         call    sys_end
  1033.  
  1034. @@:      
  1035. ; Find APP_STARTUP_THUNK in DLL.OBJ
  1036.         sub     eax, 4
  1037.         mov     eax, [eax]
  1038.  
  1039. ;.change_eip:
  1040.         mov     ecx, [current_slot]
  1041.         mov     ecx, [ecx+APPDATA.pl0_stack]
  1042.         mov     [ecx+REG_EIP], eax
  1043.        
  1044. ; } End patch by Coldy, For DLL autoload
  1045.         mov     fs, dx
  1046.  
  1047. .common:
  1048.         stdcall free_kernel_space, [ebp+APP_HDR.img_base]
  1049.         stdcall kernel_free, ebp
  1050.         mov     ebx, [current_slot]
  1051.         cmp     [ebx+APPDATA.debugger_slot], 0
  1052.         je      .exit
  1053.         mov     eax, [TASK_BASE]
  1054.         mov     [eax+TASKDATA.state], TSTATE_RUN_SUSPENDED
  1055.         call    change_task
  1056. .exit:
  1057.         popad
  1058.         iretd
  1059.  
  1060. EFL_IF      = 0x0200
  1061. EFL_IOPL1   = 0x1000
  1062. EFL_IOPL2   = 0x2000
  1063. EFL_IOPL3   = 0x3000
  1064.  
  1065. align 4
  1066. proc set_app_params stdcall,slot:dword, params:dword, flags:dword
  1067.  
  1068.        locals
  1069.          pl0_stack dd ?
  1070.        endl
  1071.  
  1072.         mov     eax, [xsave_area_size]
  1073.         add     eax, RING0_STACK_SIZE
  1074.         stdcall kernel_alloc, eax
  1075.         mov     [pl0_stack], eax
  1076.  
  1077.         lea     edi, [eax+RING0_STACK_SIZE]
  1078.  
  1079.         mov     eax, [slot]
  1080.         mov     ebx, eax
  1081.  
  1082.         shl     eax, 8
  1083.         mov     [eax+SLOT_BASE+APPDATA.fpu_state], edi
  1084.         mov     [eax+SLOT_BASE+APPDATA.exc_handler], 0
  1085.         mov     [eax+SLOT_BASE+APPDATA.except_mask], 0
  1086.         mov     [eax+SLOT_BASE+APPDATA.terminate_protection], 80000001h
  1087.  
  1088. ;set default io permission map
  1089.         mov     ecx, [SLOT_BASE+sizeof.APPDATA+APPDATA.io_map]
  1090.         mov     [eax+SLOT_BASE+APPDATA.io_map], ecx
  1091.         mov     ecx, [SLOT_BASE+sizeof.APPDATA+APPDATA.io_map+4]
  1092.         mov     [eax+SLOT_BASE+APPDATA.io_map+4], ecx
  1093.  
  1094.         mov     esi, fpu_data
  1095.         mov     ecx, [xsave_area_size]
  1096.         add     ecx, 3
  1097.         shr     ecx, 2
  1098.         rep movsd
  1099.  
  1100.         cmp     [thread_count], ebx
  1101.         adc     [thread_count], 0   ; update number of processes
  1102.         shl     ebx, 8
  1103.         lea     edx, [ebx+SLOT_BASE+APP_EV_OFFSET]
  1104.         mov     [SLOT_BASE+APPDATA.fd_ev+ebx], edx
  1105.         mov     [SLOT_BASE+APPDATA.bk_ev+ebx], edx
  1106.  
  1107.         add     edx, APP_OBJ_OFFSET-APP_EV_OFFSET
  1108.         mov     [SLOT_BASE+APPDATA.fd_obj+ebx], edx
  1109.         mov     [SLOT_BASE+APPDATA.bk_obj+ebx], edx
  1110.  
  1111.         mov     ecx, [def_cursor]
  1112.         mov     [SLOT_BASE+APPDATA.cursor+ebx], ecx
  1113.         mov     eax, [pl0_stack]
  1114.         mov     [SLOT_BASE+APPDATA.pl0_stack+ebx], eax
  1115.         add     eax, RING0_STACK_SIZE
  1116.         mov     [SLOT_BASE+APPDATA.saved_esp0+ebx], eax
  1117.  
  1118.         push    ebx
  1119.         stdcall kernel_alloc, maxPathLength
  1120.         pop     ebx
  1121.         mov     esi, [current_slot]
  1122.         mov     esi, [esi+APPDATA.cur_dir]
  1123.         mov     ecx, maxPathLength/4
  1124.         mov     edi, eax
  1125.         mov     [ebx+SLOT_BASE+APPDATA.cur_dir], eax
  1126.         rep movsd
  1127.  
  1128.         shr     ebx, 3
  1129.         mov     dword [TASK_TABLE+ebx+TASKDATA.mem_start], 0
  1130.  
  1131.         mov     ebx, [slot]
  1132.         mov     eax, ebx
  1133.         shl     ebx, 5
  1134.         lea     ecx, [draw_data+ebx];ecx - pointer to draw data
  1135.  
  1136. ; set window state to 'normal' (non-minimized/maximized/rolled-up) state
  1137.         mov     [ebx+window_data+WDATA.fl_wstate], WSTATE_NORMAL
  1138.         mov     [ebx+window_data+WDATA.fl_redraw], 1
  1139.         add     ebx, TASK_TABLE     ;ebx - pointer to information about process
  1140.         mov     [ebx+TASKDATA.wnd_number], al;set window number on screen = process slot
  1141.  
  1142.         mov     [ebx+TASKDATA.event_mask], dword 1+2+4;set default event flags (see 40 function)
  1143.  
  1144.         inc     dword [process_number]
  1145.         mov     eax, [process_number]
  1146.         mov     [ebx+TASKDATA.pid], eax    ;set PID
  1147.  
  1148. ;set draw data to full screen
  1149.         xor     eax, eax
  1150.         mov     [ecx+0], dword eax
  1151.         mov     [ecx+4], dword eax
  1152.         mov     eax, [screen_workarea.right]
  1153.         mov     [ecx+8], eax
  1154.         mov     eax, [screen_workarea.bottom]
  1155.         mov     [ecx+12], eax
  1156.  
  1157.         mov     ebx, [pl0_stack]
  1158.         mov     esi, [params]
  1159.         lea     ecx, [ebx+REG_EIP]
  1160.         xor     eax, eax
  1161.  
  1162.         mov     [ebx+REG_RET], dword common_app_entry
  1163.         mov     [ebx+REG_EDI], eax
  1164.         mov     [ebx+REG_ESI], eax
  1165.         mov     [ebx+REG_EBP], eax
  1166.         mov     [ebx+REG_ESP], ecx;ebx+REG_EIP
  1167.         mov     [ebx+REG_EBX], eax
  1168.         mov     [ebx+REG_EDX], eax
  1169.         mov     [ebx+REG_ECX], eax
  1170.         mov     [ebx+REG_EAX], eax
  1171.  
  1172.         mov     eax, [esi+APP_HDR.eip]
  1173.         mov     [ebx+REG_EIP], eax
  1174.         mov     [ebx+REG_CS], dword app_code
  1175.         mov     ecx, USER_PRIORITY
  1176.  
  1177.         test    byte [flags], 2
  1178.         jz      @F
  1179.  
  1180.         mov     [ebx+REG_CS], dword os_code ; kernel thread
  1181.         mov     ecx, MAX_PRIORITY
  1182. @@:
  1183.         mov     [ebx+REG_EFLAGS], dword EFL_IOPL1+EFL_IF
  1184.  
  1185.         mov     eax, [esi+APP_HDR.esp]
  1186.         mov     [ebx+REG_APP_ESP], eax
  1187.         mov     [ebx+REG_SS], dword app_data
  1188.  
  1189.         lea     edx, [ebx+REG_RET]
  1190.         mov     ebx, [slot]
  1191.         shl     ebx, 5
  1192.         mov     [ebx*8+SLOT_BASE+APPDATA.saved_esp], edx
  1193.  
  1194.         xor     edx, edx; process state - running
  1195. ; set if debuggee
  1196.         test    byte [flags], 1
  1197.         jz      .no_debug
  1198.         mov     eax, [current_slot_idx]
  1199.         mov     [SLOT_BASE+ebx*8+APPDATA.debugger_slot], eax
  1200. .no_debug:
  1201.         mov     [TASK_TABLE+ebx+TASKDATA.state], dl
  1202.         lea     edx, [SLOT_BASE+ebx*8]
  1203.         call    scheduler_add_thread
  1204.         ret
  1205. endp
  1206.  
  1207. align 4
  1208. get_stack_base:
  1209.         mov     eax, [current_slot]
  1210.         mov     eax, [eax+APPDATA.pl0_stack]
  1211.         ret
  1212.  
  1213.  
  1214. include "debug.inc"
  1215.