Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Regard whitespace Rev 836 → Rev 837

/kernel/branches/kolibri_pe/fs/fs.inc
0,0 → 1,797
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ;;
;; System service for filesystem call ;;
;; (C) 2004 Ville Turjanmaa, License: GPL ;;
;; 29.04.2006 Elimination of hangup after the ;;
;; expiration hd_wait_timeout (for LBA) - Mario79 ;;
;; 15.01.2005 get file size/attr/date, ;;
;; file_append (only for hd) - ATV ;;
;; 23.11.2004 test if hd/partition is set - ATV ;;
;; 18.11.2004 get_disk_info and more error codes - ATV ;;
;; 08.11.2004 expand_pathz and rename (only for hd) - ATV ;;
;; 20.10.2004 Makedir/Removedir (only for hd) - ATV ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
iglobal
dir0: db 'HARDDISK '
db 'RAMDISK '
db 'FLOPPYDISK '
db 0
 
dir1: db 'FIRST '
db 'SECOND '
db 'THIRD '
db 'FOURTH '
db 0
 
not_select_IDE db 0
 
hd_address_table: dd 0x1f0,0x00,0x1f0,0x10
dd 0x170,0x00,0x170,0x10
endg
 
file_system:
 
; IN:
;
; eax = 0 ; read file /RamDisk/First 6
; eax = 8 ; lba read
; eax = 15 ; get_disk_info
;
; OUT:
;
; eax = 0 : read ok
; eax = 1 : no hd base and/or partition defined
; eax = 2 : function is unsupported for this FS
; eax = 3 : unknown FS
; eax = 4 : partition not defined at hd
; eax = 5 : file not found
; eax = 6 : end of file
; eax = 7 : memory pointer not in application area
; eax = 8 : disk full
; eax = 9 : fat table corrupted
; eax = 10 : access denied
; eax = 11 : disk error
;
; ebx = size
 
; \begin{diamond}[18.03.2006]
; for subfunction 16 (start application) error codes must be negative
; because positive values are valid PIDs
; so possible return values are:
; eax > 0 : process created, eax=PID
 
; -0x10 <= eax < 0 : -eax is filesystem error code:
; eax = -1 = 0xFFFFFFFF : no hd base and/or partition defined
; eax = -3 = 0xFFFFFFFD : unknown FS
; eax = -5 = 0xFFFFFFFB : file not found
; eax = -6 = 0xFFFFFFFA : unexpected end of file (probably not executable file)
; eax = -9 = 0xFFFFFFF7 : fat table corrupted
; eax = -10 = 0xFFFFFFF6 : access denied
 
; -0x20 <= eax < -0x10: eax is process creation error code:
; eax = -0x20 = 0xFFFFFFE0 : too many processes
; eax = -0x1F = 0xFFFFFFE1 : not Menuet/Kolibri executable
; eax = -0x1E = 0xFFFFFFE2 : no memory
 
; ebx is not changed
 
; \end{diamond}[18.03.2006]
 
; Extract parameters
; add eax, std_application_base_address ; abs start of info block
 
cmp dword [eax+0],15 ; GET_DISK_INFO
je fs_info
 
cmp dword [CURRENT_TASK],1 ; no memory checks for kernel requests
jz no_checks_for_kernel
mov edx,eax
cmp dword [eax+0],1
jnz .usual_check
mov ebx,[eax+12]
; add ebx,std_application_base_address
mov ecx,[eax+8]
call check_region
test eax,eax
jnz area_in_app_mem
 
.error_output:
mov esi,buffer_failed
call sys_msg_board_str
; mov eax,7
mov dword [esp+36],7
ret
iglobal
buffer_failed db 'K : Buffer check failed',13,10,0
endg
.usual_check:
cmp dword [eax+0],0
mov ecx,512
jnz .small_size
mov ecx,[eax+8]
shl ecx,9
.small_size:
mov ebx,[eax+12]
; add ebx,std_application_base_address
call check_region
test eax,eax
jz .error_output
area_in_app_mem:
mov eax,edx
no_checks_for_kernel:
 
