forked from KolibriOS/kolibrios
40b1c24dc3
2)DLL loader git-svn-id: svn://kolibrios.org@198 a494cfbc-eb01-0410-851d-a64ba20cac60
1166 lines
30 KiB
PHP
1166 lines
30 KiB
PHP
GREEDY_KERNEL equ 0; 1
|
|
|
|
|
|
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
|
|
}
|
|
|
|
align 4
|
|
proc test_app_header stdcall, header:dword
|
|
virtual at ebx
|
|
APP_HEADER_00 APP_HEADER_00
|
|
end virtual
|
|
|
|
mov ebx, [header]
|
|
cmp [ebx+6], word '00'
|
|
jne .check_01_header
|
|
|
|
mov eax,[APP_HEADER_00.start]
|
|
mov [app_start],eax
|
|
mov eax,[APP_HEADER_00.i_end]
|
|
mov [app_i_end],eax
|
|
mov eax,[APP_HEADER_00.mem_size]
|
|
mov [app_mem],eax
|
|
shr eax,1
|
|
sub eax,0x10
|
|
mov [app_esp],eax
|
|
mov eax,[APP_HEADER_00.i_param]
|
|
mov [app_i_param],eax
|
|
mov [app_i_icon],dword 0
|
|
|
|
mov eax,1
|
|
ret
|
|
|
|
.check_01_header:
|
|
virtual at ebx
|
|
APP_HEADER_01 APP_HEADER_01
|
|
end virtual
|
|
|
|
cmp [ebx+6],word '01'
|
|
jne .no_01_header
|
|
|
|
mov eax,[APP_HEADER_01.start]
|
|
mov [app_start],eax
|
|
mov eax,[APP_HEADER_01.i_end]
|
|
mov [app_i_end],eax
|
|
mov eax,[APP_HEADER_01.mem_size]
|
|
mov [app_mem],eax
|
|
mov eax,[APP_HEADER_01.stack_top]
|
|
mov [app_esp],eax
|
|
mov eax,[APP_HEADER_01.i_param]
|
|
mov [app_i_param],eax
|
|
mov eax,[APP_HEADER_01.i_icon]
|
|
mov [app_i_icon],eax
|
|
|
|
mov eax,1
|
|
ret
|
|
|
|
.no_01_header:
|
|
|
|
xor eax, eax
|
|
ret
|
|
endp
|
|
|
|
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)
|
|
; mov [new_process_place], eax
|
|
ret
|
|
|
|
.failed:
|
|
xor eax,eax
|
|
ret
|
|
endp
|
|
|
|
align 4
|
|
proc create_app_space stdcall, app_size:dword,img_size:dword
|
|
locals
|
|
app_pages dd ?
|
|
img_pages dd ?
|
|
dir_addr dd ?
|
|
app_tabs dd ?
|
|
endl
|
|
|
|
stdcall wait_mutex, pg_data.pg_mutex
|
|
|
|
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
|
|
|
|
if GREEDY_KERNEL
|
|
lea eax, [ecx+ebx+2] ;only image size
|
|
else
|
|
lea eax, [eax+ebx+2] ;all requested memory
|
|
end if
|
|
cmp eax, [pg_data.pages_free]
|
|
ja .fail
|
|
|
|
call alloc_page
|
|
test eax, eax
|
|
jz .fail
|
|
mov [dir_addr], eax
|
|
stdcall map_page,[tmp_task_pdir],eax,dword PG_SW
|
|
|
|
mov esi, sys_pgdir
|
|
mov edi, [tmp_task_pdir]
|
|
mov ecx, 384
|
|
cld
|
|
rep movsd
|
|
|
|
mov ecx, 384
|
|
xor eax, eax
|
|
cld
|
|
rep stosd
|
|
|
|
mov ecx, 256
|
|
mov esi, sys_pgdir+0xc00
|
|
rep movsd
|
|
|
|
mov eax, [dir_addr]
|
|
or eax, PG_SW
|
|
mov ebx, [tmp_task_pdir]
|
|
mov [ebx+0x600], eax
|
|
|
|
mov eax, [dir_addr]
|
|
call set_cr3
|
|
|
|
mov edx, [app_tabs]
|
|
mov edi, new_app_base
|
|
@@:
|
|
call alloc_page
|
|
test eax, eax
|
|
jz .fail
|
|
|
|
stdcall map_page_table, edi, eax
|
|
add edi, 0x00400000
|
|
dec edx
|
|
jnz @B
|
|
|
|
mov edi, new_app_base
|
|
shr edi, 10
|
|
add edi, pages_tab
|
|
mov ecx, [app_tabs]
|
|
shl ecx, 10
|
|
xor eax, eax
|
|
rep stosd
|
|
|
|
mov edx, new_app_base
|
|
.alloc:
|
|
call alloc_page
|
|
test eax, eax
|
|
jz .fail
|
|
|
|
stdcall map_page,edx,eax,dword PG_UW
|
|
add edx, 0x1000
|
|
sub [app_pages], 1
|
|
sub [img_pages], 1
|
|
jnz .alloc
|
|
|
|
mov ecx, [app_pages]
|
|
and ecx, ecx
|
|
jz .next
|
|
|
|
mov ebx, edx
|
|
shr edx, 12
|
|
.reserve:
|
|
mov dword [pages_tab+edx*4], 0x02
|
|
invlpg [ebx]
|
|
inc edx
|
|
dec ecx
|
|
jnz .reserve
|
|
.next:
|
|
mov edi, new_app_base
|
|
mov ecx, [img_size]
|
|
shr ecx, 2
|
|
xor eax, eax
|
|
cld
|
|
rep stosd
|
|
|
|
stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP
|
|
|
|
dec [pg_data.pg_mutex]
|
|
mov eax, [dir_addr]
|
|
ret
|
|
.fail:
|
|
dec [pg_data.pg_mutex]
|
|
cmp [dir_addr], 0
|
|
jz @f
|
|
stdcall destroy_app_space, [dir_addr]
|
|
@@:
|
|
xor eax, eax
|
|
ret
|
|
endp
|
|
|
|
align 4
|
|
set_cr3:
|
|
mov esi, [CURRENT_TASK]
|
|
mov ebx, esi
|
|
shl esi,8
|
|
mov [PROC_BASE+esi+0xB8],eax
|
|
imul ebx,tss_step
|
|
add ebx,tss_data
|
|
mov [ebx+28], eax
|
|
mov cr3, eax
|
|
ret
|
|
|
|
align 4
|
|
proc destroy_page_table stdcall, pg_tab:dword
|
|
|
|
push esi
|
|
|
|
mov esi, [pg_tab]
|
|
mov ecx, 1024
|
|
.free:
|
|
mov eax, [esi]
|
|
test eax, 1
|
|
jz .next
|
|
call free_page
|
|
.next:
|
|
add esi, 4
|
|
dec ecx
|
|
jnz .free
|
|
pop esi
|
|
ret
|
|
endp
|
|
|
|
align 4
|
|
proc destroy_app_space stdcall, pg_dir:dword
|
|
|
|
stdcall wait_mutex, pg_data.pg_mutex
|
|
|
|
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 [PROC_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, not 0xFFF
|
|
stdcall map_page,[tmp_task_pdir],eax,dword PG_SW
|
|
mov esi, [tmp_task_pdir]
|
|
add esi, 0x604
|
|
mov edi, 383
|
|
.destroy:
|
|
mov eax, [esi]
|
|
test eax, 1
|
|
jz .next
|
|
and eax, not 0xFFF
|
|
stdcall map_page,[tmp_task_ptab],eax,dword PG_SW
|
|
stdcall destroy_page_table, [tmp_task_ptab]
|
|
mov eax, [esi]
|
|
call free_page
|
|
.next:
|
|
add esi, 4
|
|
dec edi
|
|
jnz .destroy
|
|
|
|
mov eax, [pg_dir]
|
|
call free_page
|
|
.exit:
|
|
stdcall map_page,[tmp_task_ptab],dword 0,dword PG_UNMAP
|
|
stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP
|
|
dec [pg_data.pg_mutex]
|
|
ret
|
|
endp
|
|
|
|
align 4
|
|
proc fs_execute
|
|
|
|
;fn_read:dword, file_size:dword, cluster:dword
|
|
|
|
; ebx - cmdline
|
|
; edx - flags
|
|
; ebp - full filename
|
|
; [esp+4] = procedure DoRead, [esp+8] = filesize & [esp+12]... - arguments for it
|
|
|
|
locals
|
|
cmdline dd ?
|
|
flags dd ?
|
|
filename dd ?
|
|
retval dd ?
|
|
endl
|
|
|
|
pushad
|
|
|
|
mov [cmdline], ebx
|
|
mov [flags], edx
|
|
mov eax, [ebp]
|
|
mov [filename], eax
|
|
|
|
stdcall wait_mutex, pg_data.tmp_task_mutex
|
|
|
|
mov edi, [tmp_task_data]
|
|
mov ecx, (2048+256)/4
|
|
xor eax, eax
|
|
rep stosd
|
|
|
|
mov esi, [filename]
|
|
mov edi, [tmp_task_data]
|
|
add edi, TMP_FILE_NAME
|
|
mov ecx, 1024
|
|
rep movsb
|
|
|
|
mov esi, [filename]
|
|
mov edi, [tmp_task_data]
|
|
add edi, TMP_ICON_OFFS
|
|
mov ecx, 1024
|
|
rep movsb
|
|
|
|
mov esi, [cmdline]
|
|
test esi, esi
|
|
jz @f
|
|
mov edi, [tmp_task_data]
|
|
add edi, TMP_CMD_LINE
|
|
mov ecx, 256
|
|
rep movsb
|
|
@@:
|
|
mov eax, TMP_FILE_NAME
|
|
add eax, [tmp_task_data]
|
|
mov ebx, [tmp_task_data] ;cmd line
|
|
add ebx, TMP_CMD_LINE
|
|
|
|
stdcall fs_exec, eax, ebx, [flags], [ebp+8],\
|
|
[ebp+12], [ebp+16],[ebp+20]
|
|
mov [retval], eax
|
|
popad
|
|
mov [pg_data.tmp_task_mutex], 0
|
|
mov eax, [retval]
|
|
ret
|
|
|
|
endp
|
|
|
|
align 4
|
|
proc fs_exec stdcall file_name:dword, cmd_line:dword, flags:dword,\
|
|
fn_read:dword, file_size:dword,\
|
|
cluster:dword, some_data:dword
|
|
|
|
locals
|
|
slot dd ?
|
|
app_path_size dd ?
|
|
save_cr3 dd ?
|
|
img_size dd ?
|
|
endl
|
|
|
|
; check filename length - with terminating NULL must be no more than 1024 symbols
|
|
|
|
mov edi, [file_name]
|
|
mov ecx, 1024
|
|
xor eax, eax
|
|
repnz scasb
|
|
jz @f
|
|
mov eax, -ERROR_FILE_NOT_FOUND
|
|
ret
|
|
@@:
|
|
sub edi, [file_name]
|
|
mov [app_path_size], edi
|
|
|
|
mov esi, new_process_loading
|
|
call sys_msg_board_str ; write message to message board
|
|
|
|
pushfd
|
|
cli
|
|
|
|
.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
|
|
mov ecx, -0x20 ; too many processes
|
|
jz .err
|
|
mov [slot], eax
|
|
|
|
mov edi,eax
|
|
shl edi,8
|
|
add edi,PROC_BASE
|
|
mov ecx,256/4
|
|
xor eax,eax
|
|
cld
|
|
rep stosd ;clean extended information about process
|
|
|
|
; write application name
|
|
|
|
mov edi, [file_name]
|
|
mov ecx, [app_path_size]
|
|
add edi, ecx
|
|
dec edi
|
|
std
|
|
mov al, '/'
|
|
repnz scasb
|
|
cld
|
|
jnz @f
|
|
inc edi
|
|
@@:
|
|
inc edi
|
|
; now edi points to name without path
|
|
|
|
mov esi, edi
|
|
mov ecx, 8 ; 8 chars for name
|
|
mov edi, [slot]
|
|
shl edi, cl
|
|
add edi, PROC_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 al, ' '
|
|
rep stosb
|
|
pop eax
|
|
mov cl, 3 ; 3 chars for extension
|
|
dec esi
|
|
@@:
|
|
dec eax
|
|
cmp eax, esi
|
|
jbe .copy_process_ext_done
|
|
cmp byte [eax], '.'
|
|
jnz @b
|
|
lea esi, [eax+1]
|
|
.copy_process_ext_loop:
|
|
lodsb
|
|
test al, al
|
|
jz .copy_process_ext_done
|
|
stosb
|
|
loop .copy_process_ext_loop
|
|
.copy_process_ext_done:
|
|
mov al, ' '
|
|
rep stosb
|
|
|
|
; read header
|
|
lea eax, [file_size]
|
|
mov ebx, [eax]
|
|
mov [img_size], ebx
|
|
mov edi, TMP_BUFF
|
|
call [fn_read]
|
|
|
|
test eax, eax
|
|
jnz .err
|
|
|
|
; check menuet signature
|
|
|
|
mov ecx, -0x1F
|
|
;check MENUET signature
|
|
cmp [TMP_BUFF],dword 'MENU'
|
|
jnz .err
|
|
cmp [TMP_BUFF+4],word 'ET'
|
|
jnz .err
|
|
|
|
stdcall test_app_header, TMP_BUFF
|
|
test eax, eax
|
|
jz .err
|
|
|
|
mov eax, cr3
|
|
mov [save_cr3], eax
|
|
if GREEDY_KERNEL
|
|
stdcall create_app_space,[app_mem],[img_size]
|
|
else
|
|
stdcall create_app_space,[app_mem],[app_mem]
|
|
end if
|
|
test eax, eax
|
|
jz .failed
|
|
|
|
mov ebx,[slot]
|
|
shl ebx,8
|
|
mov [PROC_BASE+ebx+0xB8],eax
|
|
|
|
mov esi, TMP_BUFF
|
|
mov edi, new_app_base
|
|
mov ecx, 512/4
|
|
cld
|
|
rep movsd
|
|
|
|
;read file
|
|
@@:
|
|
lea eax, [file_size]
|
|
cmp dword [eax], 0
|
|
jz .done
|
|
push edi
|
|
call [fn_read]
|
|
pop edi
|
|
add edi, 512
|
|
test eax, eax
|
|
jz @b
|
|
cmp ebx, 6
|
|
jne .failed
|
|
.done:
|
|
stdcall add_app_parameters, [slot], new_app_base,\
|
|
[cmd_line],[file_name],[flags]
|
|
|
|
mov eax, [save_cr3]
|
|
call set_cr3
|
|
|
|
xor eax, eax
|
|
mov [application_table_status],eax ;unlock application_table_status mutex
|
|
popfd
|
|
mov eax,[process_number] ;set result
|
|
ret
|
|
|
|
.failed:
|
|
mov eax, [save_cr3]
|
|
call set_cr3
|
|
.err:
|
|
|
|
popfd
|
|
xor eax, eax
|
|
mov [application_table_status],eax
|
|
ret
|
|
endp
|
|
|
|
align 4
|
|
proc add_app_parameters stdcall,slot:dword,img_base:dword,\
|
|
cmd_line:dword, app_path:dword, flags:dword
|
|
|
|
mov eax,[slot]
|
|
bt [cpu_caps], CAPS_SSE
|
|
jnc .no_SSE
|
|
shl eax, 8
|
|
mov ebx, eax
|
|
add eax, eax
|
|
add eax, [fpu_data]
|
|
mov [ebx+PROC_BASE+APPDATA.fpu_state], eax
|
|
mov [ebx+PROC_BASE+APPDATA.fpu_handler], 0
|
|
mov [ebx+PROC_BASE+APPDATA.sse_handler], 0
|
|
jmp .m1
|
|
.no_SSE:
|
|
mov ecx, eax
|
|
mov ebx, eax
|
|
shl eax, 7
|
|
shl ebx, 4
|
|
sub eax, ebx ;eax*=112
|
|
add eax, [fpu_data]
|
|
shl ecx, 8
|
|
mov [ecx+PROC_BASE+APPDATA.fpu_state], eax
|
|
mov [ecx+PROC_BASE+APPDATA.fpu_handler], 0
|
|
mov [ecx+PROC_BASE+APPDATA.sse_handler], 0
|
|
.m1:
|
|
mov ebx,[slot]
|
|
cmp ebx,[TASK_COUNT]
|
|
jle .noinc
|
|
inc dword [TASK_COUNT] ;update number of processes
|
|
.noinc:
|
|
shl ebx,8
|
|
mov eax,[app_mem]
|
|
mov [PROC_BASE+0x8c+ebx],eax
|
|
|
|
shr ebx,3
|
|
mov eax, new_app_base
|
|
mov dword [CURRENT_TASK+ebx+0x10],eax
|
|
|
|
.add_command_line:
|
|
mov edx,[app_i_param]
|
|
test edx,edx
|
|
jz .no_command_line ;application don't need parameters
|
|
mov eax,[cmd_line]
|
|
test eax,eax
|
|
jz .no_command_line ;no parameters specified
|
|
;calculate parameter length
|
|
xor ecx,ecx
|
|
.command_line_len:
|
|
cmp byte [eax],0
|
|
jz .command_line_len_end
|
|
inc eax
|
|
inc ecx
|
|
cmp ecx,255
|
|
jl .command_line_len
|
|
|
|
.command_line_len_end:
|
|
;ecx - parameter length
|
|
;edx - address of parameters in new process address space
|
|
inc ecx
|
|
mov edi, [img_base]
|
|
add edi, edx
|
|
mov esi, [cmd_line]
|
|
rep movsb
|
|
|
|
.no_command_line:
|
|
|
|
mov edx,[app_i_icon]
|
|
test edx,edx
|
|
jz .no_command_line_1 ;application don't need path of file
|
|
mov esi,[app_path]
|
|
test esi, esi
|
|
jz .no_command_line_1 ;application don't need path of file
|
|
mov ecx, 64
|
|
mov edi, [img_base]
|
|
add edi, edx
|
|
rep movsb
|
|
|
|
.no_command_line_1:
|
|
mov ebx,[slot]
|
|
mov eax,ebx
|
|
shl ebx,5
|
|
add ebx,CURRENT_TASK ;ebx - pointer to information about process
|
|
mov [ebx+0xe],al ;set window number on screen = process slot
|
|
|
|
mov [ebx],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
|
|
|
|
mov ecx,ebx
|
|
add ecx,(draw_data-CURRENT_TASK) ;ecx - pointer to draw data
|
|
;set draw data to full screen
|
|
|
|
mov [ecx+0],dword 0
|
|
mov [ecx+4],dword 0
|
|
mov eax,[SCR_X_SIZE]
|
|
mov [ecx+8],eax
|
|
mov eax,[SCR_Y_SIZE]
|
|
mov [ecx+12],eax
|
|
;set window state to 'normal' (non-minimized/maximized/rolled-up) state
|
|
mov [ecx+WDATA.fl_wstate],WSTATE_NORMAL
|
|
;set cr3 register in TSS of application
|
|
|
|
mov ecx,[slot]
|
|
shl ecx,8
|
|
mov eax,[PROC_BASE+0xB8+ecx]
|
|
;or eax, PG_NOCACHE
|
|
mov [l.cr3],eax
|
|
|
|
mov eax,[app_start]
|
|
mov [l.eip],eax ;set eip in TSS
|
|
mov eax,[app_esp]
|
|
mov [l.esp],eax ;set stack in TSS
|
|
|
|
;gdt
|
|
mov ax,app_code ;ax - selector of code segment
|
|
mov [l.cs],ax
|
|
mov ax,app_data
|
|
mov [l.ss],ax
|
|
mov [l.ds],ax
|
|
mov [l.es],ax
|
|
mov [l.fs],ax
|
|
mov ax,graph_data ;ax - selector of graphic segment
|
|
mov [l.gs],ax
|
|
mov [l.io],word 128
|
|
mov [l.eflags],dword 0x1202
|
|
|
|
mov [l.ss0],os_data
|
|
mov ebx,[slot]
|
|
shl ebx,12
|
|
add ebx,sysint_stack_data+4096
|
|
mov [l.esp0],ebx
|
|
|
|
;copy tss to it place
|
|
mov eax,tss_sceleton
|
|
mov ebx,[slot]
|
|
imul ebx,tss_step
|
|
add ebx,tss_data ;ebx - address of application TSS
|
|
mov ecx,120
|
|
call memmove
|
|
|
|
;Add IO access table - bit array of permitted ports
|
|
or eax,-1
|
|
mov edi,[slot]
|
|
imul edi,tss_step
|
|
add edi,tss_data+128
|
|
mov ecx,2048
|
|
cld
|
|
rep stosd ;full access to 2048*8=16384 ports
|
|
|
|
mov ecx,ebx ;ecx - address of application TSS
|
|
mov edi,[slot]
|
|
shl edi,3
|
|
;set TSS descriptor
|
|
mov [edi+gdts+tss0+0],word tss_step ;limit (size)
|
|
mov [edi+gdts+tss0+2],cx ;part of offset
|
|
mov eax,ecx
|
|
shr eax,16
|
|
mov [edi+gdts+tss0+4],al ;part of offset
|
|
mov [edi+gdts+tss0+7],ah ;part of offset
|
|
mov [edi+gdts+tss0+5],word 01010000b*256+11101001b ;system flags
|
|
|
|
;flush keyboard and buttons queue
|
|
mov [KEY_COUNT],byte 0
|
|
mov [BTN_COUNT],byte 0
|
|
|
|
mov edi,[slot]
|
|
shl edi,5
|
|
add edi,window_data
|
|
mov ebx,[slot]
|
|
movzx esi,word [WIN_STACK+ebx*2]
|
|
lea esi,[WIN_POS+esi*2]
|
|
call windowactivate ;gui initialization
|
|
|
|
mov ebx,[slot]
|
|
shl ebx,5
|
|
mov [CURRENT_TASK+ebx+0xa],byte 0 ;set process state - running
|
|
; set if debuggee
|
|
mov eax, [flags]
|
|
test byte [flags], 1
|
|
jz .no_debug
|
|
mov [CURRENT_TASK+ebx+0xa],byte 1 ;set process state - suspended
|
|
mov eax,[CURRENT_TASK]
|
|
mov [PROC_BASE+ebx*8+0xac],eax ;set debugger PID - current
|
|
.no_debug:
|
|
|
|
mov esi,new_process_running
|
|
call sys_msg_board_str ;output information about succefull startup
|
|
|
|
ret
|
|
endp
|
|
|
|
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,[PROC_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
|
|
mov [r_count], ecx
|
|
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]
|
|
add ebx, new_app_base
|
|
push ecx
|
|
stdcall map_memEx, [proc_mem_map],\
|
|
[PROC_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 [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
|
|
mov [w_count], ecx
|
|
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],\
|
|
[PROC_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 [offset], edx
|
|
sub [tmp_w_cnt], edx
|
|
jnz .read_mem
|
|
|
|
popad
|
|
mov eax, [w_count]
|
|
ret
|
|
endp
|
|
|
|
|
|
align 4
|
|
proc new_sys_threads
|
|
locals
|
|
thread_start dd ?
|
|
thread_stack dd ?
|
|
params dd ?
|
|
slot dd ?
|
|
endl
|
|
|
|
mov [thread_start], ebx
|
|
mov [thread_stack], ecx
|
|
mov [params], 0
|
|
|
|
xor edx,edx ; flags=0
|
|
|
|
cmp eax,1
|
|
jnz .failed ;other subfunctions
|
|
mov esi,new_process_loading
|
|
call sys_msg_board_str
|
|
|
|
.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
|
|
|
|
xor eax,eax
|
|
mov [app_i_param],eax
|
|
mov [app_i_icon],eax
|
|
|
|
mov ebx, [thread_start]
|
|
mov ecx, [thread_stack]
|
|
|
|
mov [app_start],ebx
|
|
mov [app_esp],ecx
|
|
|
|
mov esi,[CURRENT_TASK]
|
|
shl esi,8
|
|
add esi,PROC_BASE
|
|
mov ebx,esi ;ebx=esi - pointer to extended information about current thread
|
|
|
|
mov edi,[slot]
|
|
shl edi,8
|
|
add edi,PROC_BASE
|
|
mov edx,edi ;edx=edi - pointer to extended infomation about new thread
|
|
mov ecx,256/4
|
|
rep stosd ;clean extended information about new thread
|
|
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 [app_mem],eax ;set memory size
|
|
mov eax,[ebx+0xb8]
|
|
mov [edx+0xb8],eax ;copy page directory
|
|
|
|
stdcall add_app_parameters, [slot], new_app_base,\
|
|
[params], dword 0,dword 0
|
|
|
|
mov esi,new_process_running
|
|
call sys_msg_board_str ;output information about succefull startup
|
|
|
|
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
|
|
|
|
align 4
|
|
proc wait_mutex stdcall, mutex:dword
|
|
mov ebx, [mutex]
|
|
.wait_lock:
|
|
cmp dword [ebx],0
|
|
je .get_lock
|
|
push ebx
|
|
call change_task
|
|
pop ebx
|
|
jmp .wait_lock
|
|
|
|
.get_lock:
|
|
mov eax, 1
|
|
xchg eax, [ebx]
|
|
test eax, eax
|
|
jnz .wait_lock
|
|
ret
|
|
endp
|
|
|
|
|
|
include "debug.inc"
|
|
|
|
iglobal
|
|
new_process_loading db 'K : New Process - loading',13,10,0
|
|
new_process_running db 'K : New Process - done',13,10,0
|
|
start_not_enough_memory db 'K : New Process - not enough memory',13,10,0
|
|
endg
|
|
|