Subversion Repositories Kolibri OS

Rev

Rev 9941 | Rev 10002 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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