fs_read:
 
mov ebx,[eax+20] ; program wants root directory ?
test bl,bl
je fs_getroot
test bh,bh
jne fs_noroot
fs_getroot:
; \begin{diamond}[18.03.2006]
; root - only read is allowed
; other operations return "access denied", eax=10
; (execute operation returns eax=-10)
cmp dword [eax], 0
jz .read_root
mov dword [esp+36], 10
ret
.read_root:
; \end{diamond}[18.03.2006]
mov esi,dir0
mov edi,[eax+12]
; add edi,std_application_base_address
mov ecx,11
push ecx
; cld ; already is
rep movsb
mov al,0x10
stosb
add edi,32-11-1
pop ecx
rep movsb
stosb
and dword [esp+36],0 ; ok read
mov dword [esp+24],32*2 ; size of root
ret
 
fs_info: ;start of code - Mihasik
push eax
cmp [eax+21],byte 'h'
je fs_info_h
cmp [eax+21],byte 'H'
je fs_info_h
cmp [eax+21],byte 'r'
je fs_info_r
cmp [eax+21],byte 'R'
je fs_info_r
mov eax,3 ;if unknown disk
xor ebx,ebx
xor ecx,ecx
xor edx,edx
jmp fs_info1
fs_info_r:
call ramdisk_free_space ;if ramdisk
mov ecx,edi ;free space in ecx
shr ecx,9 ;free clusters
mov ebx,2847 ;total clusters
mov edx,512 ;cluster size
xor eax,eax ;always 0
jmp fs_info1
fs_info_h: ;if harddisk
call get_hd_info
fs_info1:
pop edi
mov [esp+36],eax
mov [esp+24],ebx ; total clusters on disk
mov [esp+32],ecx ; free clusters on disk
mov [edi],edx ; cluster size in bytes
ret ;end of code - Mihasik
 
fs_noroot:
 
push dword [eax+0] ; read/write/delete/.../makedir/rename/lba/run
push dword [eax+4] ; 512 block number to read
push dword [eax+8] ; bytes to write/append or 512 blocks to read
mov ebx,[eax+12]
; add ebx,std_application_base_address
push ebx ; abs start of return/save area
 
lea esi,[eax+20] ; abs start of dir + filename
mov edi,[eax+16]
; add edi,std_application_base_address ; abs start of work area
 
call expand_pathz
 
push edi ; dir start
push ebx ; name of file start
 
mov eax,[edi+1]
cmp eax,'RD '
je fs_yesramdisk
cmp eax,'RAMD'
jne fs_noramdisk
 
fs_yesramdisk:
 
cmp byte [edi+1+11],0
je fs_give_dir1
 
mov eax,[edi+1+12]
cmp eax,'1 '
je fs_yesramdisk_first
cmp eax,'FIRS'
jne fs_noramdisk
 
fs_yesramdisk_first:
 
cmp dword [esp+20],8 ; LBA read ramdisk
jne fs_no_LBA_read_ramdisk
 
mov eax,[esp+16] ; LBA block to read
mov ecx,[esp+8] ; abs pointer to return area
 
call LBA_read_ramdisk
jmp file_system_return
 
 
fs_no_LBA_read_ramdisk:
 
cmp dword [esp+20],0 ; READ
jne fs_noramdisk_read
 
mov eax,[esp+4] ; fname
add eax,2*12+1
mov ebx,[esp+16] ; block start
inc ebx
mov ecx,[esp+12] ; block count
mov edx,[esp+8] ; return
mov esi,[esp+0]
sub esi,eax
add esi,12+1 ; file name length
call fileread
 
jmp file_system_return
 
 
fs_noramdisk_read:
fs_noramdisk:
 
;********************************************************************
mov eax,[edi+1]
cmp eax,'FD '
je fs_yesflpdisk
cmp eax,'FLOP'
jne fs_noflpdisk
 
