Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 132 → Rev 133

/kernel/trunk/fs/fat32.inc
90,6 → 90,7
Sector512: ; label for dev_hdcd.inc
buffer: times 512 db 0
deltree_buffer: times 512 db 0
fsinfo_buffer: times 512 db 0
endg
 
iglobal
1037,7 → 1038,7
 
push eax ebx
mov eax,[ADR_FSINFO]
mov ebx,buffer
mov ebx,fsinfo_buffer
call hd_read
cmp [hd_error],0
jne add_not_fs
1047,8 → 1048,8
 
add [ebx+0x1e8],ecx
call hd_write
cmp [hd_error],0
jne add_not_fs
; cmp [hd_error],0
; jne add_not_fs
 
add_not_fs:
pop ebx eax
1057,368 → 1058,6
ret
 
 
file_append:
;-----------------------------------------------------
; input : eax = file name
; edx = path
; ecx = pointer to buffer
; ebx = bytes to write (0 = truncate file)
; esi = start position (-1 = end of file)
; output : eax = 0 - ok
; 3 - unknown FS
; 5 - file not found
; 6 - end of file
; 8 - disk full
; 9 - fat table corrupted
; 10 - access denied
; ebx = bytes written
;-----------------------------------------------------
cmp [fat_type],0
jnz append_fat_ok
mov eax,ERROR_UNKNOWN_FS
ret
 
append_fat_ok:
; call reserve_hd1
 
pushad
 
mov ebx,edx
call get_cluster_of_a_path
jc append_not_found
 
mov ebx,PUSHAD_EAX ; file name
call analyze_directory
jc append_not_found
 
mov [sector_tmp],eax
mov [entry_pos],ebx
 
test byte [ebx+11],0x10 ; is it directory?
jnz append_access ; yes
 
mov ecx,[ebx+28] ; file size
mov edi,PUSHAD_ESI ; write position
cmp edi,-1 ; -1 = eof
jnz append_inside_file
mov edi,ecx ; file size
 
append_inside_file:
cmp edi,ecx ; start above old file size?
ja append_eof ; yes
 
mov [old_filesize],ecx
mov [new_filepos],edi
 
mov ecx,PUSHAD_EBX ; bytes to write
test ecx,ecx ; truncate?
jz append_truncate ; yes
 
mov [bytes2write],ecx ; bytes to write
mov esi,PUSHAD_ECX ; pointer to buffer
mov eax,[ebx+20-2] ; FAT entry
mov ax,[ebx+26]
and eax,[fatMASK]
jnz append_find_pos ; first cluster <> 0
 
mov eax,2
call get_free_FAT
jc append_disk_full
mov ecx,eax ; set files first cluster
mov [ebx+26],cx ; 16 bits low of cluster
shr ecx,16
mov [ebx+20],cx ; 16 bits high of cluster (=0 fat16)
mov edx,[fatEND] ; new end for cluster chain
call set_FAT
cmp [hd_error],0
jne append_access
 
push eax ; save first cluster
mov eax,[sector_tmp]
mov ebx,buffer
call hd_write ; write new file entry back to disk
cmp [hd_error],0
jne append_access_1
 
pop eax
 
append_remove_free:
mov ecx,-1 ; remove 1 cluster from free disk space
call add_disk_free_space ; Note: uses buffer
cmp [hd_error],0
jne append_access
 
append_found_cluster:
mov [cluster],eax
sub eax,2
mov ecx,[SECTORS_PER_CLUSTER]
imul eax,ecx
add eax,[DATA_START]
xor edi,edi
 
append_new_sector:
cmp [hd_error],0
jne append_access
push ecx
mov ecx,[bytes2write] ; bytes left in buffer
mov ebx,512
sub ebx,edi ; bytes left in sector
cmp ecx,ebx
jb append_bytes_ok
mov ecx,ebx
 
append_bytes_ok:
cmp ecx,512 ; overwrite full sector?
jz append_full_sector ; yes
mov ebx,buffer ; overwrite part of sector
call hd_read ; read old sector
cmp [hd_error],0
jne append_access_1
 
