From c1783c769fb265d2c9dcbe6342d11aac97a53b56 Mon Sep 17 00:00:00 2001 From: "Evgeny Grechnikov (Diamond)" Date: Mon, 26 Jun 2006 12:13:58 +0000 Subject: [PATCH] 1. Execution of files with long names (function 70.7). 2. Function 70 now supports folders on ramdisk. git-svn-id: svn://kolibrios.org@91 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/trunk/blkdev/rd.inc | 439 +++++++++++++++++++++++++++------ kernel/trunk/core/newproce.inc | 238 +++++++++++++++++- kernel/trunk/docs/sysfuncr.txt | 160 +++++------- kernel/trunk/fs/fat12.inc | 113 ++++++++- kernel/trunk/fs/fat32.inc | 132 +++++++++- kernel/trunk/fs/fs_lfn.inc | 7 +- 6 files changed, 902 insertions(+), 187 deletions(-) diff --git a/kernel/trunk/blkdev/rd.inc b/kernel/trunk/blkdev/rd.inc index 4c97bf0f60..5e2f7c4219 100644 --- a/kernel/trunk/blkdev/rd.inc +++ b/kernel/trunk/blkdev/rd.inc @@ -914,25 +914,104 @@ ramdisk_root_next: cmc ret +ramdisk_root_extend_dir: + stc + ret + +ramdisk_notroot_next: + add edi, 0x20 + test edi, 0x1FF + jz ramdisk_notroot_next_sector + ret ; CF=0 +ramdisk_notroot_next_sector: + push ecx + mov ecx, [eax] + mov ecx, [ecx*2+0x280000] + and ecx, 0xFFF + cmp ecx, 2849 + jae ramdisk_notroot_first.err2 + mov [eax], ecx + pop ecx +ramdisk_notroot_first: + mov eax, [eax] + cmp eax, 2 + jb .err + cmp eax, 2849 + jae .err + shl eax, 9 + lea edi, [eax+(31 shl 9)+0x100000] + clc + ret +.err2: + pop ecx +.err: + stc + ret +ramdisk_notroot_next_write: + test edi, 0x1FF + jz ramdisk_notroot_next_sector +ramdisk_root_next_write: + ret + +ramdisk_notroot_extend_dir: + pusha + xor eax, eax + mov edi, 0x280000 + mov ecx, 2849 + repnz scasw + jnz .notfound + mov word [edi-2], 0xFFF + sub edi, 0x280000 + shr edi, 1 + dec edi + mov eax, [esp+28] + mov ecx, [eax] + mov [0x280000+ecx*2], di + mov [eax], edi + shl edi, 9 + add edi, (31 shl 9)+0x100000 + mov [esp], edi + xor eax, eax + mov ecx, 128 + rep stosd + popa + clc + ret +.notfound: + popa + stc + ret + rd_find_lfn: ; in: esi->name ; out: CF=1 - file not found ; else CF=0 and edi->direntry push esi edi + push 0 push ramdisk_root_first push ramdisk_root_next +.loop: call fat_find_lfn jc .notfound cmp byte [esi], 0 - jnz .notfound - add esp, 12 - pop esi - ret ; CF=0 + jz .found + test byte [edi+11], 10h + jz .notfound + movzx eax, word [edi+26] + mov [esp+8], eax + mov dword [esp+4], ramdisk_notroot_first + mov dword [esp], ramdisk_notroot_next + jmp .loop .notfound: - add esp, 8 + add esp, 12 pop edi esi stc ret +.found: + mov eax, [esp+8] + add esp, 16 ; CF=0 + pop esi + ret ;---------------------------------------------------------------- ; @@ -1041,37 +1120,76 @@ fs_RamdiskRead: ; ;-------------------------------------------------------------- fs_RamdiskReadFolder: + push edi cmp byte [esi], 0 - jz @f -; ramdisk doesn't support folders - mov eax, ERROR_ACCESS_DENIED + jz .root + call rd_find_lfn + jnc .found + pop edi or ebx, -1 + mov eax, ERROR_FILE_NOT_FOUND ret -@@: - push esi edi ecx +.found: + test byte [edi+11], 0x10 + jnz .found_dir + pop edi + or ebx, -1 + mov eax, ERROR_ACCESS_DENIED + ret +.found_dir: + movzx eax, word [edi+26] + add eax, 31 + push 0 + jmp .doit +.root: + mov eax, 19 + push 14 +.doit: + push esi ecx ebp + sub esp, 262*2 ; reserve space for LFN + mov ebp, esp + push dword [ebx+4] ; for fat_get_name: read ANSI/UNICODE names + mov ebx, [ebx] ; init header - push ecx + push eax ecx mov edi, edx mov ecx, 32/4 xor eax, eax rep stosd mov byte [edx], 1 ; version - pop ecx - push ebp - sub esp, 262*2 ; allocate space for LFN - mov ebp, esp - push dword [ebx+4] ; for fat_get_name: read ANSI/UNICODE name - mov ebx, [ebx] -; read root + pop ecx eax mov esi, edi ; esi points to block of data of folder entry (BDFE) - mov edi, 0x100000+512*19 +.main_loop: + mov edi, eax + shl edi, 9 + add edi, 0x100000 + push eax .l1: call fat_get_name jc .l2 cmp byte [edi+11], 0xF - jnz @f + jnz .do_bdfe add edi, 0x20 + test edi, 0x1FF + jnz .do_bdfe + pop eax + inc eax + dec byte [esp+262*2+16] + jz .done + jns @f +; read next sector from FAT + mov eax, [(eax-31-1)*2+0x280000] + and eax, 0xFFF + cmp eax, 0xFF8 + jae .done + add eax, 31 + mov byte [esp+262*2+16], 0 @@: + mov edi, eax + shl edi, 9 + add edi, 0x100000 + push eax +.do_bdfe: inc dword [edx+8] ; new file found dec ebx jns .l2 @@ -1081,8 +1199,23 @@ fs_RamdiskReadFolder: call fat_entry_to_bdfe .l2: add edi, 0x20 - cmp edi, 0x100000+512*33 - jb .l1 + test edi, 0x1FF + jnz .l1 + pop eax + inc eax + dec byte [esp+262*2+16] + jz .done + jns @f +; read next sector from FAT + mov eax, [(eax-31-1)*2+0x280000] + and eax, 0xFFF + cmp eax, 0xFF8 + jae .done + add eax, 31 + mov byte [esp+262*2+16], 0 +@@: + jmp .main_loop +.done: add esp, 262*2+4 pop ebp mov ebx, [edx+4] @@ -1091,7 +1224,7 @@ fs_RamdiskReadFolder: js @f mov al, ERROR_END_OF_FILE @@: - pop ecx edi esi + pop ecx esi edi edi ret iglobal @@ -1346,7 +1479,8 @@ fat_gen_short_name: fs_RamdiskRewrite: cmp byte [esi], 0 jz @b -; ramdisk doesn't support folders + pushad + xor ebp, ebp push esi @@: lodsb @@ -1354,18 +1488,59 @@ fs_RamdiskRewrite: jz @f cmp al, '/' jnz @b + lea ebp, [esi-1] + jmp @b +@@: pop esi -.err5: - mov eax, 5 ; file not found + test ebp, ebp + jnz .noroot + push ramdisk_root_extend_dir + push ramdisk_root_next_write + push ebp + push ramdisk_root_first + push ramdisk_root_next + jmp .common1 +.noroot: +; check existence + mov byte [ebp], 0 + call rd_find_lfn + mov byte [ebp], '/' + lea esi, [ebp+1] + jnc @f + mov eax, ERROR_FILE_NOT_FOUND +.ret1: + mov [esp+28], eax + popad xor ebx, ebx ret @@: - pop esi -; check existence - push edi - call rd_find_lfn + test byte [edi+11], 0x10 ; must be directory + mov eax, ERROR_ACCESS_DENIED + jz .ret1 + movzx ebp, word [edi+26] ; ebp=cluster + mov eax, ERROR_FAT_TABLE + cmp ebp, 2 + jb .ret1 + cmp ebp, 2849 + jae .ret1 + push ramdisk_notroot_extend_dir + push ramdisk_notroot_next_write + push ebp + push ramdisk_notroot_first + push ramdisk_notroot_next +.common1: + call fat_find_lfn jc .notfound -; found, delete FAT chain +; found; must not be directory + test byte [edi+11], 10h + jz @f + add esp, 20 + popad + mov eax, ERROR_ACCESS_DENIED + xor ebx, ebx + ret +@@: +; delete FAT chain push edi xor eax, eax mov dword [edi+28], eax ; zero size @@ -1392,17 +1567,24 @@ fs_RamdiskRewrite: ; file is not found; generate short name call fat_name_is_legal jc @f - pop edi - jmp .err5 + add esp, 20 + popad + mov eax, ERROR_FILE_NOT_FOUND + xor ebx, ebx + ret @@: sub esp, 12 mov edi, esp call fat_gen_short_name .test_short_name_loop: - push esi ecx - mov esi, 0x100000+512*19 + push esi edi ecx + mov esi, edi + lea eax, [esp+12+12+8] + mov [eax], ebp + call dword [eax-4] + jc .found .test_short_name_entry: - cmp byte [esi+11], 0xF + cmp byte [edi+11], 0xF jz .test_short_name_cont mov ecx, 11 push esi edi @@ -1410,22 +1592,22 @@ fs_RamdiskRewrite: pop edi esi jz .short_name_found .test_short_name_cont: - add esi, 20h - cmp esi, 0x100000+512*33 - jb .test_short_name_entry - pop ecx esi + lea eax, [esp+12+12+8] + call dword [eax-8] + jnc .test_short_name_entry jmp .found .short_name_found: + pop ecx edi esi call fat_next_short_name - pop ecx esi jnc .test_short_name_loop .disk_full: - add esp, 12 - pop edi + add esp, 12+20 + popad mov eax, ERROR_DISK_FULL xor ebx, ebx ret .found: + pop ecx edi esi ; now find space in directory ; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~' mov al, '~' @@ -1452,9 +1634,15 @@ fs_RamdiskRewrite: div ecx pop edx .notilde: + push -1 + push -1 ; find successive entries in directory xor ecx, ecx - mov edi, 0x100000+512*19 + push eax + lea eax, [esp+12+8+12+8] + mov [eax], ebp + call dword [eax-4] + pop eax .scan_dir: cmp byte [edi], 0 jz .free @@ -1462,19 +1650,36 @@ fs_RamdiskRewrite: jz .free xor ecx, ecx .scan_cont: - add edi, 0x20 - cmp edi, 0x100000+512*33 - jb .scan_dir - pop edi ecx - jmp .disk_full + push eax + lea eax, [esp+12+8+12+8] + call dword [eax-8] + pop eax + jnc .scan_dir + push eax + lea eax, [esp+12+8+12+8] + call dword [eax+8] ; extend directory + pop eax + jnc .scan_dir + add esp, 8+8+12+20 + popad + mov eax, ERROR_DISK_FULL + xor ebx, ebx + ret .free: + test ecx, ecx + jnz @f + mov [esp], edi + mov ecx, [esp+8+8+12+8] + mov [esp+4], ecx + xor ecx, ecx +@@: inc ecx cmp ecx, eax jb .scan_cont ; found! ; calculate name checksum push esi ecx - mov esi, [esp+8] + mov esi, [esp+8+8] mov ecx, 11 xor eax, eax @@: @@ -1483,39 +1688,40 @@ fs_RamdiskRewrite: inc esi loop @b pop ecx esi + pop edi + pop dword [esp+8+12+8] ; edi points to last entry in free chunk dec ecx jz .nolfn push esi - push edi + push eax + mov al, 40h .writelfn: - sub edi, 20h - push ecx eax - mov eax, [esp+8] - sub eax, edi - shr eax, 5 - cmp ecx, 1 - jnz @f - or al, 40h -@@: + or al, cl + mov esi, [esp+4] + push ecx + dec ecx + imul ecx, 13 + add esi, ecx stosb mov cl, 5 call .read_symbols mov ax, 0xF stosw - pop eax + mov al, [esp+4] stosb - push eax mov cl, 6 call .read_symbols xor eax, eax stosw mov cl, 2 call .read_symbols - pop eax ecx - sub edi, 0x20 + pop ecx + lea eax, [esp+8+8+12+8] + call dword [eax+4] ; next write + xor eax, eax loop .writelfn - pop edi + pop eax pop esi .nolfn: xchg esi, [esp] @@ -1537,7 +1743,7 @@ fs_RamdiskRewrite: and word [edi+26], 0 ; low word of cluster - to be filled and dword [edi+28], 0 ; file size - to be filled .doit: - push ecx edx + push edx push ecx push edi add edi, 26 ; edi points to low word of cluster @@ -1578,18 +1784,20 @@ fs_RamdiskRewrite: jnz .write_loop .done: mov ebx, edx - pop edi edi ecx edx ecx + pop edi edi ecx edx sub ebx, edx mov [edi+28], ebx - pop edi + add esp, 20 + popad xor eax, eax ret .disk_full2: mov ebx, edx - pop edi edi ecx edx ecx + pop edi edi ecx edx sub ebx, edx mov [edi+28], ebx - pop edi + add esp, 20 + popad push ERROR_DISK_FULL pop eax ret @@ -1654,4 +1862,95 @@ fs_RamdiskSetFileInfo: xor eax, eax ret +;---------------------------------------------------------------- +; +; fs_RamdiskExecute - LFN variant for executing on sys floppy +; +; esi points to ramdisk filename (e.g. 'launcher') +; ebp points to full filename (e.g. '/rd/1/launcher') +; dword [ebx] = flags +; dword [ebx+4] = cmdline +; +; ret ebx,edx destroyed +; eax > 0 - PID, < 0 - error +; +;-------------------------------------------------------------- +fs_RamdiskExecute: + mov edx, [ebx] + mov ebx, [ebx+4] + test ebx, ebx + jz @f + add ebx, std_application_base_address +@@: + +;---------------------------------------------------------------- +; +; fs_RamdiskExecute.flags - second entry +; +; esi points to ramdisk filename (kernel address) +; ebp points to full filename +; edx flags +; ebx cmdline (kernel address) +; +; ret eax > 0 - PID, < 0 - error +; +;-------------------------------------------------------------- + +.flags: + cmp byte [esi], 0 + jnz @f +; cannot execute root! + mov eax, -ERROR_ACCESS_DENIED + ret +@@: + push edi + call rd_find_lfn + jnc .found + pop edi + mov eax, -ERROR_FILE_NOT_FOUND + ret +.found: + movzx eax, word [edi+26] ; cluster + push eax + push dword [edi+28] ; size + push .DoRead + call fs_execute + add esp, 12 + pop edi + ret + +.DoRead: +; read next block +; in: eax->parameters, edi->buffer +; out: eax = error code + pushad + cmp dword [eax], 0 ; file size + jz .eof + mov edx, [eax+4] ; cluster + lea esi, [edx+31] + shl esi, 9 + add esi, 0x100000 + mov ecx, 512/4 + rep movsd + mov ecx, [eax] + sub ecx, 512 + jae @f + add edi, ecx + neg ecx + push eax + xor eax, eax + rep stosb + pop eax +@@: + mov [eax], ecx + mov dx, [edx*2+0x280000] + mov [eax+4], dx ; high word is already zero + popad + xor eax, eax + ret +.eof: + popad + mov eax, 6 + ret + ; \end{diamond} diff --git a/kernel/trunk/core/newproce.inc b/kernel/trunk/core/newproce.inc index 9a93e1ae8a..2e5cb7157c 100644 --- a/kernel/trunk/core/newproce.inc +++ b/kernel/trunk/core/newproce.inc @@ -307,8 +307,8 @@ new_start_application_fl: jz .cleanfailed mov eax,[new_process_place] - call create_app_cr3_table ;create page directory for new process inc ecx ; -0x1E = no memory + call create_app_cr3_table ;create page directory for new process test eax,eax jz .cleanfailed_mem @@ -563,14 +563,16 @@ new_start_application_fl: mov ebx,[new_process_place] shl ebx,5 - mov [0x3000+ebx+0xa],byte 0 ;set process state - running ; set if debuggee - test byte [esp+28], 1 - jz .no_debug - mov [0x3000+ebx+0xa],byte 1 ;set process state - suspended - mov eax,[0x3000] - mov [0x80000+ebx*8+0xac],eax ;set debugger PID - current + test byte [esp+28], 1 + jz .no_debug + mov [0x3000+ebx+0xa], byte 1 ; set process state - suspended + mov eax, [0x3000] + mov [0x80000+ebx*8+0xac], eax ;set debugger PID - current + jmp .debug .no_debug: + mov [0x3000+ebx+0xa], byte 0 ; set process state - running +.debug: mov esi,new_process_running call sys_msg_board_str ;output information about succefull startup @@ -1269,9 +1271,9 @@ new_start_application_hd: jz .cleanfailed mov eax,[new_process_place] + inc ecx ; -0x1E = no memory call create_app_cr3_table ;create page directory test eax,eax - inc ecx ; -0x1E = no memory jz .cleanfailed_mem call MEM_Get_Linear_Address @@ -1392,4 +1394,222 @@ new_start_application_hd: ret end if - include 'debug.inc' +; \begin{diamond} + include 'debug.inc' + +fs_execute: +; ebx - cmdline +; edx - flags +; ebp - full filename +; [esp+4] = procedure DoRead, [esp+8] = filesize & [esp+12]... - arguments for it + pushad +; check filename length - with terminating NULL must be no more than 1024 symbols + mov edi, ebp + mov ecx, 1024 + xor eax, eax + repnz scasb + jz @f + popad + mov eax, -ERROR_FILE_NOT_FOUND + ret +@@: + + mov esi, new_process_loading + call sys_msg_board_str ; write message to message board + +; lock application_table_status mutex +.table_status: + cli + cmp [application_table_status], 0 + jz .stf + sti + call change_task + jmp .table_status +.stf: + call set_application_table_status + push ebx ; save command line pointer for add_app_parameters + + call find_new_process_place ; find new process slot + call safe_sti + test eax, eax + mov ecx, -0x20 ; too many processes + jz .failed + +; write application name + push edi + mov ecx, edi + sub ecx, ebp + mov [appl_path], ebp + mov [appl_path_size], 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, [new_process_place] + shl edi, cl + add edi, 0x80000 +.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, [esp+8+36] + mov edi, 0x90000 + call dword [eax-4] + mov ecx, eax + neg ecx + jnz .cleanfailed +; check menuet signature + mov ecx, -0x1F + cmp dword [0x90000], 'MENU' + jnz .cleanfailed + cmp word [0x90004], 'ET' + jnz .cleanfailed + call get_app_params + mov ecx, -0x1F + test esi, esi + jz .cleanfailed + + mov eax, [new_process_place] + inc ecx ; -0x1E = no memory + call create_app_cr3_table + test eax, eax + jz .cleanfailed_mem + + call MEM_Get_Linear_Address + + mov ebx, std_application_base_address + mov ecx, [app_mem] + add ecx, 4095 + shr ecx, 12 + mov edx, eax ; edx - linear address of page directory + call mem_alloc_specified_region + mov ecx, -0x1E ; no memory + test eax, eax + jz .cleanfailed_mem1 + + add edx, std_application_base_address shr 20 + mov eax, [edx] + and eax, not 4095 + call MEM_Get_Linear_Address + push edx ; save pointer to first page table + mov edx, eax +; read file +; first block is already read to 0x90000 + mov eax, [edx] + and eax, not 0xFFF + call MEM_Get_Linear_Address + mov esi, 0x90000 + mov edi, eax + mov ecx, 512/4 + rep movsd + sub edi, eax +.loop1: +; [esp] = pointer to current page directory entry +; edx = pointer to current page table +; edi = offset in page + mov eax, [edx] + and eax, not 0xFFF + call MEM_Get_Linear_Address + push edi + add edi, eax + lea eax, [esp+8+36+8] + call dword [eax-4] + pop edi + test eax, eax + jnz .endloop1 + add edi, 512 ; new offset + cmp edi, 4096 + jb .loop1 + xor edi, edi + add edx, 4 ; go to next page + test edx, 4096-1 + jnz .loop1 + pop eax + add eax, 4 ; go to next directory entry + push eax + mov eax, [eax] + and eax, not 0xFFF + call MEM_Get_Linear_Address + mov edx, eax + jmp .loop1 +.endloop1: + pop edx + cmp eax, 6 + jnz .cleanfailed_mem2 + call new_start_application_fl.add_app_parameters + mov [esp+28], eax + popad + ret + +.cleanfailed_mem2: +; file read error; free all allocated mem + mov ecx, eax + neg ecx + mov eax, [new_process_place] + call dispose_app_cr3_table + jmp .cleanfailed +.cleanfailed_mem1: +; there is mem for directory entry, but there is no mem for pages +; so free directory entry + mov eax, [new_process_place] + shl eax, 8 + mov eax, [0x80000+eax+0xB8] + call MEM_Free_Page +.cleanfailed_mem: +; there is no mem for directory entry, display message + mov esi, start_not_enough_memory + call sys_msg_board_str +.cleanfailed: + push ecx +; clean process name, this avoid problems with @panel + mov edi, [new_process_place] + shl edi, 8 + add edi, 0x80000 + mov ecx, 11 + mov al, ' ' + rep stosb + pop eax +.failed: + pop ebx + mov [esp+28], eax + popad + mov [application_table_status], 0 + call safe_sti + ret +; \end{diamond} diff --git a/kernel/trunk/docs/sysfuncr.txt b/kernel/trunk/docs/sysfuncr.txt index 78c372f070..0f0d815d90 100644 --- a/kernel/trunk/docs/sysfuncr.txt +++ b/kernel/trunk/docs/sysfuncr.txt @@ -581,7 +581,7 @@ чтобы форсировать выбор в меню выхода. ====================================================================== -========= Функция 18, подфункция 2 - завершить процесс/поток. ======== +==== Функция 18, подфункция 2 - завершить процесс/поток по слоту. ==== ====================================================================== Параметры: * eax = 18 - номер функции @@ -592,6 +592,8 @@ Замечания: * Нельзя завершить поток операционной системы OS/IDLE (номер слота 1), можно завершить любой обычный поток/процесс. + * Смотри также подфункцию 18 - завершение + процесса/потока с заданным идентификатором. ====================================================================== = Функция 18, подфункция 3 - сделать активным окно заданного потока. = @@ -929,18 +931,21 @@ db 'Kolibri',0 * eax = общий размер имеющейся памяти в килобайтах ====================================================================== -====================== Функция 18б подфункция 18 ===================== -===================== Завершение процесса по PID'у =================== +====================== Функция 18, подфункция 18 ===================== +============= Завершить процесс/поток по идентификатору. ============= ====================================================================== Параметры: * eax = 18 - номер функции * ebx = 18 - номер подфункции - * ecx = PID -Возращаемое значение: - * eax = 0 - процесс завершен. - * eax = -1 - ошибка. (процесс с таким PID не существует или является - системным) - + * ecx = идентификатор процесса/потока (PID/TID) +Возвращаемое значение: + * eax = 0 - успешно + * eax = -1 - ошибка (процесс не найден или является системным) +Замечания: + * Нельзя завершить поток операционной системы OS/IDLE (номер слота + 1), можно завершить любой обычный поток/процесс. + * Смотри также подфункцию 2 - завершение + процесса/потока по заданному слоту. ====================================================================== ============ Функция 19 - запустить программу с рамдиска. ============ @@ -953,7 +958,7 @@ db 'Kolibri',0 * Если eax > 0, то eax содержит PID созданного процесса * Если eax < 0, то -eax - код ошибки файловой системы Замечания: - * Эта функция устарела; используйте подфункцию 16 функции 58. + * Эта функция устарела; используйте подфункцию 7 функции 70. * Комадная строка должна заканчиваться символом с кодом 0 (ASCIIZ-строка); учитываются либо все символы до завершающего нуля включительно, либо первые 256 символов, в зависимости от того, @@ -3111,99 +3116,6 @@ dword- (вероятнее всего, нули, но это определяется устройством) и это будет считаться успехом (eax=0). -====================================================================== -========= Функция 58, подфункция 12 - получить размер файла. ========= -====================================================================== -Параметры: - * eax = 58 - номер функции - * ebx = указатель на информационную структуру -Формат информационной структуры: - * +0: dword: 12 = номер функции - * +4: dword: игнорируется - * +8: dword: игнорируется - * +12 = +0xC: dword: игнорируется - * +16 = +0x10: dword: указатель на буфер для работы системы - (4096 байт) - * +20 = +0x14: ASCIIZ-имя файла, правила формирования имён указаны в - общем описании -Возвращаемое значение: - * eax = 0 - успешно, иначе код ошибки файловой системы - * ebx = размер файла (в байтах) или 0 для HD, -1 для RD, - если файл не найден -Замечания: - * Эта функция устарела, используйте подфункцию 5 функции 70. - * Функция не поддерживается для дискет. - * Текущая реализация позволяет также определять размер папки - (по цепочке кластеров в FAT), но не следует на это полагаться. - -====================================================================== -===== Функция 58, подфункция 13 - получить атрибуты файла/папки. ===== -====================================================================== -Параметры: - * eax = 58 - номер функции - * ebx = указатель на информационную структуру -Формат информационной структуры: - * +0: dword: 13 = номер функции - * +4: dword: игнорируется - * +8: dword: игнорируется - * +12 = +0xC: dword: игнорируется - * +16 = +0x10: dword: указатель на буфер для работы системы - (4096 байт) - * +20 = +0x14: ASCIIZ-имя файла, правила формирования имён указаны в - общем описании -Возвращаемое значение: - * eax = 0 - успешно, иначе код ошибки файловой системы - * ebx = байт FAT-атрибута (дополненный нулями до dword) - или 0 для HD, -1 для RD, если файл не найден -Значения для битов FAT-атрибутов: - * бит 0: файл только для чтения - * бит 1: файл является скрытым - * бит 2: файл является системным - * бит 3: это не файл, а метка тома (может встречаться только - один раз на диске, в корневом каталоге) - * бит 4: это папка - * бит 5: файл не архивировался - многие программы архивации имеют - опцию, по которой архивируются только файлы с установленным этим - битом, после чего этот бит сбрасывается - это может быть полезно - для автоматического создания backup-архивов, ибо при записи - бит обычно устанавливается (не в Kolibri, правда) -Замечания: - * Эта функция устарела, используйте подфункцию 5 функции 70. - * Функция не поддерживается для дискет. - -====================================================================== -====================== Функция 58, подфункция 14 ===================== -======= Получить дату/время последней модификации файла/папки. ======= -====================================================================== -Параметры: - * eax = 58 - номер функции - * ebx = указатель на информационную структуру -Формат информационной структуры: - * +0: dword: 14 = номер функции - * +4: dword: игнорируется - * +8: dword: игнорируется - * +12 = +0xC: dword: игнорируется - * +16 = +0x10: dword: указатель на буфер для работы системы - (4096 байт) - * +20 = +0x14: ASCIIZ-имя файла, правила формирования имён указаны в - общем описании -Возвращаемое значение: - * eax = 0 - успешно, иначе код ошибки файловой системы - * ebx = дата/время в формате FAT или 0 для HD, -1 для RD, - если файл не найден - * младшее слово = время последней модификации, hhhhhmmmmmmsssss: - * младшие 5 бит = число двухсекундных интервалов, 0<=s<=29 - * следующие 6 бит = минуты, 0<=m<=59 - * старшие 5 бит = часы, 0<=h<=23 - * старшее слово = дата последней модификации, yyyyyyymmmmddddd: - * младшие 5 бит = день, 1<=d<=31 - * следующие 4 бита = месяц, 1<=m<=12 - * старшие 7 бит = год относительно 1980 -Замечания: - * Эта функция устарела, используйте подфункцию 5 функции 70. - * Функция не поддерживается для дискет. - * Создание файла/папки считается модификацией. - ====================================================================== = Функция 58, подфункция 15 - получить информацию о файловой системе. ====================================================================== @@ -3267,6 +3179,7 @@ dword- * eax < 0 - произошла ошибка, -eax содержит код ошибки файловой системы Замечания: + * Эта функция устарела, используйте подфункцию 7 функции 70. * Комадная строка должна заканчиваться символом с кодом 0 (ASCIIZ-строка); учитываются либо все символы до завершающего нуля включительно, либо первые 256 символов, в зависимости от того, @@ -4051,7 +3964,7 @@ Architecture Software Developer's Manual, Volume 3, Appendix B); Общий формат информационной структуры: * +0: dword: номер подфункции * +4: dword: смещение в файле - * +8: dword: старший dword смещения (должен быть 0) + * +8: dword: старший dword смещения (должен быть 0) или поле флагов * +12 = +0xC: dword: размер * +16 = +0x10: dword: указатель на данные * +20 = +0x14: n db: ASCIIZ-строка с именем файла @@ -4069,10 +3982,13 @@ Architecture Software Developer's Manual, Volume 3, Appendix B); * /FD/1 = /FLOPPYDISK/1 для доступа к первому флоппи-дисководу, /FD/2 = /FLOPPYDISK/2 для второго флоппи-дисковода * /HD0/x, /HD1/x, /HD2/x, /HD3/x для доступа соответственно - к устройствам IDE0 (Primary Master), IDE1 (Primary Slave), + к жёстким дискам на IDE0 (Primary Master), IDE1 (Primary Slave), IDE2 (Secondary Master), IDE3 (Secondary Slave); x - номер раздела на выбранном винчестере, изменяется от 1 до 255 (на каждом из винчестеров нумерация начинается с 1) + * /CD0/1, /CD1/1, /CD2/1, /CD3/1 для доступа соответственно + к CD на IDE0 (Primary Master), IDE1 (Primary Slave), + IDE2 (Secondary Master), IDE3 (Secondary Slace) Примеры: * '/rd/1/kernel.asm',0 * '/HD0/1/kernel.asm',0 @@ -4084,6 +4000,7 @@ Architecture Software Developer's Manual, Volume 3, Appendix B); * подфункция 2 - создание/перезапись файла * подфункция 5 - получение атрибутов файла/папки * подфункция 6 - установка атрибутов файла/папки + * подфункция 7 - запуск программы ====================================================================== = Функция 70, подфункция 0 - чтение файла с поддержкой длинных имён. = @@ -4297,6 +4214,39 @@ Architecture Software Developer's Manual, Volume 3, Appendix B); * Функция не поддерживает виртуальные папки типа /, /rd и корневые папки типа /rd/1. +====================================================================== +============ Функция 70, подфункция 7 - запуск программы. ============ +====================================================================== +Параметры: + * eax = 70 - номер функции + * ebx = указатель на информационную структуру +Формат информационной структуры: + * +0: dword: 7 = номер подфункции + * +4: dword: поле флагов: + * бит 0: запустить процесс как отлаживаемый + * остальные биты зарезервированы и должны быть установлены в 0 + * +8: dword: 0 или указатель на ASCIIZ-строку с параметрами + * +12 = +0xC: dword: 0 (зарезервировано) + * +16 = +0x10: dword: 0 (зарезервировано) + * +20 = +0x14: ASCIIZ-имя файла, правила формирования имён указаны в + общем описании + или + * +20 = +0x14: db 0 + * +21 = +0x15: dd указатель на ASCIIZ-строку с именем файла +Возвращаемое значение: + * eax > 0 - программа загружена, eax содержит PID + * eax < 0 - произошла ошибка, -eax содержит + код ошибки файловой системы + * ebx разрушается +Замечания: + * Командная строка должна заканчиваться символом с кодом 0 + (ASCIIZ-строка); учитываются либо все символы до завершающего нуля + включительно, либо первые 256 символов, в зависимости от того, + что меньше. + * Если процесс запускается как отлаживаемый, он создаётся + в замороженном состоянии; для запуска используйте + подфункцию 5 функции 69. + ====================================================================== ========== Функция -1 - завершить выполнение потока/процесса ========= ====================================================================== diff --git a/kernel/trunk/fs/fat12.inc b/kernel/trunk/fs/fat12.inc index a035bd1bf1..62a71c9688 100644 --- a/kernel/trunk/fs/fat12.inc +++ b/kernel/trunk/fs/fat12.inc @@ -1594,7 +1594,16 @@ fs_FloppyRewrite: .common1: call fat_find_lfn jc .notfound -; found, delete FAT chain +; found; must not be directory + test byte [edi+11], 10h + jz @f + add esp, 28 + popad + mov eax, ERROR_ACCESS_DENIED + xor ebx, ebx + ret +@@: +; delete FAT chain push edi xor eax, eax mov dword [edi+28], eax ; zero size @@ -1960,4 +1969,106 @@ fs_FloppySetFileInfo: @@: ret +;---------------------------------------------------------------- +; +; fs_FloppyExecute - LFN variant for executing from floppy +; +; esi points to floppy filename (e.g. 'dir1/name') +; ebp points to full filename (e.g. '/fd/1/dir1/name') +; dword [ebx] = flags +; dword [ebx+4] = cmdline +; +; ret ebx,edx destroyed +; eax > 0 - PID, < 0 - error +; +;-------------------------------------------------------------- +fs_FloppyExecute: + mov edx, [ebx] + mov ebx, [ebx+4] + test ebx, ebx + jz @f + add ebx, std_application_base_address +@@: + +;---------------------------------------------------------------- +; +; fs_FloppyExecute.flags - second entry +; +; esi points to floppy filename (kernel address) +; ebp points to full filename +; edx flags +; ebx cmdline (kernel address) +; +; ret eax > 0 - PID, < 0 - error +; +;-------------------------------------------------------------- + +.flags: + call read_flp_fat + cmp byte [esi], 0 + jnz @f +; cannot execute root! + mov eax, -ERROR_ACCESS_DENIED + ret +@@: + push edi + call fd_find_lfn + jnc .found + pop edi + mov eax, -ERROR_FILE_NOT_FOUND + ret +.found: + movzx eax, word [edi+26] ; cluster + push eax + push dword [edi+28] ; size + push .DoRead + call fs_execute + add esp, 12 + pop edi + ret + +.DoRead: +; read next block +; in: eax->parameters, edi->buffer +; out: eax = error code + pushad + cmp dword [eax], 0 ; file size + jz .eof + mov eax, [eax+4] ; cluster + add eax, 31 + call read_chs_sector + cmp [FDC_Status], 0 + jnz .err + pop edi + mov esi, 0xD000 + push edi + mov ecx, 512/4 + rep movsd + mov eax, [esp+28] + mov ecx, [eax] + sub ecx, 512 + jae @f + add edi, ecx + neg ecx + push eax + xor eax, eax + rep stosb + pop eax +@@: + mov [eax], ecx + mov edx, [eax+4] + mov dx, [edx*2+0x282000] + mov [eax+4], dx ; high word is already zero + popad + xor eax, eax + ret +.eof: + popad + mov eax, 6 + ret +.err: + popad + mov eax, 11 + ret + ; \end{diamond} diff --git a/kernel/trunk/fs/fat32.inc b/kernel/trunk/fs/fat32.inc index d74ef2510a..7e6a908f76 100644 --- a/kernel/trunk/fs/fat32.inc +++ b/kernel/trunk/fs/fat32.inc @@ -7,6 +7,7 @@ ;; Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it ;; ;; ;; ;; See file COPYING for details ;; +;; 23.06.2006 LFN start application - diamond ;; ;; 15.06.2006 LFN get/set file/folder info - diamond ;; ;; 27.05.2006 LFN create/rewrite file - diamond ;; ;; 04.05.2006 LFN read folder - diamond ;; @@ -3396,7 +3397,16 @@ fs_HdRewrite: .common1: call fat_find_lfn jc .notfound -; found, delete FAT chain +; found; must not be directory + test byte [edi+11], 10h + jz @f + add esp, 32 + popad + mov eax, ERROR_ACCESS_DENIED + xor ebx, ebx + ret +@@: +; delete FAT chain push edi xor eax, eax mov dword [edi+28], eax ; zero size @@ -3801,4 +3811,124 @@ fs_HdSetFileInfo: xor eax, eax ret +;---------------------------------------------------------------- +; +; fs_HdExecute - LFN variant for executing from harddisk +; +; esi points to hd filename (e.g. 'dir1/name') +; ebp points to full filename (e.g. '/hd0/1/dir1/name') +; dword [ebx] = flags +; dword [ebx+4] = cmdline +; +; ret ebx,edx destroyed +; eax > 0 - PID, < 0 - error +; +;-------------------------------------------------------------- +fs_HdExecute: + mov edx, [ebx] + mov ebx, [ebx+4] + test ebx, ebx + jz @f + add ebx, std_application_base_address +@@: + +;---------------------------------------------------------------- +; +; fs_HdExecute.flags - second entry +; +; esi points to floppy filename (kernel address) +; ebp points to full filename +; edx flags +; ebx cmdline (kernel address) +; +; ret eax > 0 - PID, < 0 - error +; +;-------------------------------------------------------------- + +.flags: + cmp [fat_type], 0 + jnz @f + mov eax, ERROR_UNKNOWN_FS + ret +@@: + cmp byte [esi], 0 + jnz @f +; cannot execute root! + mov eax, -ERROR_ACCESS_DENIED + ret +@@: + push edi + call hd_find_lfn + jnc .found + pop edi + mov eax, -ERROR_FILE_NOT_FOUND + cmp [hd_error], 0 + jz @f + mov al, -11 +@@: + ret +.found: + mov eax, [edi+20-2] + mov ax, [edi+26] + push 0 + push eax + push dword [edi+28] ; size + push .DoRead + call fs_execute + add esp, 16 + pop edi + ret + +.DoRead: +; read next block +; in: eax->parameters, edi->buffer +; out: eax = error code + pushad + cmp dword [eax], 0 ; file size + jz .eof + add eax, 4 + call fat_get_sector + mov ebx, edi + call hd_read + cmp [hd_error], 0 + jnz .err + mov eax, [esp+28] + mov ecx, [eax] + sub ecx, 512 + jae @f + lea edi, [edi+ecx+512] + neg ecx + push eax + xor eax, eax + rep stosb + pop eax +@@: + mov [eax], ecx + mov edx, [eax+8] + inc edx + cmp edx, [SECTORS_PER_CLUSTER] + jb @f + push eax + mov eax, [eax+4] + call get_FAT + cmp [hd_error], 0 + jnz .err + mov ecx, eax + pop eax + mov [eax+4], ecx + xor edx, edx +@@: + mov [eax+8], edx + popad + xor eax, eax + ret +.eof: + popad + mov eax, 6 + ret +.err: + popad + mov eax, 11 + ret + ; \end{diamond} diff --git a/kernel/trunk/fs/fs_lfn.inc b/kernel/trunk/fs/fs_lfn.inc index 38a5a4fe3a..fab2a2ead3 100644 --- a/kernel/trunk/fs/fs_lfn.inc +++ b/kernel/trunk/fs/fs_lfn.inc @@ -81,7 +81,7 @@ file_system_lfn: ; 4 : set end of file - not implemented yet ; 5 : get file/directory attributes structure ; 6 : set file/directory attributes structure -; 7 : start application - not implemented yet +; 7 : start application ; 8 : delete file - not implemented yet ; 9 : create directory - not implemented yet ; 10: rename file/directory - not implemented yet @@ -90,11 +90,13 @@ file_system_lfn: ; parse file name xchg ebx, eax lea esi, [ebx+20] + mov ebp, esi ; for 'start app' function full path must be known lodsb test al, al jnz @f mov esi, [esi] add esi, std_application_base_address + mov ebp, esi lodsb @@: cmp al, '/' @@ -349,6 +351,7 @@ fs_RamdiskServices: dd fs_NotImplemented dd fs_RamdiskGetFileInfo dd fs_RamdiskSetFileInfo + dd fs_RamdiskExecute fs_NumRamdiskServices = ($ - fs_RamdiskServices)/4 fs_OnFloppy: @@ -377,6 +380,7 @@ fs_FloppyServices: dd fs_NotImplemented dd fs_FloppyGetFileInfo dd fs_FloppySetFileInfo + dd fs_FloppyExecute fs_NumFloppyServices = ($ - fs_FloppyServices)/4 fs_OnHd0: @@ -443,6 +447,7 @@ fs_HdServices: dd fs_NotImplemented dd fs_HdGetFileInfo dd fs_HdSetFileInfo + dd fs_HdExecute fs_NumHdServices = ($ - fs_HdServices)/4 ;*******************************************************