fs_yesflpdisk:
call reserve_flp
 
cmp byte [edi+1+11],0
je fs_give_dir1
 
mov eax,[edi+1+12]
cmp eax,'1 '
je fs_yesflpdisk_first
cmp eax,'FIRS'
je fs_yesflpdisk_first
cmp eax,'2 '
je fs_yesflpdisk_second
cmp eax,'SECO'
jne fs_noflpdisk
jmp fs_yesflpdisk_second
 
fs_yesflpdisk_first:
mov [flp_number],1
jmp fs_yesflpdisk_start
fs_yesflpdisk_second:
mov [flp_number],2
fs_yesflpdisk_start:
cmp dword [esp+20],0 ; READ
jne fs_noflpdisk_read
 
mov eax,[esp+4] ; fname
add eax,2*12+1
mov ebx,[esp+16] ; block start
inc ebx
mov ecx,[esp+12] ; block count
mov edx,[esp+8] ; return
mov esi,[esp+0]
sub esi,eax
add esi,12+1 ; file name length
call floppy_fileread
 
jmp file_system_return
 
 
fs_noflpdisk_read:
fs_noflpdisk:
;*****************************************************************
 
mov eax,[edi+1]
cmp eax,'HD0 '
je fs_yesharddisk_IDE0
cmp eax,'HD1 '
je fs_yesharddisk_IDE1
cmp eax,'HD2 '
je fs_yesharddisk_IDE2
cmp eax,'HD3 '
je fs_yesharddisk_IDE3
jmp old_path_harddisk
fs_yesharddisk_IDE0:
call reserve_hd1
mov [hdbase],0x1f0
mov [hdid],0x0
mov [hdpos],1
jmp fs_yesharddisk_partition
fs_yesharddisk_IDE1:
call reserve_hd1
mov [hdbase],0x1f0
mov [hdid],0x10
mov [hdpos],2
jmp fs_yesharddisk_partition
fs_yesharddisk_IDE2:
call reserve_hd1
mov [hdbase],0x170
mov [hdid],0x0
mov [hdpos],3
jmp fs_yesharddisk_partition
fs_yesharddisk_IDE3:
call reserve_hd1
mov [hdbase],0x170
mov [hdid],0x10
mov [hdpos],4
fs_yesharddisk_partition:
call reserve_hd_channel
; call choice_necessity_partition
; jmp fs_yesharddisk_all
jmp fs_for_new_semantic
 
choice_necessity_partition:
mov eax,[edi+1+12]
call StringToNumber
mov [fat32part],eax
choice_necessity_partition_1:
mov ecx,[hdpos]
xor eax,eax
mov [hd_entries], eax ; entries in hd cache
mov edx,DRIVE_DATA+2
cmp ecx,0x80
jb search_partition_array
mov ecx,4
search_partition_array:
mov bl,[edx]
movzx ebx,bl
add eax,ebx
inc edx
loop search_partition_array
mov ecx,[hdpos]
mov edx,BiosDiskPartitions
sub ecx,0x80
jb .s
je .f
@@:
mov ebx,[edx]
add edx,4
add eax,ebx
loop @b
jmp .f
.s:
sub eax,ebx
.f:
add eax,[fat32part]
dec eax
xor edx,edx
imul eax,100
add eax,DRIVE_DATA+0xa
mov [transfer_adress],eax
call partition_data_transfer_1
ret
 
old_path_harddisk:
mov eax,[edi+1]
cmp eax,'HD '
je fs_yesharddisk
cmp eax,'HARD'
jne fs_noharddisk
 
fs_yesharddisk:
cmp dword [esp+20],8 ; LBA read
jne fs_no_LBA_read
mov eax,[esp+16] ; LBA block to read
lea ebx,[edi+1+12] ; pointer to FIRST/SECOND/THIRD/FOURTH
mov ecx,[esp+8] ; abs pointer to return area
call LBA_read
jmp file_system_return
 
fs_no_LBA_read:
 
