Subversion Repositories Kolibri OS

Rev

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