append_full_sector:
sub [bytes2write],ecx
add [new_filepos],ecx
add edi,buffer
cld
rep movsb
pop ecx
 
mov ebx,buffer
call hd_write
cmp [hd_error],0
jne append_access
 
cmp [bytes2write],0 ; is all done?
jz append_done
xor edi,edi
inc eax
dec ecx
jnz append_new_sector
 
mov eax,[cluster]
call get_FAT
cmp [hd_error],0
jne append_access
 
cmp eax,2
jb append_fat
cmp eax,[LAST_CLUSTER]
jbe append_found_cluster
 
append_alloc_cluster:
mov eax,2 ; ToDo: use temp array to keep track
call get_free_FAT ; of last free cluster
jc append_disk_full
push eax ; save new cluster
mov edx,[fatEND] ; new end for cluster chain
call set_FAT
cmp [hd_error],0
jne append_access_1
mov edx,eax
mov eax,[cluster]
call set_FAT ; update previous cluster
cmp [hd_error],0
jne append_access_1
 
pop eax
jmp append_remove_free
 
append_find_pos:
call find_filepos
mov [cluster],ebx
jnc append_new_sector
test edi,edi
jz append_alloc_cluster
 
append_fat:
mov eax,ERROR_FAT_TABLE
jmp append_ret_code
append_disk_full:
cmp [hd_error],0
jne append_access
mov eax,ERROR_DISK_FULL
jmp append_ret_code
 
append_done:
xor eax,eax
 
append_ret_code:
mov PUSHAD_EAX,eax ; return code
 
mov eax,[sector_tmp] ; update directory entry
mov ebx,buffer
call hd_read
cmp [hd_error],0
jne append_access
mov ebx,[entry_pos]
mov ecx,[new_filepos]
cmp ecx,[old_filesize] ; is file pos above old size?
jbe append_size_ok ; no
mov [ebx+28],ecx ; new file size
 
append_size_ok:
call set_current_time_for_entry
mov ebx,buffer
call hd_write ; write new file entry back to disk
cmp [hd_error],0
jne append_access
 
sub ecx,PUSHAD_ESI ; start position
mov PUSHAD_EBX,ecx ; bytes written
popad
call update_disk ; write all of cache and fat to hd
cmp [hd_error],0
jne append_access_2
 
mov [hd1_status],0
ret
 
append_eof:
popad
mov [hd1_status],0
xor ebx,ebx
mov eax,ERROR_END_OF_FILE
ret
 
append_not_found:
cmp [hd_error],0
jne append_access
popad
mov [hd1_status],0
xor ebx,ebx
mov eax,ERROR_FILE_NOT_FOUND
ret
append_access_1:
add esp,4
append_access:
popad
append_access_2:
mov [hd1_status],0
xor ebx,ebx
mov eax,ERROR_ACCESS_DENIED
ret
 
append_truncate:
mov edx,[ebx+20-2] ; FAT entry
mov dx,[ebx+26]
and edx,[fatMASK]
mov [ebx+28],edi ; set new file size
test edi,edi ; 0 length file?
jnz truncate_save_size ; no
mov [ebx+20],di ; FAT entry = 0
mov [ebx+26],di
 
truncate_save_size:
call set_current_time_for_entry
mov ebx,buffer
call hd_write
cmp [hd_error],0
jne append_access
 
mov eax,edx ; first cluster
test edi,edi ; 0 length file?
jz truncate_clear_chain
 
imul esi,[SECTORS_PER_CLUSTER],512 ; esi = cluster size in bytes
 
truncate_new_cluster:
cmp eax,2 ; incorrect fat chain?
jb truncate_eof ; yes
cmp eax,[fatRESERVED] ; is it end of file?
jnb truncate_eof ; yes
sub edi,esi
jbe truncate_pos_found
call get_FAT ; get next cluster
cmp [hd_error],0
jne append_access
 
jmp truncate_new_cluster
 
truncate_pos_found:
mov edx,[fatEND] ; new end for cluster chain
call set_FAT
cmp [hd_error],0
jne append_access
 