cmp byte [edi+1+11],0 ; directory read
je fs_give_dir1
call reserve_hd1
fs_for_new_semantic:
call choice_necessity_partition
 
fs_yesharddisk_all:
mov eax,1
mov ebx, [esp+24+24]
cmp [hdpos],0 ; is hd base set?
jz hd_err_return
cmp [fat32part],0 ; is partition set?
jnz @f
hd_err_return:
call free_hd_channel
and [hd1_status], 0
jmp file_system_return
@@:
 
cmp dword [esp+20],0 ; READ
jne fs_noharddisk_read
 
mov eax,[esp+0] ; /fname
lea edi,[eax+12]
mov byte [eax],0 ; path to asciiz
inc eax ; filename start
 
mov ebx,[esp+12] ; count to read
mov ecx,[esp+8] ; buffer
mov edx,[esp+4]
add edx,12*2 ; dir start
sub edi,edx ; path length
mov esi,[esp+16] ; blocks to read
 
call file_read
 
mov edi,[esp+0]
mov byte [edi],'/'
 
call free_hd_channel
and [hd1_status], 0
jmp file_system_return
 
fs_noharddisk_read:
 
call free_hd_channel
and [hd1_status], 0
 
fs_noharddisk:
; \begin{diamond}[18.03.2006]
mov eax, 5 ; file not found
; à ìîæåò áûòü, âîçâðàùàòü äðóãîé êîä îøèáêè?
mov ebx, [esp+24+24] ; do not change ebx in application
; \end{diamond}[18.03.2006]
 
file_system_return:
 
add esp,24
 
mov [esp+36],eax
mov [esp+24],ebx
ret
 
 
fs_give_dir1:
 
; \begin{diamond}[18.03.2006]
; /RD,/FD,/HD - only read is allowed
; other operations return "access denied", eax=10
; (execute operation returns eax=-10)
cmp dword [esp+20], 0
jz .read
add esp, 20
pop ecx
mov dword [esp+36], 10
ret
.read:
; \end{diamond}[18.03.2006]
mov al,0x10
mov ebx,1
mov edi,[esp+8]
mov esi,dir1
fs_d1_new:
mov ecx,11
; cld
rep movsb
stosb
add edi,32-11-1
dec ebx
jne fs_d1_new
 
add esp,24
 
and dword [esp+36],0 ; ok read
mov dword [esp+24],32*1 ; dir/data size
ret
 
 
 
LBA_read_ramdisk:
 
cmp [lba_read_enabled],1
je lbarrl1
 
xor ebx,ebx
mov eax,2
ret
 
lbarrl1:
 
cmp eax,18*2*80
jb lbarrl2
xor ebx,ebx
mov eax,3
ret
 
lbarrl2:
 
pushad
 
call restorefatchain
 
mov edi,ecx
mov esi,eax
 
shl esi,9
add esi,RAMDISK
mov ecx,512/4
; cld
rep movsd
 
popad
 
xor ebx,ebx
xor eax,eax
ret
 
LBA_read:
 
; IN:
;
; eax = LBA block to read
; ebx = pointer to FIRST/SECOND/THIRD/FOURTH
; ecx = abs pointer to return area
 
cmp [lba_read_enabled],1
je lbarl1
mov eax,2
ret
 
lbarl1:
 
call reserve_hd1
 
push eax
push ecx
 
mov edi,hd_address_table
mov esi,dir1
mov eax,[ebx]
mov edx,'1 '
mov ecx,4
blar0:
cmp eax,[esi]
je blar2
cmp eax,edx
je blar2
inc edx
add edi,8
add esi,11
dec ecx
jnz blar0
 
mov eax,1
mov ebx,1
jmp LBA_read_ret
 
blar2:
mov eax,[edi+0]
mov ebx,[edi+4]
 
mov [hdbase],eax
mov [hdid],ebx
 
call wait_for_hd_idle
cmp [hd_error],0
jne hd_lba_error
 
