kolibrios-gitea/kernel/branches/kolibri_pe/core/taskman.inc

1306 lines
32 KiB
PHP
Raw Normal View History

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision$
EFL_IF equ 0x0200
EFL_IOPL1 equ 0x1000
EFL_IOPL2 equ 0x2000
EFL_IOPL3 equ 0x3000
struc APP_HEADER_00
{ .banner dq ?
.version dd ? ;+8
.start dd ? ;+12
.i_end dd ? ;+16
.mem_size dd ? ;+20
.i_param dd ? ;+24
}
struc APP_HEADER_01
{ .banner dq ?
.version dd ? ;+8
.start dd ? ;+12
.i_end dd ? ;+16
.mem_size dd ? ;+20
.stack_top dd ? ;+24
.i_param dd ? ;+28
.i_icon dd ? ;+32
}
struc APP_PARAMS
{ .app_cmdline ;0x00
.app_path ;0x04
.app_eip ;0x08
.app_esp ;0x0C
.app_mem ;0x10
}
macro _clear_ op
{ mov ecx, op/4
xor eax, eax
cld
rep stosd
}
align 4
test_app_header:
virtual at eax
APP_HEADER_00 APP_HEADER_00
end virtual
virtual at eax
APP_HEADER_01 APP_HEADER_01
end virtual
cmp dword [eax], 'MENU'
jne .fail
cmp word [eax+4],'ET'
jne .fail
cmp [eax+6], word '00'
jne .check_01_header
mov ecx,[APP_HEADER_00.start]
mov [ebx+0x08], ecx ;app_eip
mov edx,[APP_HEADER_00.mem_size]
mov [ebx+0x10], edx ;app_mem
shr edx,1
sub edx,0x10
mov [ebx+0x0C], edx ;app_esp
mov ecx,[APP_HEADER_00.i_param]
mov [ebx], ecx ;app_cmdline
mov [ebx+4], dword 0 ;app_path
mov edx, [APP_HEADER_00.i_end]
mov [ebx+0x14], edx
ret
.check_01_header:
cmp [eax+6],word '01'
jne .fail
mov ecx,[APP_HEADER_01.start]
mov [ebx+0x08], ecx ;app_eip
mov edx,[APP_HEADER_01.mem_size]
; \begin{diamond}[20.08.2006]
; sanity check (functions 19,58 load app_i_end bytes and that must
; fit in allocated memory to prevent kernel faults)
cmp edx,[APP_HEADER_01.i_end]
jb .fail
; \end{diamond}[20.08.2006]
mov [ebx+0x10], edx ;app_mem
mov ecx,[APP_HEADER_01.stack_top]
mov [ebx+0x0C], ecx ;app_esp
mov edx,[APP_HEADER_01.i_param]
mov [ebx], edx ;app_cmdline
mov ecx,[APP_HEADER_01.i_icon]
mov [ebx+4], ecx ;app_path
mov edx, [APP_HEADER_01.i_end]
mov [ebx+0x14], edx
ret
.fail:
xor eax, eax
ret
align 4
proc mnt_exec stdcall file_base:dword, file_size:dword, \
path:dword, cmd_line:dword, flags:dword
locals
cmdline rb 256
filename rb 1024
save_cr3 dd ?
slot dd ?
slot_base dd ?
;app header data
hdr_cmdline dd ? ;0x00
hdr_path dd ? ;0x04
hdr_eip dd ? ;0x08
hdr_esp dd ? ;0x0C
hdr_mem dd ? ;0x10
hdr_i_end dd ? ;0x14
endl
push ebx
push edi
push esi
mov esi, [path]
lea edi, [filename]
lea ecx, [edi+1024]
@@:
cmp edi, ecx
jae .bigfilename
lodsb
stosb
test al, al
jnz @b
lea edi, [cmdline]
mov dword [edi],0
mov esi, [cmd_line]
test esi, esi
jz .no_cmdline
lea ecx, [edi+255]
mov [edi+252], dword 0
@@:
cmp edi, ecx
jae .no_cmdline
lodsb
stosb
test al, al
jnz @b
.no_cmdline:
mov eax, [file_base]
lea ebx, [hdr_cmdline]
call test_app_header
mov ecx, -0x1F
test eax, eax
jz .err_hdr
; DEBUGF 1,"%s",new_process_loading
lea ebx, [application_table_status]
call wait_mutex
call set_application_table_status
call get_new_process_place
test eax, eax
mov ecx, -0x20 ; too many processes
jz .err
mov [slot], eax
shl eax, 8
add eax, SLOT_BASE
mov [slot_base], eax
mov edi, eax
_clear_ 256 ;clean extended information about process
; write application name
lea eax, [filename]
stdcall strrchr, eax, '/' ; now eax points to name without path
lea esi, [eax+1]
test eax, eax
jnz @F
lea esi, [filename]
@@:
mov ecx, 8 ; 8 chars for name
mov edi, [slot_base]
.copy_process_name_loop:
lodsb
cmp al, '.'
jz .copy_process_name_done
test al, al
jz .copy_process_name_done
stosb
loop .copy_process_name_loop
.copy_process_name_done:
mov ebx, cr3
mov [save_cr3], ebx
stdcall create_app_space,[hdr_mem],[file_base],[file_size]
mov ecx, -30 ; no memory
test eax, eax
jz .failed
mov ebx,[slot_base]
mov [ebx+APPDATA.dir_table],eax
mov ecx,[hdr_mem]
mov [ebx+APPDATA.mem_size],ecx
mov edi, [file_size]
add edi, 4095
and edi, not 4095
sub ecx, edi
jna @F
xor eax, eax
cld
rep stosb
@@:
mov ecx, [file_base]
call @mem_free@4
lea eax, [hdr_cmdline]
lea ebx, [cmdline]
lea ecx, [filename]
stdcall set_app_params ,[slot],eax,ebx,ecx,[flags]
mov eax, [save_cr3]
call set_cr3
mov eax,[process_number] ;set result
mov [application_table_status], 0 ;unlock application_table_status mutex
pop edi
pop esi
pop ebx
ret
.bigfilename:
pop edi
pop esi
pop ebx
mov eax, -ERROR_FILE_NOT_FOUND
ret
.failed:
mov eax, [save_cr3]
call set_cr3
.err:
.err_hdr:
mov ecx, [file_base]
call @mem_free@4
pop edi
pop esi
pop ebx
xor eax, eax
mov [application_table_status],eax
mov eax, ecx
ret
endp
align 4
proc pe_app_param stdcall path:dword, raw:dword, ex_pg_dir:dword, ex_stack:dword
locals
slot dd ?
slot_base dd ?
pl0_stack dd ?
endl
push ebx
push esi
push edi
lea ebx, [application_table_status]
call wait_mutex
call set_application_table_status
call get_new_process_place
test eax, eax
mov ecx, -0x20 ; too many processes
jz .err
mov [slot], eax
shl eax, 8
add eax, SLOT_BASE
mov [slot_base], eax
mov edi, eax
_clear_ 256 ;clean extended information about process
; write application name
stdcall strrchr, [path], '/' ; now eax points to name without path
lea esi, [eax+1]
test eax, eax
jnz @F
lea esi, [path]
@@:
mov ecx, 8 ; 8 chars for name
mov edi, [slot_base]
.copy_process_name_loop:
lodsb
cmp al, '.'
jz .copy_process_name_done
test al, al
jz .copy_process_name_done
stosb
loop .copy_process_name_loop
.copy_process_name_done:
mov eax, [ex_pg_dir]
mov ebx, [slot_base]
mov [ebx+APPDATA.dir_table],eax
;mov eax,[hdr_mem]
;mov [ebx+APPDATA.mem_size],eax
mov ecx, 2
call @frame_alloc@4
lea edi, [eax+OS_BASE]
mov [pl0_stack], edi
mov [ebx+APPDATA.pl0_stack], edi
add edi, RING0_STACK_SIZE
mov [ebx+APPDATA.saved_esp0], edi
mov [ebx+APPDATA.fpu_state], edi
mov [ebx+APPDATA.fpu_handler], 0
mov [ebx+APPDATA.sse_handler], 0
;set default io permission map
mov [ebx+APPDATA.io_map],\
(tss._io_map_0-OS_BASE+PG_MAP)
mov [ebx+APPDATA.io_map+4],\
(tss._io_map_1-OS_BASE+PG_MAP)
mov esi, fpu_data
mov ecx, 512/4
rep movsd
mov eax, [slot]
cmp eax,[TASK_COUNT]
jle .noinc
inc dword [TASK_COUNT] ;update number of processes
.noinc:
lea edx, [ebx+APP_EV_OFFSET]
mov [ebx+APPDATA.fd_ev],edx
mov [ebx+APPDATA.bk_ev],edx
add edx, APP_OBJ_OFFSET-APP_EV_OFFSET
mov [ebx+APPDATA.fd_obj],edx
mov [ebx+APPDATA.bk_obj],edx
mov ecx, [def_cursor]
mov [ebx+APPDATA.cursor],ecx
call _alloc_page
lea edi, [eax+OS_BASE] ; FIXME
mov esi,[current_slot]
mov esi,[esi+APPDATA.cur_dir]
mov ecx,0x1000/4
mov [ebx+APPDATA.cur_dir],edi
rep movsd
mov ebx, [slot]
mov eax, ebx
shl ebx, 5
mov dword [CURRENT_TASK+ebx+0x10], 0
lea ecx,[draw_data+ebx] ;ecx - pointer to draw data
; set window state to 'normal' (non-minimized/maximized/rolled-up) state
mov [ebx+window_data+WDATA.fl_wstate], WSTATE_NORMAL
mov [ebx+window_data+WDATA.fl_redraw], 1
add ebx,CURRENT_TASK ;ebx - pointer to information about process
mov [ebx+TASKDATA.wnd_number],al;set window number on screen = process slot
mov [ebx+TASKDATA.event_mask],dword 1+2+4 ;set default event flags (see 40 function)
inc dword [process_number]
mov eax,[process_number]
mov [ebx+4],eax ;set PID
;set draw data to full screen
mov [ecx+0],dword 0
mov [ecx+4],dword 0
mov eax,[Screen_Max_X]
mov [ecx+8],eax
mov eax,[Screen_Max_Y]
mov [ecx+12],eax
mov ebx, [pl0_stack]
mov eax, [raw]
lea ecx, [ebx+REG_EDI]
mov edx, [ex_stack]
mov [ebx+REG_ENTRY], dword _sys_app_entry
mov [ebx+REG_RESTART], dword _pe_restart
mov [ebx+REG_RAW], eax
mov [ebx+REG_CSTACK], ecx
mov [ebx+REG_USTACK], edx
lea ebx, [ebx+REG_ENTRY]
mov ecx, [slot]
shl ecx, 5
mov [ecx*8+SLOT_BASE+APPDATA.saved_esp], ebx
mov [CURRENT_TASK+ecx+TASKDATA.state], 0
; DEBUGF 1,"%s",new_process_running
.err:
mov eax,[process_number] ;set result
mov [application_table_status], 0 ;unlock application_table_status mutex
pop edi
pop esi
pop ebx
ret
endp
align 4
_pe_restart:
add esp, 12
popad
iretd
align 4
proc get_new_process_place
;input:
; none
;result:
; eax=[new_process_place]<>0 - ok
; 0 - failed.
;This function find least empty slot.
;It doesn't increase [TASK_COUNT]!
mov eax,CURRENT_TASK
mov ebx,[TASK_COUNT]
inc ebx
shl ebx,5
add ebx,eax ;ebx - address of process information for (last+1) slot
.newprocessplace:
;eax = address of process information for current slot
cmp eax,ebx
jz .endnewprocessplace ;empty slot after high boundary
add eax,0x20
cmp word [eax+0xa],9 ;check process state, 9 means that process slot is empty
jnz .newprocessplace
.endnewprocessplace:
mov ebx,eax
sub eax,CURRENT_TASK
shr eax,5 ;calculate slot index
cmp eax,256
jge .failed ;it should be <256
mov word [ebx+0xa],9 ;set process state to 9 (for slot after hight boundary)
ret
.failed:
xor eax,eax
ret
endp
align 4
proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword
locals
app_pages dd ?
img_pages dd ?
dir_addr dd ?
app_tabs dd ?
endl
mov ebx, pg_data.pg_mutex
call wait_mutex ;ebx
xor eax, eax
mov [dir_addr], eax
mov eax, [app_size]
add eax, 4095
and eax, not 4095
mov [app_size], eax
mov ebx, eax
shr eax, 12
mov [app_pages], eax
add ebx, 0x3FFFFF
and ebx, not 0x3FFFFF
shr ebx, 22
mov [app_tabs], ebx
mov ecx, [img_size]
add ecx, 4095
and ecx, not 4095
mov [img_size], ecx
shr ecx, 12
mov [img_pages], ecx
call _alloc_page
test eax, eax
mov [dir_addr], eax
jz .fail
;lea edi, [eax + OS_BASE]
;mov ecx, (OS_BASE shr 20)/4
;xor eax, eax
;cld
;rep stosd
;mov ecx, 1024-(OS_BASE shr 20)/4
;mov esi, _sys_pdbr+(OS_BASE shr 20)
;rep movsd
lea edi, [eax+OS_BASE]
mov ecx, 512
xor eax, eax
cld
rep stosd
mov esi, [img_base]
mov ecx, 512 ; FIX only core tabs
mov esi, _sys_pdbr+(HEAP_BASE shr 20)
rep movsd
mov edi, [dir_addr]
lea eax, [edi+PG_SW]
mov [edi+OS_BASE+(page_tabs shr 20)], eax
mov eax, edi
call set_cr3
mov esi, [img_base]
mov ebx, [app_tabs]
mov edi, master_tab
@@:
call _alloc_page
test eax, eax
jz .fail
or eax, PG_UW
stosd
dec ebx
jnz @B
mov edi, page_tabs
mov ecx, [app_tabs]
shl ecx, 10
xor eax, eax
rep stosd
xor ebx, ebx
.alloc:
call _alloc_page
test eax, eax
jz .fail
stdcall map_page,ebx,eax,dword PG_UW
add ebx, 0x1000
dec [app_pages]
jnz .alloc
mov ecx, [img_size] ; FIXME remap md
mov esi, [img_base]
xor edi, edi
rep movsb
.done:
dec [pg_data.pg_mutex]
mov eax, [dir_addr]
ret
.fail:
dec [pg_data.pg_mutex]
cmp [dir_addr], 0
je @f
stdcall destroy_app_space, [dir_addr]
@@:
xor eax, eax
ret
endp
;addr_t __fastcall pe_app_space(size_t size);
align 4
@pe_app_space@4:
sub esp, 16
mov [esp+4], ebx
mov [esp+8], esi
mov [esp+12], edi
lea ebx, [ecx+0x3FFFFF]
call _alloc_page
test eax, eax
mov [esp], eax
jz .fail
mov ecx, 512
lea edi, [eax + OS_BASE]
xor eax, eax
cld
rep stosd
mov ecx, 512 ; FIX only core tabs
mov esi, _sys_pdbr+(HEAP_BASE shr 20)
rep movsd
mov esi, [esp]
shr ebx, 22
.new_ptab:
call _alloc_page
test eax, eax
jz .fail
lea edi, [eax+OS_BASE]
or eax, PG_UW
mov [esi+OS_BASE], eax
mov ecx, 1024
xor eax, eax
rep stosd
add esi, 4
dec ebx
jnz .new_ptab
call _alloc_page
test eax, eax
jz .fail
lea edi, [eax+OS_BASE]
or eax, PG_UW
mov ebx, [esp]
lea edx, [ebx+PG_SW]
mov [ebx+OS_BASE+(0x7FC00000 shr 20)], eax
mov [ebx+OS_BASE+(page_tabs shr 20)], edx
mov ecx, 1024
xor eax, eax
rep stosd
mov eax, ebx
.fail:
mov ebx, [esp+4]
mov esi, [esp+8]
mov edi, [esp+12]
add esp, 16
ret
align 4
set_cr3:
mov ebx, [current_slot]
mov [ebx+APPDATA.dir_table], eax
mov cr3, eax
ret
align 4
proc destroy_page_table stdcall, pg_tab:dword
push ebx
push esi
mov esi, [pg_tab]
mov ebx, 1024
.free:
mov ecx, [esi]
test ecx, 1
jz .next
test ecx, 1 shl 9
jnz .next ;skip shared pages
call @frame_free@4
.next:
add esi, 4
dec ebx
jnz .free
pop esi
pop ebx
ret
endp
align 4
proc destroy_app_space stdcall, pg_dir:dword
mov ebx, pg_data.pg_mutex
call wait_mutex ;ebx
xor edx,edx
mov eax,0x2
mov ebx, [pg_dir]
.loop:
;eax = current slot of process
mov ecx,eax
shl ecx,5
cmp byte [CURRENT_TASK+ecx+0xa],9 ;if process running?
jz @f ;skip empty slots
shl ecx,3
cmp [SLOT_BASE+ecx+0xB8],ebx ;compare page directory addresses
jnz @f
inc edx ;thread found
@@:
inc eax
cmp eax,[TASK_COUNT] ;exit loop if we look through all processes
jle .loop
;edx = number of threads
;our process is zombi so it isn't counted
cmp edx,1
jg .exit
;if there isn't threads then clear memory.
mov eax, [pg_dir]
and eax, -4096
add eax, OS_BASE
mov [tmp_task_pdir], eax
mov esi, eax
mov edi, (HEAP_BASE shr 20)/4
.destroy:
mov eax, [esi]
test eax, 1
jz .next
and eax, not 0xFFF
add eax, OS_BASE
stdcall destroy_page_table, eax
mov ecx, [esi]
call @frame_free@4
.next:
add esi, 4
dec edi
jnz .destroy
mov ecx, [pg_dir]
call @frame_free@4
.exit:
dec [pg_data.pg_mutex]
ret
endp
align 4
get_pid:
mov eax, [TASK_BASE]
mov eax, [eax+TASKDATA.pid]
ret
pid_to_slot:
;Input:
; eax - pid of process
;Output:
; eax - slot of process or 0 if process don't exists
;Search process by PID.
push ebx
push ecx
mov ebx,[TASK_COUNT]
shl ebx,5
mov ecx,2*32
.loop:
;ecx=offset of current process info entry
;ebx=maximum permitted offset
cmp byte [CURRENT_TASK+ecx+0xa],9
jz .endloop ;skip empty slots
cmp [CURRENT_TASK+ecx+0x4],eax ;check PID
jz .pid_found
.endloop:
add ecx,32
cmp ecx,ebx
jle .loop
pop ecx
pop ebx
xor eax,eax
ret
.pid_found:
shr ecx,5
mov eax,ecx ;convert offset to index of slot
pop ecx
pop ebx
ret
check_region:
;input:
; ebx - start of buffer
; ecx - size of buffer
;result:
; eax = 1 region lays in app memory
; eax = 0 region don't lays in app memory
mov eax,[CURRENT_TASK]
jmp check_process_region
;-----------------------------------------------------------------------------
check_process_region:
;input:
; eax - slot
; ebx - start of buffer
; ecx - size of buffer
;result:
; eax = 1 region lays in app memory
; eax = 0 region don't lays in app memory
test ecx,ecx
jle .ok
shl eax,5
cmp word [CURRENT_TASK+eax+0xa],0
jnz .failed
shl eax,3
mov eax,[SLOT_BASE+eax+0xb8]
test eax,eax
jz .failed
mov eax,1
ret
; call MEM_Get_Linear_Address
; push ebx
; push ecx
; push edx
; mov edx,ebx
; and edx,not (4096-1)
; sub ebx,edx
; add ecx,ebx
; mov ebx,edx
; add ecx,(4096-1)
; and ecx,not (4096-1)
;.loop:
;;eax - linear address of page directory
;;ebx - current page
;;ecx - current size
; mov edx,ebx
; shr edx,22
; mov edx,[eax+4*edx]
; and edx,not (4096-1)
; test edx,edx
; jz .failed1
; push eax
; mov eax,edx
; call MEM_Get_Linear_Address
; mov edx,ebx
; shr edx,12
; and edx,(1024-1)
; mov eax,[eax+4*edx]
; and eax,not (4096-1)
; test eax,eax
; pop eax
; jz .failed1
; add ebx,4096
; sub ecx,4096
; jg .loop
; pop edx
; pop ecx
; pop ebx
.ok:
mov eax,1
ret
;
;.failed1:
; pop edx
; pop ecx
; pop ebx
.failed:
xor eax,eax
ret
align 4
proc read_process_memory
;Input:
; eax - process slot
; ebx - buffer address
; ecx - buffer size
; edx - start address in other process
;Output:
; eax - number of bytes read.
locals
slot dd ?
buff dd ?
r_count dd ?
offset dd ?
tmp_r_cnt dd ?
endl
mov [slot], eax
mov [buff], ebx
and [r_count], 0
mov [tmp_r_cnt], ecx
mov [offset], edx
pushad
.read_mem:
mov edx, [offset]
mov ebx, [tmp_r_cnt]
mov ecx, 0x400000
and edx, 0x3FFFFF
sub ecx, edx
cmp ecx, ebx
jbe @f
mov ecx, ebx
@@:
cmp ecx, 0x8000
jna @F
mov ecx, 0x8000
@@:
mov eax, [slot]
shl eax,8
mov ebx, [offset]
push ecx
stdcall map_memEx, [proc_mem_map],\
[SLOT_BASE+eax+0xB8],\
ebx, ecx
pop ecx
mov esi, [offset]
and esi, 0xfff
add esi, [proc_mem_map]
mov edi, [buff]
mov edx, ecx
rep movsb
add [r_count], edx
add [offset], edx
sub [tmp_r_cnt], edx
jnz .read_mem
popad
mov eax, [r_count]
ret
endp
align 4
proc write_process_memory
;Input:
; eax - process slot
; ebx - buffer address
; ecx - buffer size
; edx - start address in other process
;Output:
; eax - number of bytes written
locals
slot dd ?
buff dd ?
w_count dd ?
offset dd ?
tmp_w_cnt dd ?
endl
mov [slot], eax
mov [buff], ebx
and [w_count], 0
mov [tmp_w_cnt], ecx
mov [offset], edx
pushad
.read_mem:
mov edx, [offset]
mov ebx, [tmp_w_cnt]
mov ecx, 0x400000
and edx, 0x3FFFFF
sub ecx, edx
cmp ecx, ebx
jbe @f
mov ecx, ebx
@@:
cmp ecx, 0x8000
jna @F
mov ecx, 0x8000
@@:
mov eax, [slot]
shl eax,8
mov ebx, [offset]
; add ebx, new_app_base
push ecx
stdcall map_memEx, [proc_mem_map],\
[SLOT_BASE+eax+0xB8],\
ebx, ecx
pop ecx
mov edi, [offset]
and edi, 0xfff
add edi, [proc_mem_map]
mov esi, [buff]
mov edx, ecx
rep movsb
add [w_count], edx
add [offset], edx
sub [tmp_w_cnt], edx
jnz .read_mem
popad
mov eax, [w_count]
ret
endp
align 4
proc new_sys_threads
locals
slot dd ?
app_cmdline dd ? ;0x00
app_path dd ? ;0x04
app_eip dd ? ;0x08
app_esp dd ? ;0x0C
app_mem dd ? ;0x10
endl
cmp eax,1
jne .failed ;other subfunctions
xor eax,eax
mov [app_cmdline], eax
mov [app_path], eax
mov [app_eip], ebx
mov [app_esp], ecx
;DEBUGF 1,"%s",new_process_loading
.wait_lock:
cmp [application_table_status],0
je .get_lock
call change_task
jmp .wait_lock
.get_lock:
mov eax, 1
xchg eax, [application_table_status]
cmp eax, 0
jne .wait_lock
call set_application_table_status
call get_new_process_place
test eax, eax
jz .failed
mov [slot], eax
mov esi,[current_slot]
mov ebx,esi ;ebx=esi - pointer to extended information about current thread
mov edi, eax
shl edi,8
add edi,SLOT_BASE
mov edx,edi ;edx=edi - pointer to extended infomation about new thread
mov ecx,256/4
xor eax, eax
cld
rep stosd ;clean extended information about new thread
mov esi,ebx
mov edi,edx
mov ecx,11
rep movsb ;copy process name
mov eax,[ebx+APPDATA.heap_base]
mov [edx+APPDATA.heap_base], eax
mov ecx,[ebx+APPDATA.heap_top]
mov [edx+APPDATA.heap_top], ecx
mov eax,[ebx+APPDATA.mem_size]
mov [edx+APPDATA.mem_size], eax
mov ecx,[ebx+APPDATA.dir_table]
mov [edx+APPDATA.dir_table],ecx ;copy page directory
lea eax, [app_cmdline]
stdcall set_app_params ,[slot],eax,dword 0,\
dword 0,dword 0
; DEBUGF 1,"%s",new_process_running
mov [application_table_status],0 ;unlock application_table_status mutex
mov eax,[process_number] ;set result
ret
.failed:
mov [application_table_status],0
mov eax,-1
ret
endp
; param
; ebx=mutex
align 4
wait_mutex:
push eax
push ebx
.do_wait:
cmp dword [ebx],0
je .get_lock
call change_task
jmp .do_wait
.get_lock:
mov eax, 1
xchg eax, [ebx]
test eax, eax
jnz .do_wait
pop ebx
pop eax
ret
align 4
proc set_app_params stdcall,slot:dword, params:dword,\
cmd_line:dword, app_path:dword, flags:dword
locals
pl0_stack dd ?
endl
mov ecx, 2 ;(RING0_STACK_SIZE+512) shr 12
call @frame_alloc@4
add eax, OS_BASE
mov [pl0_stack], eax
lea edi, [eax+RING0_STACK_SIZE]
mov eax, [slot]
mov ebx, eax
shl eax, 8
mov [eax+SLOT_BASE+APPDATA.fpu_state], edi
mov [eax+SLOT_BASE+APPDATA.fpu_handler], 0
mov [eax+SLOT_BASE+APPDATA.sse_handler], 0
;set default io permission map
mov [eax+SLOT_BASE+APPDATA.io_map],\
(tss._io_map_0-OS_BASE+PG_MAP)
mov [eax+SLOT_BASE+APPDATA.io_map+4],\
(tss._io_map_1-OS_BASE+PG_MAP)
mov esi, fpu_data
mov ecx, 512/4
rep movsd
cmp ebx,[TASK_COUNT]
jle .noinc
inc dword [TASK_COUNT] ;update number of processes
.noinc:
shl ebx,8
lea edx, [ebx+SLOT_BASE+APP_EV_OFFSET]
mov [SLOT_BASE+APPDATA.fd_ev+ebx],edx
mov [SLOT_BASE+APPDATA.bk_ev+ebx],edx
add edx, APP_OBJ_OFFSET-APP_EV_OFFSET
mov [SLOT_BASE+APPDATA.fd_obj+ebx],edx
mov [SLOT_BASE+APPDATA.bk_obj+ebx],edx
mov ecx, [def_cursor]
mov [SLOT_BASE+APPDATA.cursor+ebx],ecx
mov eax, [pl0_stack]
mov [SLOT_BASE+APPDATA.pl0_stack+ebx],eax
add eax, RING0_STACK_SIZE
mov [SLOT_BASE+APPDATA.saved_esp0+ebx], eax
call _alloc_page
lea edi, [eax + OS_BASE]
mov [ebx+SLOT_BASE+APPDATA.cur_dir], edi
mov esi,[current_slot]
mov esi,[esi+APPDATA.cur_dir]
mov ecx,0x1000/4
rep movsd
shr ebx,3
mov dword [CURRENT_TASK+ebx+0x10], 0
.add_command_line:
mov edx,[params]
mov edx,[edx] ;app_cmdline
test edx,edx
jz @f ;application doesn't need parameters
mov eax, edx
add eax, 256
jc @f
cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8]
ja @f
mov byte [edx], 0 ;force empty string if no cmdline given
mov eax, [cmd_line]
test eax, eax
jz @f
stdcall strncpy, edx, eax, 256
@@:
mov edx,[params]
mov edx, [edx+4] ;app_path
test edx,edx
jz @F ;application don't need path of file
mov eax, edx
add eax, 1024
jc @f
cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8]
ja @f
stdcall strncpy, edx, [app_path], 1024
@@:
mov ebx,[slot]
mov eax,ebx
shl ebx,5
lea ecx,[draw_data+ebx] ;ecx - pointer to draw data
; set window state to 'normal' (non-minimized/maximized/rolled-up) state
mov [ebx+window_data+WDATA.fl_wstate], WSTATE_NORMAL
mov [ebx+window_data+WDATA.fl_redraw], 1
add ebx,CURRENT_TASK ;ebx - pointer to information about process
mov [ebx+TASKDATA.wnd_number],al;set window number on screen = process slot
mov [ebx+TASKDATA.event_mask],dword 1+2+4 ;set default event flags (see 40 function)
inc dword [process_number]
mov eax,[process_number]
mov [ebx+4],eax ;set PID
;set draw data to full screen
mov [ecx+0],dword 0
mov [ecx+4],dword 0
mov eax,[Screen_Max_X]
mov [ecx+8],eax
mov eax,[Screen_Max_Y]
mov [ecx+12],eax
mov ebx, [pl0_stack]
mov esi,[params]
lea ecx, [ebx+REG_EIP]
xor eax, eax
mov [ebx+REG_RET], dword irq0.return
mov [ebx+REG_EDI], eax
mov [ebx+REG_ESI], eax
mov [ebx+REG_EBP], eax
mov [ebx+REG_ESP], ecx ;ebx+REG_EIP
mov [ebx+REG_EBX], eax
mov [ebx+REG_EDX], eax
mov [ebx+REG_ECX], eax
mov [ebx+REG_EAX], eax
mov eax, [esi+0x08] ;app_eip
mov [ebx+REG_EIP], eax ;app_entry
mov [ebx+REG_CS], dword sel_app_code
mov [ebx+REG_EFLAGS], dword EFL_IOPL3+EFL_IF
mov eax, [esi+0x0C] ;app_esp
mov [ebx+REG_APP_ESP], eax ;app_stack
mov [ebx+REG_SS], dword sel_app_data
lea ecx, [ebx+REG_RET]
mov ebx, [slot]
shl ebx, 5
mov [ebx*8+SLOT_BASE+APPDATA.saved_esp], ecx
xor ecx, ecx ; process state - running
; set if debuggee
test byte [flags], 1
jz .no_debug
inc ecx ; process state - suspended
mov eax,[CURRENT_TASK]
mov [SLOT_BASE+ebx*8+APPDATA.debugger_slot],eax
.no_debug:
mov [CURRENT_TASK+ebx+TASKDATA.state], cl
; DEBUGF 1,"%s",new_process_running
ret
endp
include "debug.inc"