mov eax,edx ; clear rest of chain
 
truncate_clear_chain:
call clear_cluster_chain
cmp [hd_error],0
jne append_access
 
truncate_eof:
popad
call update_disk ; write all of cache and fat to hd
cmp [hd_error],0
jne append_access_2
 
mov [hd1_status],0
xor ebx,ebx
xor eax,eax
ret
 
 
find_filepos:
;-----------------------------------------------------
; input : eax = first cluster
; edi = bytes to skip over (start position)
; output : if CARRY=0 file position found
; if CARRY=1 end of file found
; eax = current file sector
; ebx = last cluster
; ecx = sector count in last cluster
; edi = bytes to skip over (sector position)
;-----------------------------------------------------
push esi
mov ecx,[SECTORS_PER_CLUSTER]
imul esi,ecx,512 ; esi = cluster size in bytes
mov ebx,eax
 
filepos_new_cluster:
cmp eax,2 ; incorrect fat chain?
jb filepos_eof ; yes
cmp eax,[fatRESERVED] ; is it end of file?
jnb filepos_eof ; yes
 
mov ebx,eax
cmp edi,esi ; skip over full cluster?
jb filepos_cluster_ok ; no
 
sub edi,esi
call get_FAT ; get next cluster
cmp [hd_error],0
jne filepos_eof
 
jmp filepos_new_cluster
 
filepos_cluster_ok:
sub eax,2
imul eax,ecx
add eax,[DATA_START]
 
filepos_new_sector:
cmp edi,512 ; skip over full sector?
jb filepos_sector_ok ; no
sub edi,512
inc eax
dec ecx
jnz filepos_new_sector
 
filepos_eof:
pop esi
stc
ret
 
filepos_sector_ok:
pop esi
clc
ret
 
 
file_write:
;--------------------------------------------------------------------------
; INPUT : user-reg register-in-this meaning symbol-in-this-routine
3994,7 → 3633,7
 
; extends file on hd to given size (new data area is undefined)
; in: edi->direntry, ecx=new size
; out: CF=0 => OK, eax destroyed
; out: CF=0 => OK, eax=0
; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL or 11)
hd_extend_file:
push ebp
4072,6 → 3711,10
ror edx, 16
mov [edi+26], dx
@@:
push ecx
mov ecx, -1
call add_disk_free_space
pop ecx
mov eax, edx
cmp [hd_error], 0
jnz .device_err3
4080,7 → 3723,7
.extend_done:
mov [edi+28], ecx
pop edx ebp
clc
xor eax, eax ; CF=0
ret
.device_err3:
pop edx
4095,6 → 3738,246
@@: stc
ret
 