; eax = hd port
; ebx = set for primary (0x00) or slave (0x10)
 
cli
 
mov edx,eax
inc edx
xor eax,eax
out dx,al
inc edx
inc eax
out dx,al
inc edx
mov eax,[esp+4]
out dx,al
shr eax,8
inc edx
out dx,al
shr eax,8
inc edx
out dx,al
shr eax,8
inc edx
and al,1+2+4+8
add al,bl
add al,128+64+32
out dx,al
 
inc edx
mov al,20h
out dx,al
 
sti
 
call wait_for_sector_buffer
cmp [hd_error],0
jne hd_lba_error
 
cli
 
mov edi,[esp+0]
mov ecx,256
sub edx,7
cld
rep insw
 
sti
 
xor eax,eax
xor ebx,ebx
 
LBA_read_ret:
mov [hd_error],0
mov [hd1_status],0
add esp,2*4
 
ret
 
 
expand_pathz:
; IN:
; esi = asciiz path & file
; edi = buffer for path & file name
; OUT:
; edi = directory & file : / 11 + / 11 + / 11 - zero terminated
; ebx = /file name - zero terminated
; esi = pointer after source
 
push eax
push ecx
push edi ;[esp+0]
 
pathz_start:
mov byte [edi],'/'
inc edi
mov al,32
mov ecx,11
cld
rep stosb ; clear filename area
sub edi,11
mov ebx,edi ; start of dir/file name
 
pathz_new_char:
mov al,[esi]
inc esi
cmp al,0
je pathz_end
 
cmp al,'/'
jne pathz_not_path
cmp edi,ebx ; skip first '/'
jz pathz_new_char
lea edi,[ebx+11] ; start of next directory
jmp pathz_start
 
pathz_not_path:
cmp al,'.'
jne pathz_not_ext
lea edi,[ebx+8] ; start of extension
jmp pathz_new_char
 
pathz_not_ext:
cmp al,'a'
jb pathz_not_low
cmp al,'z'
ja pathz_not_low
sub al,0x20 ; char to uppercase
 
pathz_not_low:
mov [edi],al
inc edi
mov eax,[esp+0] ; start_of_dest_path
add eax,512 ; keep maximum path under 512 bytes
cmp edi,eax
jb pathz_new_char
 
pathz_end:
cmp ebx,edi ; if path end with '/'
jnz pathz_put_zero ; go back 1 level
sub ebx,12
 
pathz_put_zero:
mov byte [ebx+11],0
dec ebx ; include '/' char into file name
pop edi
pop ecx
pop eax
ret
 
;*******************************************
;* string to number
;* input eax - 4 byte string
;* output eax - number
;*******************************************
StringToNumber:
; ÏÅÐÅÂÎÄ ÑÒÐÎÊÎÂÎÃÎ ×ÈÑËÀ  ×ÈÑËÎÂÎÉ ÂÈÄ
; Âõîä:
; EDI - àäðåñ ñòðîêè ñ ÷èñëîì. Êîíåö ÷èñëà îòìå÷åí êîäîì 0Dh
; Âûõîä:
; CF - èíäèêàòîð îøèáîê:
; 0 - îøèáîê íåò;
; 1 - îøèáêà
; Åñëè CF=0, òî AX - ÷èñëî.
 
push bx
push cx
push dx
push edi
mov [partition_string],eax
mov edi,partition_string
xor cx,cx
i1:
mov al,[edi]
cmp al,32 ;13
je i_exit
; cmp al,'0'
; jb err
; cmp al,'9'
; ja err
sub al,48
shl cx,1
jc err
mov bx,cx
shl cx,1
jc err
shl cx,1
jc err
add cx,bx
jc err
cbw
add cx,ax
jc err
i3:
inc edi
jmp i1
i_exit:
mov ax,cx
clc
i4:
movzx eax,ax
pop edi
pop dx
pop cx
pop bx
ret
 
err:
stc
jmp i4
 
partition_string: dd 0
db 32
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property