Subversion Repositories Kolibri OS

Rev

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

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