;----------------------------------------------------------------
;
; fs_HdSetFileEnd - set end of file on hard disk
;
; esi points to filename
; ebx points to 64-bit number = new file size
; ecx ignored (reserved)
; edx ignored (reserved)
;
; ret eax = 0 ok or other = errormsg
;
;--------------------------------------------------------------
fs_HdSetFileEnd:
cmp [fat_type], 0
jnz @f
push ERROR_UNKNOWN_FS
.ret:
pop eax
ret
@@:
cmp byte [esi], 0
jnz @f
.access_denied:
push ERROR_ACCESS_DENIED
jmp .ret
@@:
push edi
call hd_find_lfn
pushfd
cmp [hd_error], 0
jz @f
popfd
push 11
jmp .ret
@@:
popfd
jnc @f
pop edi
push ERROR_FILE_NOT_FOUND
jmp .ret
@@:
; must not be directory
test byte [edi+11], 10h
jz @f
pop edi
jmp .access_denied
@@:
; file size must not exceed 4 Gb
cmp dword [ebx+4], 0
jz @f
pop edi
push ERROR_END_OF_FILE
jmp .ret
@@:
push eax ; save directory sector
; set file modification date/time to current
call fat_update_datetime
mov eax, [ebx]
cmp eax, [edi+28]
jb .truncate
ja .expand
pop eax
mov ebx, buffer
call hd_write
pop edi
xor eax, eax
cmp [hd_error], 0
jz @f
mov al, 11
@@:
ret
.expand:
push ebx ebp ecx
push dword [edi+28] ; save old size
mov ecx, eax
call hd_extend_file
push eax ; return code
jnc .expand_ok
cmp al, ERROR_DISK_FULL
jz .disk_full
.pop_ret:
call update_disk
pop eax ecx ebp ebx ecx edi edi
ret
.expand_ok:
.disk_full:
; save directory
mov eax, [edi+28]
xchg eax, [esp+20]
mov ebx, buffer
call hd_write
mov eax, [edi+20-2]
mov ax, [edi+26]
mov edi, eax
cmp [hd_error], 0
jz @f
.pop_ret11:
mov byte [esp], 11
jmp .pop_ret
@@:
; now zero new data
xor ebp, ebp
; edi=current cluster, ebp=sector in cluster
; [esp+20]=new size, [esp+4]=old size, [esp]=return code
.zero_loop:
sub dword [esp+4], 0x200
jae .next_cluster
lea eax, [edi-2]
imul eax, [SECTORS_PER_CLUSTER]
add eax, [DATA_START]
add eax, ebp
cmp dword [esp+4], -0x200
jz .noread
mov ebx, buffer
call hd_read
cmp [hd_error], 0
jnz .err_next
.noread:
mov ecx, [esp+4]
neg ecx
push edi
mov edi, buffer+0x200
add edi, [esp+8]
push eax
xor eax, eax
mov [esp+12], eax
rep stosb
pop eax
pop edi
call hd_write
cmp [hd_error], 0
jz .next_cluster
.err_next:
mov byte [esp], 11
.next_cluster:
sub dword [esp+20], 0x200
jbe .pop_ret
inc ebp
cmp ebp, [SECTORS_PER_CLUSTER]
jb .zero_loop
xor ebp, ebp
mov eax, edi
call get_FAT
mov edi, eax
cmp [hd_error], 0
jnz .pop_ret11
jmp .zero_loop
.truncate:
mov [edi+28], eax
push ecx
mov ecx, [edi+20-2]
mov cx, [edi+26]
push eax
test eax, eax
jz .zero_size
; find new last cluster
@@:
mov eax, [SECTORS_PER_CLUSTER]
shl eax, 9
sub [esp], eax
jbe @f
mov eax, ecx
call get_FAT
mov ecx, eax
cmp [hd_error], 0
jz @b
.device_err3:
pop eax ecx eax edi
push 11
pop eax
ret
@@:
; we will zero data at the end of last sector - remember it
push ecx
; terminate FAT chain
push edx
mov eax, ecx
mov edx, [fatEND]
call set_FAT
mov eax, edx
pop edx
cmp [hd_error], 0
jz @f
.device_err4:
pop ecx
jmp .device_err3
.zero_size:
and word [edi+20], 0
and word [edi+26], 0
push 0
mov eax, ecx
@@:
; delete FAT chain
call clear_cluster_chain
cmp [hd_error], 0
jnz .device_err4
; save directory
mov eax, [esp+12]
push ebx
mov ebx, buffer
call hd_write
pop ebx
cmp [hd_error], 0
jnz .device_err4
; zero last sector, ignore errors
pop ecx
pop eax
dec ecx
imul ecx, [SECTORS_PER_CLUSTER]
add ecx, [DATA_START]
push eax
sar eax, 9
add ecx, eax
pop eax
and eax, 0x1FF
jz .truncate_done
push ebx eax
mov eax, ecx
mov ebx, buffer
call hd_read
pop eax
lea edi, [buffer+eax]
push ecx
mov ecx, 0x200
sub ecx, eax
xor eax, eax
rep stosb
pop eax
call hd_write
pop ebx
.truncate_done:
pop ecx eax edi
call update_disk
xor eax, eax
cmp [hd_error], 0
jz @f
mov al, 11
@@:
ret
 
fs_HdGetFileInfo:
cmp [fat_type], 0
jnz @f