0,0 → 1,1173 |
|
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 ? |
master_addr dd ? |
app_tabs dd ? |
endl |
|
stdcall wait_mutex, pg_data.pg_mutex |
|
xor eax, eax |
mov [dir_addr], eax |
mov [master_addr], eax |
|
mov eax, [app_size] |
add eax, 4095+4096 |
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 eax, [img_size] |
add eax, 4095 |
and eax, NOT(4095) |
|
mov [img_size], eax |
shr eax, 12 |
mov [img_pages], eax |
|
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 |
|
call alloc_page |
test eax, eax |
jz .fail |
mov [master_addr], eax |
stdcall map_page,[tmp_task_ptab],eax,dword PG_SW |
|
mov ecx, 384 |
mov edi, [tmp_task_ptab] |
mov esi, master_tab |
cld |
rep movsd |
|
mov ecx, 384 |
xor eax, eax |
rep stosd |
|
mov ecx, 256 |
mov esi, master_tab+0xc00 |
rep movsd |
|
mov eax, [master_addr] |
or eax, PG_SW |
mov ebx, [tmp_task_pdir] |
mov [ebx+0x600], eax |
mov ecx, [tmp_task_ptab] |
mov [ecx+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,[tmp_task_pdir], 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_ptab],dword 0,dword PG_UNMAP |
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, 0x600 |
mov eax, [esi] |
call free_page ;destroy master table |
add esi, 4 |
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 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 |
stdcall create_app_space,[app_mem], [app_mem];[file_size] |
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 0x3202 |
|
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+0x8c] |
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 |
|