Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 383 → Rev 384

/kernel/branches/gfx_kernel/fs/fs_phys.inc
File deleted
\ No newline at end of file
/kernel/branches/gfx_kernel/fs/fat12.inc
31,9 → 31,9
reserve_flp_ok:
 
push eax
mov eax,[0x3000]
mov eax,[CURRENT_TASK]
shl eax,5
mov eax,[eax+0x3000+TASKDATA.pid]
mov eax,[eax+CURRENT_TASK+TASKDATA.pid]
mov [flp_status],eax
pop eax
sti
104,7 → 104,7
mov edi,edx
dec ebx
shl ebx,9
mov esi,0x8000
mov esi,FLOPPY_BUFF
add esi,ebx
shl ecx,9
cld
147,7 → 147,7
cmp [FDC_Status],0
jne fdc_status_error_3_1
mov dl,16
mov edi,0xD000
mov edi,FDD_BUFF
inc [FDD_Sector]
l.21_1:
mov esi,eax ;Name of file we want
219,7 → 219,7
frfl8_1:
mov edi,[n_sector]
shl edi,1 ;find next cluster from FAT
add edi,0x282000
add edi,FLOPPY_FAT
mov eax,[edi]
and eax,4095
mov edi,eax
274,7 → 274,7
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],1 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
mov edi,0x8000
mov edi,FLOPPY_BUFF
call SeekTrack
read_flp_root_1:
call ReadSectWithRetr
303,7 → 303,7
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],0 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
mov edi,0x8000
mov edi,FLOPPY_BUFF
call SeekTrack
read_flp_fat_1:
call ReadSectWithRetr
332,8 → 332,8
calculatefatchain_flp:
pushad
 
mov esi,0x8000
mov edi,0x282000
mov esi,FLOPPY_BUFF
mov edi,FLOPPY_FAT
 
fcnew_1:
mov eax,dword [esi]
361,7 → 361,7
add edi,4
add esi,12
 
cmp edi,0x282000+2856*2 ;2849 clusters
cmp edi,FLOPPY_FAT+2856*2 ;2849 clusters
jnz fcnew_1
 
popad
384,7 → 384,7
cmp [FDC_Status],0
jne fdc_status_error
mov esi,flp_label
mov edi,0xD000+39
mov edi,FDD_BUFF+39
mov ecx,15
cld
rep cmpsb
392,7 → 392,7
mov [root_read],0
mov [flp_fat],0
same_label:
mov esi,0xD000+39
mov esi,FDD_BUFF+39
mov edi,flp_label
mov ecx,15
cld
413,7 → 413,7
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],1 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
mov esi,0x8000
mov esi,FLOPPY_BUFF
call SeekTrack
save_flp_root_1:
push esi
442,7 → 442,7
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],0 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
mov esi,0x8000
mov esi,FLOPPY_BUFF
call SeekTrack
save_flp_fat_1:
push esi
471,8 → 471,8
restorefatchain_flp: ; restore fat chain
pushad
 
mov esi,0x282000
mov edi,0x8000
mov esi,FLOPPY_FAT
mov edi,FLOPPY_BUFF
 
fcnew2_1:
mov eax,dword [esi]
489,11 → 489,11
add edi,2
add esi,8
 
cmp edi,0x8000+0x1200 ;4274 bytes - all used FAT
cmp edi,FLOPPY_BUFF+0x1200 ;4274 bytes - all used FAT
jb fcnew2_1
 
mov esi,0x8000 ; duplicate fat chain
mov edi,0x8000+0x1200
mov esi,FLOPPY_BUFF ; duplicate fat chain
mov edi,FLOPPY_BUFF+0x1200
mov ecx,0x1200/4
cld
rep movsd
534,7 → 534,7
cmp [FDC_Status],0
jne fdc_status_error_4
mov dl,16
mov edi,0xD000
mov edi,FDD_BUFF
inc [FDD_Sector]
l.21_2:
mov esi,eax ;Name of file we want
574,7 → 574,7
movzx edi, word [edi+0xf] ;edi = cluster
frnewd_1:
shl edi,1 ;find next cluster from FAT
add edi,0x282000
add edi,FLOPPY_FAT
mov eax,[edi]
mov [edi],word 0x0 ;clear fat chain cluster
and eax,4095
662,7 → 662,7
call read_flp_root
cmp [FDC_Status],0
jne fdc_status_error_7
mov edi,0x8000 ;Point at directory
mov edi,FLOPPY_BUFF ;Point at directory
mov edx,224 +1
; find an empty spot for filename in the root dir
l20ds_1:
689,7 → 689,7
cmp [FDC_Status],0
jne fdc_status_error_7
mov dl,16
mov edi,0xD000
mov edi,FDD_BUFF
inc [FDD_Sector]
l.21_3:
mov esi,eax ;Name of file we want
783,7 → 783,7
add ebx,1
mov edi,ebx ; find free cluster in FAT
shl edi,1
add edi,0x282000
add edi,FLOPPY_FAT
mov eax,[edi]
and eax,4095
jnz frnewds_2
920,7 → 920,7
jne not_found_file_analyze_flp
 
mov ecx,512/32
mov ebx,0xD000
mov ebx,FDD_BUFF
 
adr1_analyze_flp:
mov esi,edx ;[esp+16]
937,7 → 937,7
 
mov eax,[clust_tmp_flp]
shl eax,1 ;find next cluster from FAT
add eax,0x282000
add eax,FLOPPY_FAT
mov eax,[eax]
and eax,4095
cmp eax,0x0ff8
985,7 → 985,7
jne error_found_file_analyze1
 
mov ecx,512/32
mov ebx,0xD000
mov ebx,FDD_BUFF
 
adr1_analyze1:
cmp byte [ebx],0x00
999,7 → 999,7
 
mov eax,[clust_tmp_flp]
shl eax,1 ;find next cluster from FAT
add eax,0x282000
add eax,FLOPPY_FAT
mov eax,[eax]
and eax,4095
cmp eax,0x0ff8
1013,14 → 1013,14
 
mov eax,[clust_tmp_flp]
shl eax,1 ;find next cluster from FAT
add eax,0x282000
sub edi,0x282000
add eax,FLOPPY_FAT
sub edi,FLOPPY_FAT
mov [eax],di
 
pusha
mov ecx,512/4
xor eax,eax
mov edi,0xD000
mov edi,FDD_BUFF
cld
rep stosd
popa
1032,7 → 1032,7
popa
cmp [FDC_Status],0
jne error_found_file_analyze1
mov ebx,0xD000
mov ebx,FDD_BUFF
 
found_file_analyze1:
 
1061,7 → 1061,7
add ebx,1
mov edi,ebx ; find free cluster in FAT
shl edi,1
add edi,0x282000
add edi,FLOPPY_FAT
mov eax,[edi]
and eax,4095
cmp eax,0x0
1114,6 → 1114,12
popa
ret
 
uglobal
; this is for delete support
fd_prev_sector dd ?
fd_prev_prev_sector dd ?
endg
 
flp_root_next:
cmp edi, 0xD200-0x20
jae @f
1124,6 → 1130,13
inc dword [eax]
cmp dword [eax], 14
jae flp_root_first.readerr
push [fd_prev_sector]
pop [fd_prev_prev_sector]
push eax
mov eax, [eax]
add eax, 19-1
mov [fd_prev_sector], eax
pop eax
flp_root_first:
mov eax, [eax]
pusha
1132,7 → 1145,7
popa
cmp [FDC_Status], 0
jnz .readerr
mov edi, 0xD000
mov edi, FDD_BUFF
ret ; CF=0
.readerr:
stc
1139,12 → 1152,12
ret
 
flp_rootmem_first:
mov edi, 0x8000
mov edi, FLOPPY_BUFF
clc
ret
flp_rootmem_next:
add edi, 0x20
cmp edi, 0x8000+14*0x200
cmp edi, FLOPPY_BUFF+14*0x200
cmc
flp_rootmem_next_write:
flp_rootmem_begin_write:
1162,7 → 1175,11
flp_notroot_next_sector:
push ecx
mov ecx, [eax]
mov ecx, [ecx*2+0x282000]
push [fd_prev_sector]
pop [fd_prev_prev_sector]
add ecx, 31
mov [fd_prev_sector], ecx
mov ecx, [(ecx-31)*2+FLOPPY_FAT]
and ecx, 0xFFF
cmp ecx, 2849
jae flp_notroot_first.err2
1178,7 → 1195,7
add eax, 31
call read_chs_sector
popa
mov edi, 0xD000
mov edi, FDD_BUFF
cmp [FDC_Status], 0
jnz .err
ret ; CF=0
1212,25 → 1229,25
; find free cluster in FAT
pusha
xor eax, eax
mov edi, 0x282000
mov edi, FLOPPY_FAT
mov ecx, 2849
repnz scasw
jnz .notfound
mov word [edi-2], 0xFFF ; mark as last cluster
sub edi, 0x282000
sub edi, FLOPPY_FAT
shr edi, 1
dec edi
mov eax, [esp+28]
mov ecx, [eax]
mov [0x282000+ecx*2], di
mov [FLOPPY_FAT+ecx*2], di
mov [eax], edi
xor eax, eax
mov edi, 0xD000
mov edi, FDD_BUFF
mov ecx, 128
rep stosd
popa
call flp_notroot_end_write
mov edi, 0xD000
mov edi, FDD_BUFF
clc
ret
.notfound:
1341,7 → 1358,7
popa
cmp [FDC_Status], 0
jnz .err
lea eax, [0xD000+ebx+512]
lea eax, [FDD_BUFF+ebx+512]
neg ebx
push ecx
cmp ecx, ebx
1355,7 → 1372,7
pop ecx
xor ebx, ebx
.skip:
movzx edi, word [edi*2+0x282000]
movzx edi, word [edi*2+FLOPPY_FAT]
jmp .new
.done:
mov ebx, edx
1435,7 → 1452,7
popa
cmp [FDC_Status], 0
jnz .error
mov edi, 0xD000
mov edi, FDD_BUFF
push eax
.l1:
call fat_get_name
1451,7 → 1468,7
jz .done
jns @f
; read next sector from FAT
mov eax, [(eax-31-1)*2+0x282000]
mov eax, [(eax-31-1)*2+FLOPPY_FAT]
and eax, 0xFFF
cmp eax, 0xFF8
jae .done
1463,7 → 1480,7
popa
cmp [FDC_Status], 0
jnz .error
mov edi, 0xD000
mov edi, FDD_BUFF
push eax
.do_bdfe:
inc dword [edx+8] ; new file found
1483,7 → 1500,7
jz .done
jns @f
; read next sector from FAT
mov eax, [(eax-31-1)*2+0x282000]
mov eax, [(eax-31-1)*2+FLOPPY_FAT]
and eax, 0xFFF
cmp eax, 0xFF8
jae .done
1533,7 → 1550,13
xor ebx, ebx
ret
 
fs_FloppyCreateFolder:
mov al, 1
jmp fs_FloppyRewrite.common
 
fs_FloppyRewrite:
xor eax, eax
.common:
cmp byte [esi], 0
jz @b
call read_flp_fat
1567,6 → 1590,9
push flp_rootmem_next
jmp .common1
.noroot:
mov eax, ERROR_ACCESS_DENIED
cmp byte [ebp+1], 0
jz .ret1
; check existence
mov byte [ebp], 0
call fd_find_lfn
1599,9 → 1625,25
.common1:
call fat_find_lfn
jc .notfound
; found; must not be directory
; found
test byte [edi+11], 10h
jz .exists_file
; found directory; if we are creating directory, return OK,
; if we are creating file, say "access denied"
add esp, 28
popad
test al, al
mov eax, ERROR_ACCESS_DENIED
jz @f
mov al, 0
@@:
xor ebx, ebx
ret
.exists_file:
; found file; if we are creating directory, return "access denied",
; if we are creating file, delete existing file and continue
cmp byte [esp+28+28], 0
jz @f
add esp, 28
popad
mov eax, ERROR_ACCESS_DENIED
1618,7 → 1660,7
@@:
cmp eax, 0xFF8
jae .done1
lea edi, [0x282000 + eax*2] ; position in FAT
lea edi, [FLOPPY_FAT + eax*2] ; position in FAT
xor eax, eax
xchg ax, [edi]
jmp @b
1823,6 → 1865,12
and word [edi+20], 0 ; high word of cluster
and word [edi+26], 0 ; low word of cluster - to be filled
and dword [edi+28], 0 ; file size - to be filled
cmp byte [esp+28+28], 0
jz .doit
; create directory
mov byte [edi+11], 10h ; attributes: folder
mov ecx, 32*2
mov edx, edi
.doit:
lea eax, [esp+8]
call dword [eax+12] ; flush directory
1830,9 → 1878,10
push edi
push 0
mov esi, edx
jecxz .done
test ecx, ecx
jz .done
mov ecx, 2849
mov edi, 0x282000
mov edi, FLOPPY_FAT
push 0 ; first cluster
.write_loop:
; allocate new cluster
1842,7 → 1891,7
jnz .ret
dec edi
dec edi
lea eax, [edi-0x282000]
lea eax, [edi-(FLOPPY_FAT)]
shr eax, 1 ; eax = cluster
mov word [edi], 0xFFF ; mark as last cluster
xchg edi, [esp+4]
1862,10 → 1911,13
jae @f
mov ecx, [esp+20]
@@:
mov edi, FDD_BUFF
cmp byte [esp+24+28+28], 0
jnz .writedir
push ecx
mov edi, 0xD000
rep movsb
pop ecx
.writedircont:
push ecx
sub ecx, 512
neg ecx
1918,6 → 1970,28
mov eax, 11
pop edi ecx
jmp .ret
.writedir:
push ecx
mov ecx, 32/4
push ecx esi
rep movsd
pop esi ecx
mov dword [edi-32], '. '
mov dword [edi-32+4], ' '
mov dword [edi-32+8], ' '
mov byte [edi-32+11], 10h
mov word [edi-32+26], ax
push esi
rep movsd
pop esi
mov dword [edi-32], '.. '
mov dword [edi-32+4], ' '
mov dword [edi-32+8], ' '
mov byte [edi-32+11], 10h
mov ecx, [esp+28+8]
mov word [edi-32+26], cx
pop ecx
jmp .writedircont
 
;----------------------------------------------------------------
;
2042,6 → 2116,13
jz .ret
call SetUserInterrupts
.write_loop:
; skip unmodified sectors
cmp dword [esp], 0x200
jb .modify
sub ebx, 0x200
jae .skip
add ebx, 0x200
.modify:
lea eax, [edi+31] ; current sector
; get length of data in current sector
push ecx
2079,7 → 2160,7
mov ecx, 0x200
sub ecx, [esp+4+12]
jbe @f
mov edi, 0xD000
mov edi, FDD_BUFF
add edi, [esp+4+12]
rep stosb
@@:
2087,7 → 2168,7
mov ecx, 0x200
sub ecx, esi
jbe @f
mov edi, 0xD000
mov edi, FDD_BUFF
add edi, esi
rep stosb
@@:
2097,7 → 2178,7
mov eax, edx
neg ebx
jecxz @f
add ebx, 0xD000+0x200
add ebx, FDD_BUFF+0x200
call memmove
xor ebx, ebx
@@:
2112,8 → 2193,9
sub [esp], ecx
pop ecx
jz .done
.skip:
.next_cluster:
movzx edi, word [edi*2+0x282000]
movzx edi, word [edi*2+FLOPPY_FAT]
sub esi, 0x200
jae @f
xor esi, esi
2143,7 → 2225,7
@@:
sub ecx, 0x200
jbe @f
mov eax, [eax*2+0x282000]
mov eax, [eax*2+FLOPPY_FAT]
and eax, 0xFFF
jz .fat_err
cmp eax, 0xFF8
2156,7 → 2238,7
ret
@@:
push eax
mov eax, [eax*2+0x282000]
mov eax, [eax*2+FLOPPY_FAT]
and eax, 0xFFF
cmp eax, 0xFF8
pop eax
2167,7 → 2249,7
pop ecx
; now do extend
push edx esi
mov esi, 0x282000+2*2 ; start scan from cluster 2
mov esi, FLOPPY_FAT+2*2 ; start scan from cluster 2
mov edx, 2847 ; number of clusters to scan
.extend_loop:
cmp [edi+28], ecx
2187,12 → 2269,12
mov word [edi-2], 0xFFF
mov esi, edi
mov edx, ecx
sub edi, 0x282000
sub edi, FLOPPY_FAT
shr edi, 1
dec edi ; now edi=new cluster
test eax, eax
jz .first_cluster
mov [0x282000+eax*2], di
mov [FLOPPY_FAT+eax*2], di
jmp @f
.first_cluster:
pop eax ; eax->direntry
2330,7 → 2412,7
mov ecx, [esp+4]
neg ecx
push edi
mov edi, 0xD000+0x200
mov edi, FDD_BUFF+0x200
add edi, [esp+8]
xor eax, eax
mov [esp+8], eax
2347,7 → 2429,7
.next_cluster:
sub dword [esp+12], 0x200
jbe .expand_done
movzx edi, word [0x282000+edi*2]
movzx edi, word [FLOPPY_FAT+edi*2]
jmp .zero_loop
.expand_done:
pop eax ecx ecx edi edi
2362,13 → 2444,13
@@:
sub eax, 0x200
jbe @f
movzx ecx, word [0x282000+ecx*2]
movzx ecx, word [FLOPPY_FAT+ecx*2]
jmp @b
@@:
; we will zero data at the end of last sector - remember it
push ecx
; terminate FAT chain
lea ecx, [0x282000+ecx+ecx]
lea ecx, [FLOPPY_FAT+ecx+ecx]
push dword [ecx]
mov word [ecx], 0xFFF
pop ecx
2382,7 → 2464,7
; mark all clusters as free
cmp ecx, 0xFF8
jae .deleted
lea ecx, [0x282000+ecx+ecx]
lea ecx, [FLOPPY_FAT+ecx+ecx]
push dword [ecx]
and word [ecx], 0
pop ecx
2409,8 → 2491,8
pusha
call read_chs_sector
popa
add edi, 0xD000
mov ecx, 0xD000+0x200
add edi, FDD_BUFF
mov ecx, FDD_BUFF+0x200
sub ecx, edi
push eax
xor eax, eax
2471,6 → 2553,7
@@:
ret
 
if 0
;----------------------------------------------------------------
;
; fs_FloppyExecute - LFN variant for executing from floppy
2542,7 → 2625,7
cmp [FDC_Status], 0
jnz .err
pop edi
mov esi, 0xD000
mov esi, FDD_BUFF
push edi
mov ecx, 512/4
rep movsd
2559,7 → 2642,7
@@:
mov [eax], ecx
mov edx, [eax+4]
mov dx, [edx*2+0x282000]
mov dx, [edx*2+FLOPPY_FAT]
mov [eax+4], dx ; high word is already zero
popad
xor eax, eax
2572,5 → 2655,135
popad
mov eax, 11
ret
end if
 
;----------------------------------------------------------------
;
; fs_FloppyDelete - delete file or empty folder from floppy
;
; esi points to filename
;
; ret eax = 0 ok or other = errormsg
;
;--------------------------------------------------------------
fs_FloppyDelete:
call read_flp_fat
cmp [FDC_Status], 0
jz @f
push 11
jmp .pop_ret
@@:
cmp byte [esi], 0
jnz @f
; cannot delete root!
.access_denied:
push ERROR_ACCESS_DENIED
.pop_ret:
pop eax
ret
@@:
and [fd_prev_sector], 0
and [fd_prev_prev_sector], 0
push edi
call fd_find_lfn
jnc .found
pop edi
push ERROR_FILE_NOT_FOUND
jmp .pop_ret
.found:
cmp dword [edi], '. '
jz .access_denied2
cmp dword [edi], '.. '
jz .access_denied2
test byte [edi+11], 10h
jz .dodel
; we can delete only empty folders!
push eax
movzx eax, word [edi+26]
push ebx
pusha
add eax, 31
call read_chs_sector
popa
mov ebx, FDD_BUFF + 2*0x20
.checkempty:
cmp byte [ebx], 0
jz .empty
cmp byte [ebx], 0xE5
jnz .notempty
add ebx, 0x20
cmp ebx, FDD_BUFF + 0x200
jb .checkempty
movzx eax, word [FLOPPY_FAT + eax*2]
pusha
add eax, 31
call read_chs_sector
popa
mov ebx, FDD_BUFF
jmp .checkempty
.notempty:
pop ebx
pop eax
.access_denied2:
pop edi
jmp .access_denied
.empty:
pop ebx
pop eax
pusha
call read_chs_sector
popa
.dodel:
push eax
movzx eax, word [edi+26]
xchg eax, [esp]
; delete folder entry
mov byte [edi], 0xE5
; delete LFN (if present)
.lfndel:
cmp edi, FDD_BUFF
ja @f
cmp [fd_prev_sector], 0
jz .lfndone
push [fd_prev_sector]
push [fd_prev_prev_sector]
pop [fd_prev_sector]
and [fd_prev_prev_sector], 0
pusha
call save_chs_sector
popa
pop eax
pusha
call read_chs_sector
popa
mov edi, FDD_BUFF+0x200
@@:
sub edi, 0x20
cmp byte [edi], 0xE5
jz .lfndone
cmp byte [edi+11], 0xF
jnz .lfndone
mov byte [edi], 0xE5
jmp .lfndel
.lfndone:
pusha
call save_chs_sector
popa
; delete FAT chain
pop eax
test eax, eax
jz .done
@@:
lea eax, [FLOPPY_FAT + eax*2]
push dword [eax]
and word [eax], 0
pop eax
and eax, 0xFFF
jnz @b
.done:
call save_flp_fat
pop edi
xor eax, eax
ret
 
; \end{diamond}
/kernel/branches/gfx_kernel/fs/fat32.inc
7,6 → 7,9
;; Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it ;;
;; ;;
;; See file COPYING for details ;;
;; 04.02.2007 LFN create folder - diamond ;;
;; 08.10.2006 LFN delete file/folder - diamond ;;
;; 20.08.2006 LFN set file size (truncate/extend) - diamond ;;
;; 17.08.2006 LFN write/append to file - diamond ;;
;; 23.06.2006 LFN start application - diamond ;;
;; 15.06.2006 LFN get/set file/folder info - diamond ;;
60,6 → 63,8
PUSHAD_ESI equ [esp+4]
PUSHAD_EDI equ [esp+0]
 
uglobal
align 4
cluster dd 0 ; used by file_write,makedir,append
partition_count dd 0 ; partitions found by set_FAT32_variables
longname_sec1 dd 0 ; used by analyze_directory to save 2 previous
82,24 → 87,20
bytes2write dd 0 ; used by append
 
cache_search_start dd 0 ; used by find_empty_slot
endg
 
iglobal
fat_in_cache dd -1
fat_cache: times 512 db 0
endg
 
uglobal
align 4
fat_cache: times 512 db 0
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
NewDirEntry1 db ". ",0x10
times 20 db 0
NewDirEntry2 db ".. ",0x10
times 20 db 0
endg
 
uglobal
dir_entry: times 32 db 0
 
123,14 → 124,19
reserve_ok1:
 
push eax
mov eax,[0x3000]
mov eax,[CURRENT_TASK]
shl eax,5
mov eax,[eax+0x3000+TASKDATA.pid]
mov eax,[eax+CURRENT_TASK+TASKDATA.pid]
mov [hd1_status],eax
pop eax
sti
ret
;********************************************
 
uglobal
hd_in_cache db ?
endg
 
reserve_hd_channel:
cmp [hdbase], 0x1F0
jne .IDE_Channel_2
147,12 → 153,25
je .reserve_ok_2
sti
call change_task
jmp .IDE_Channel_1
jmp .IDE_Channel_2
.reserve_ok_1:
mov [IDE_Channel_1],1
ret
push eax
mov al, 1
jmp @f
.reserve_ok_2:
mov [IDE_Channel_2],1
push eax
mov al, 3
@@:
cmp [hdid], 1
sbb al, -1
cmp al, [hd_in_cache]
jz @f
mov [hd_in_cache], al
call clear_hd_cache
@@:
pop eax
ret
free_hd_channel:
165,20 → 184,6
mov [IDE_Channel_2],0
ret
;********************************************
clear_hd_cache:
 
push eax ecx edi
mov edi,0x600000
mov ecx,16384
xor eax,eax
cld
rep stosd ; clear hd cache with 0
mov [cache_search_start],eax
mov [fat_in_cache],-1
mov [fat_change],0
pop edi ecx eax
ret
 
problem_partition db 0 ; used for partitions search
 
include 'part_set.inc'
195,7 → 200,7
jb sfc_error
cmp eax,[LAST_CLUSTER]
ja sfc_error
cmp [fat_type],16
cmp [fs_type],16
je sfc_1
add eax,eax
sfc_1:
223,7 → 228,7
 
sfc_in_cache:
cmp [fat_type],16
cmp [fs_type],16
jne sfc_test32
 
sfc_set16:
259,7 → 264,7
;--------------------------------
push ebx esi
 
cmp [fat_type],16
cmp [fs_type],16
je gfc_1
add eax,eax
gfc_1:
387,7 → 392,7
jnb adr_data_cluster
 
mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir
cmp [fat_type],16
cmp [fs_type],16
jne adr_data_cluster
mov eax,[ROOT_START]
mov edx,[ROOT_SECTORS]
482,7 → 487,7
jnb adw_data_cluster
 
mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir
cmp [fat_type],16
cmp [fs_type],16
jne adw_data_cluster
mov eax,[ROOT_START]
mov edx,[ROOT_SECTORS]
605,7 → 610,7
jnb gdc_cluster
 
mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir
cmp [fat_type],16
cmp [fs_type],16
jne gdc_cluster
mov eax,[ROOT_START]
mov ecx,[ROOT_SECTORS] ; Note: not cluster size
812,219 → 817,7
ret
 
 
makedir:
;-----------------------------------------------------
; input : eax = directory name
; edx = path
; output : eax = 0 - ok
; 3 - unknown FS
; 5 - file not found
; 8 - disk full
; 10 - access denied
; Note : can only make one directory at time
;-----------------------------------------------------
cmp [fat_type],0
jnz make_dir_fat_ok
mov eax,ERROR_UNKNOWN_FS
ret
 
make_dir_fat_ok:
; call reserve_hd1
 
pushad
 
mov ebx,edx
call get_cluster_of_a_path
jnc make_dir_found_path
cmp [hd_error],0
jne make_dir_error_1
 
make_dir_path_not_found:
popad
call update_disk ; write all of cache and fat to hd
cmp [hd_error],0
jne make_dir_error_2
 
mov [hd1_status],0
mov eax,ERROR_FILE_NOT_FOUND
ret
 
make_dir_disk_full:
cmp [hd_error],0
jne make_dir_error_1
popad
call update_disk ; write all of cache and fat to hd
cmp [hd_error],0
jne make_dir_error_2
 
mov [hd1_status],0
mov eax,ERROR_DISK_FULL
ret
 
make_dir_already_exist:
cmp [hd_error],0
jne make_dir_error_1
mov eax,[cluster] ; directory cluster
xor edx,edx ; free
call set_FAT
cmp [hd_error],0
jne make_dir_error_1
 
popad
call update_disk ; write all of cache and fat to hd
make_dir_error_2:
mov [hd1_status],0
mov eax,ERROR_ACCESS_DENIED
ret
 
make_dir_error_1:
popad
jmp make_dir_error_2
 
make_dir_error_3:
add esp,4
jmp make_dir_error_1
 
make_dir_found_path:
cmp eax,[ROOT_CLUSTER]
jnz make_dir_not_root
xor eax,eax
 
make_dir_not_root:
mov ecx,eax ; directorys start cluster
mov word [NewDirEntry2+26],cx ; 16 bits low of cluster
shr ecx,16
mov word [NewDirEntry2+20],cx ; 16 bits high of cluster (=0 fat16)
 
push eax ; save parent directory cluster
mov eax,2
call get_free_FAT
mov [cluster],eax ; first free cluster
pop eax
jc make_dir_disk_full
 
push eax
mov eax,[cluster] ; directory cluster
mov edx,[fatEND] ; end for directory
call set_FAT
cmp [hd_error],0
jne make_dir_error_3
pop eax
 
mov ebx,PUSHAD_EAX ; dir name
push eax
call analyze_directory ; check if directory already exist
cmp [hd_error],0
jne make_dir_error_1
 
pop eax
jnc make_dir_already_exist ; need to free allocated cluster!
 
call analyze_directory_to_write
jc make_dir_already_exist ; need to free allocated cluster!
 
mov esi,PUSHAD_EAX ; dir name
mov edi,ebx ; pointer in buffer
mov ecx,11
cld
rep movsb
 
mov dword [ebx+28],0 ; dir size is always 0
mov ecx,[cluster]
mov [ebx+26],cx ; 16 bits low of cluster
mov word [NewDirEntry1+26],cx
shr ecx,16
mov [ebx+20],cx ; 16 bits high of cluster (=0 fat16)
mov word [NewDirEntry1+20],cx
mov byte [ebx+11],0x10 ; attribute = directory
 
call set_current_time_for_entry
mov ecx,[ebx+22]
mov dword [NewDirEntry1+22],ecx
mov dword [NewDirEntry2+22],ecx
 
mov ebx,buffer ; save the directory name,length,cluster
call hd_write
cmp [hd_error],0
jne make_dir_error_1
 
mov ecx,512/4
xor eax,eax
mov edi,buffer
cld
rep stosd ; clear new directory cluster
 
mov eax,[cluster] ; new directory cluster
sub eax,2
mov edx,[SECTORS_PER_CLUSTER]
imul eax,edx
add eax,[DATA_START]
mov ebx,buffer
add eax,edx ; start from last sector
 
dir_set_empty_directory:
dec eax ; next sector
cmp edx,1 ; is first directory sector?
jnz not_first_sector ; no. write empty sector
mov esi,NewDirEntry1
mov edi,buffer
mov ecx,64/4
cld
rep movsd ; copy 2 first directory entrys "." and ".."
 
not_first_sector:
call hd_write
cmp [hd_error],0
jne make_dir_error_1
dec edx
jnz dir_set_empty_directory
 
mov ecx,-1 ; remove 1 cluster from free disk space
call add_disk_free_space
cmp [hd_error],0
jne make_dir_error_1
 
popad
call update_disk ; write all of cache and fat to hd
cmp [hd_error],0
jne make_dir_error_2
mov [hd1_status],0
xor eax,eax
ret
 
 
removedir:
;-----------------------------------------------------
; input : eax = file/directory name
; edx = path
; output : eax = 0 - ok
; 3 - unknown FS
; 5 - file not found
; 10 - access denied
;-----------------------------------------------------
cmp [fat_type],0
jnz remove_dir_fat_ok
mov eax,ERROR_UNKNOWN_FS
ret
 
remove_dir_fat_ok:
; call reserve_hd1
 
push edi
mov edi,1 ; allow directory remove
call file_delete
cmp [hd_error],0
jne @f
 
pop edi
 
call update_disk ; write all of cache and fat to hd
@@:
mov [hd1_status],0
ret
 
add_disk_free_space:
;-----------------------------------------------------
; input : ecx = cluster count
1033,7 → 826,7
;-----------------------------------------------------
test ecx,ecx ; no change
je add_dfs_no
cmp [fat_type],32 ; free disk space only used by fat32
cmp [fs_type],32 ; free disk space only used by fat32
jne add_dfs_no
 
push eax ebx
1074,9 → 867,12
; 8 - disk full
; 10 - access denied
;--------------------------------------------------------------------------
cmp [fat_type],0
jnz fat_ok_for_writing
mov eax,ERROR_UNKNOWN_FS
cmp [fs_type], 16
jz fat_ok_for_writing
cmp [fs_type], 32
jz fat_ok_for_writing
push ERROR_UNKNOWN_FS
pop eax
ret
 
fat_ok_for_writing:
1260,8 → 1056,10
; 10 - access denied
; ebx = size of file/directory
;--------------------------------------------------------------------------
cmp [fat_type],0
jnz fat_ok_for_reading
cmp [fs_type], 16
jz fat_ok_for_reading
cmp [fs_type], 32
jz fat_ok_for_reading
xor ebx,ebx
mov eax,ERROR_UNKNOWN_FS
mov [hd1_status], ebx
1382,7 → 1180,7
 
mov eax,[ROOT_SECTORS]
shl eax,9 ; fat16 rootdir size in bytes
cmp [fat_type],16
cmp [fs_type],16
je dir_size_ret
mov eax,[ROOT_CLUSTER]
 
1417,9 → 1215,12
; 5 - file not found
; 10 - access denied
;-----------------------------------------------------
cmp [fat_type],0
jnz file_del_fat_ok
mov eax,ERROR_UNKNOWN_FS
cmp [fs_type], 16
jz file_del_fat_ok
cmp [fs_type], 32
jz file_del_fat_ok
push ERROR_UNKNOWN_FS
pop eax
ret
 
file_del_fat_ok:
1434,26 → 1235,8
jc file_to_delete_not_found
 
test byte [ebx+11],0x10 ; is it directory?
jz delete_notdir ; no. it's file
cmp edi,1 ; allow directory remove
jnz delete_no_access ; no
jnz delete_no_access
 
push eax ; save directory sector
mov eax,[ebx+20-2] ; first cluster of file
mov ax,[ebx+26] ; 0 length files start cluster = 0
and eax,[fatMASK]
xor ebp,ebp ; counter for directory deepnes
call clear_directory
pop eax
jc delete_no_access
 
push ebx ; save directory pointer in buffer
mov ebx,buffer
call hd_read ; read directory sector
cmp [hd_error],0
jne delete_no_access_1
pop ebx
 
delete_notdir:
call delete_entry_name
cmp [hd_error],0
1514,129 → 1297,6
ret
 
 
clear_directory:
;-----------------------------------------------------
; input : eax = directory cluster
; ebp = directory deepnes
; Note : use recursive call
;-----------------------------------------------------
pushad
inc ebp
cmp ebp,64 ; if over 63 directory deep
jnb clear_error ; something must be wrong
 
clear_new_cluster:
cmp eax,[LAST_CLUSTER]
ja clear_end
cmp eax,[ROOT_CLUSTER] ; don't remove root cluster
jz clear_end
mov esi,eax ; esi = current directory cluster
sub eax,2
jb clear_end
mov ecx,[SECTORS_PER_CLUSTER]
imul eax,ecx
add eax,[DATA_START]
 
clear_new_sector:
mov edi,eax ; edi = current directory sector
mov ebx,deltree_buffer
call hd_read
cmp [hd_error],0
jne clear_error
 
mov edx,512/32 ; count of dir entrys per sector = 16
 
clear_analyze:
mov al,[ebx+11] ; file attribute
and al,0xf
cmp al,0xf
je clear_long_filename
 
cmp byte [ebx],'.' ; parent or current directory
je clear_next_entry
cmp byte [ebx],0xe5 ; deleted
je clear_next_entry
cmp byte [ebx],0 ; empty
je clear_write_last
;je clear_next_entry
 
mov eax,[ebx+20-2] ; first cluster of entry
mov ax,[ebx+26]
and eax,[fatMASK]
 
test byte [ebx+11],0x10 ; is it directory?
jz clear_file ; no
 
push eax ebx
mov eax,edi
mov ebx,deltree_buffer ; save buffer over recursive call
call hd_write ; write directory sector to disk
cmp [hd_error],0
jne clear_error
 
pop ebx eax
 
call clear_directory ; recursive call !!!
jc clear_error ; exit if error found
 
push eax ebx
mov eax,edi
mov ebx,deltree_buffer
call hd_read ; read directory sector again
cmp [hd_error],0
jne clear_error_1
 
pop ebx eax
 
clear_file:
call clear_cluster_chain
cmp [hd_error],0
jne clear_error
 
clear_long_filename:
mov byte [ebx],0xe5
 
clear_next_entry:
add ebx,32 ; position of next dir entry
dec edx
jnz clear_analyze
 
mov eax,edi
mov ebx,deltree_buffer
call hd_write ; write directory sector to disk
cmp [hd_error],0
jne clear_error
 
inc eax ; next sector
dec ecx
jnz clear_new_sector
 
mov eax,esi
call get_FAT ; get next cluster
cmp [hd_error],0
jne clear_error
 
jmp clear_new_cluster ; clear it
 
clear_write_last:
mov eax,edi
mov ebx,deltree_buffer
call hd_write ; write directory sector to disk
cmp [hd_error],0
jne clear_error
 
clear_end:
popad
clc
ret
clear_error_1:
add esp,8
clear_error:
popad
stc
ret
 
 
delete_entry_name:
;-----------------------------------------------------
; input : eax = directory sector
1691,169 → 1351,6
ret
 
 
rename:
;-----------------------------------------------------------
; input : eax = source directory name
; edx = source path
; ebx = dest directory name
; edi = dest path
; output : eax = 0 - ok
; 3 - unknown FS
; 5 - file not found
; 8 - disk full
; 10 - access denied
;-----------------------------------------------------------
cmp [fat_type],0
jnz fat_ok_for_rename
mov eax,ERROR_UNKNOWN_FS
ret
 
fat_ok_for_rename:
; call reserve_hd1
 
pushad
 
mov ebx,edx ; source path
call get_cluster_of_a_path
jc rename_entry_not_found
 
mov ebx,PUSHAD_EAX ; source directory name
call analyze_directory
jc rename_entry_not_found
 
mov [sector_tmp],eax ; save source sector
mov [entry_pos],ebx
mov esi,ebx
mov edi,dir_entry
mov ecx,32/4
cld
rep movsd ; save entry
 
mov ebx,PUSHAD_EDI ; dest path
call get_cluster_of_a_path
jc rename_entry_not_found
 
mov edx,eax ; save dest directory cluster
mov ebx,PUSHAD_EBX ; dest directory name
push [longname_sec1]
push [longname_sec2]
call analyze_directory ; check if entry already exist
cmp [hd_error],0
jne rename_entry_already_exist_1
 
pop [longname_sec2]
pop [longname_sec1]
jnc rename_entry_already_exist
 
mov eax,edx
call analyze_directory_to_write
jc rename_disk_full
 
mov esi,dir_entry
mov edi,ebx
mov ecx,32/4
cld
rep movsd ; copy entry
mov esi,PUSHAD_EBX ; dest directory name
mov edi,ebx
mov ecx,11
rep movsb ; copy name
 
mov ebx,buffer ; save the directory name,length,cluster
call hd_write
 
test byte [dir_entry+11],0x10 ; is it directory?
jz rename_not_dir ; no
mov eax,[dir_entry+20-2] ; FAT entry
mov ax,[dir_entry+26]
and eax,[fatMASK]
call change_2dot_cluster
cmp [hd_error],0
jne rename_entry_already_exist
 
rename_not_dir:
cmp [hd_error],0
jne rename_entry_already_exist
mov eax,[sector_tmp]
mov ebx,buffer
call hd_read ; read source directory sector
cmp [hd_error],0
jne rename_entry_already_exist
 
mov ebx,[entry_pos]
call delete_entry_name
cmp [hd_error],0
jne rename_entry_already_exist
 
popad
call update_disk ; write all of cache and fat to hd
cmp [hd_error],0
jne rename_entry_already_exist_2
mov [hd1_status],0
xor eax,eax
ret
 
rename_entry_not_found:
cmp [hd_error],0
jne rename_entry_already_exist
popad
mov [hd1_status],0
mov eax,ERROR_FILE_NOT_FOUND
ret
 
rename_entry_already_exist_1:
add esp,8
rename_entry_already_exist:
popad
rename_entry_already_exist_2:
mov [hd1_status],0
mov eax,ERROR_ACCESS_DENIED
ret
 
rename_disk_full:
cmp [hd_error],0
jne rename_entry_already_exist
popad
mov [hd1_status],0
mov eax,ERROR_DISK_FULL
ret
 
 
change_2dot_cluster:
;-----------------------------------------------------------
; input : eax = directory cluster
; edx = value to save
; change : eax,ebx,edx
;-----------------------------------------------------------
cmp eax,[LAST_CLUSTER]
ja not_2dot ; too big cluster number, something is wrong
sub eax,2
jb not_2dot
 
imul eax,[SECTORS_PER_CLUSTER]
add eax,[DATA_START]
mov ebx,buffer
call hd_read
cmp [hd_error],0
jne not_2dot
 
cmp dword [ebx+32],'.. '
jnz not_2dot
 
cmp edx,[ROOT_CLUSTER] ; is rootdir cluster?
jne not_2dot_root
xor edx,edx ; yes. set it zero
 
not_2dot_root:
mov [ebx+32+26],dx ; 16 bits low of cluster
shr edx,16
mov [ebx+32+20],dx ; 16 bits high of cluster (=0 fat16)
call hd_write
 
not_2dot:
ret
 
 
get_hd_info:
;-----------------------------------------------------------
; output : eax = 0 - ok
1863,8 → 1360,10
; ebx = total clusters on disk
; ecx = free clusters on disk
;-----------------------------------------------------------
cmp [fat_type],0
jnz info_fat_ok
cmp [fs_type], 16
jz info_fat_ok
cmp [fs_type], 32
jz info_fat_ok
xor edx,edx
xor ebx,ebx
xor ecx,ecx
1925,430 → 1424,6
update_disk_acces_denied:
ret
 
 
;**************************************************************************
;
; 0x600008 - first entry in cache list
;
; +0 - lba sector
; +4 - state of cache sector
; 0 = empty
; 1 = used for read ( same as in hd )
; 2 = used for write ( differs from hd )
;
; +65536 - cache entries
;
;**************************************************************************
 
 
hd_read:
;-----------------------------------------------------------
; input : eax = block to read
; ebx = destination
;-----------------------------------------------------------
push ecx esi edi ; scan cache
 
mov ecx,cache_max ; entries in cache
mov esi,0x600000+8
mov edi,1
 
hdreadcache:
 
cmp dword [esi+4],0 ; empty
je nohdcache
 
cmp [esi],eax ; correct sector
je yeshdcache
 
nohdcache:
 
add esi,8
inc edi
dec ecx
jnz hdreadcache
 
call find_empty_slot ; ret in edi
cmp [hd_error],0
jne return_01
 
push eax edx
 
call wait_for_hd_idle
cmp [hd_error],0
jne hd_read_error
 
cli
xor eax,eax
mov edx,[hdbase]
inc edx
out dx,al ; ATAFeatures ॣ¨áâà "®á®¡¥­­®á⥩"
inc edx
inc eax
out dx,al ; ATASectorCount áç¥â稪 ᥪâ®à®¢
inc edx
mov eax,[esp+4]
out dx,al ; ATASectorNumber ॣ¨áâà ­®¬¥à  ᥪâ®à 
shr eax,8
inc edx
out dx,al ; ATACylinder ­®¬¥à 樫¨­¤à  (¬« ¤è¨© ¡ ©â)
shr eax,8
inc edx
out dx,al ; ­®¬¥à 樫¨­¤à  (áâ à訩 ¡ ©â)
shr eax,8
inc edx
and al,1+2+4+8
add al,byte [hdid]
add al,128+64+32
out dx,al ; ­®¬¥à £®«®¢ª¨/­®¬¥à ¤¨áª 
inc edx
mov al,20h
out dx,al ; ATACommand ॣ¨áâà ª®¬ ­¤
sti
 
call wait_for_sector_buffer
 
cmp [hd_error],0
jne hd_read_error
 
cli
push edi
shl edi,9
add edi,0x600000+65536
mov ecx,256
mov edx,[hdbase]
cld
rep insw
pop edi
sti
 
pop edx eax
blok_read_2:
lea esi,[edi*8+0x600000]
mov [esi],eax ; sector number
mov dword [esi+4],1 ; hd read - mark as same as in hd
 
yeshdcache:
 
mov esi,edi
shl esi,9
add esi,0x600000+65536
mov edi,ebx
mov ecx,512/4
cld
rep movsd ; move data
return_01:
pop edi esi ecx
ret
 
hd_write:
;-----------------------------------------------------------
; input : eax = block
; ebx = pointer to memory
;-----------------------------------------------------------
push ecx esi edi
 
; check if the cache already has the sector and overwrite it
 
mov ecx,cache_max
mov esi,0x600000+8
mov edi,1
 
hdwritecache:
 
cmp dword [esi+4],0 ; if cache slot is empty
je not_in_cache_write
 
cmp [esi],eax ; if the slot has the sector
je yes_in_cache_write
 
not_in_cache_write:
 
add esi,8
inc edi
dec ecx
jnz hdwritecache
 
; sector not found in cache
; write the block to a new location
 
call find_empty_slot ; ret in edi
cmp [hd_error],0
jne hd_write_access_denied
 
lea esi,[edi*8+0x600000]
mov [esi],eax ; sector number
 
yes_in_cache_write:
 
mov dword [esi+4],2 ; write - differs from hd
 
shl edi,9
add edi,0x600000+65536
mov esi,ebx
mov ecx,512/4
cld
rep movsd ; move data
hd_write_access_denied:
pop edi esi ecx
ret
 
 
write_cache:
;-----------------------------------------------------------
; write all changed sectors to disk
;-----------------------------------------------------------
push eax ecx edx esi edi
 
; write difference ( 2 ) from cache to hd
 
mov ecx,cache_max
mov esi,0x600000+8
mov edi,1
 
write_cache_more:
 
cmp dword [esi+4],2 ; if cache slot is not different
jne does_not_need_writing
 
mov dword [esi+4],1 ; same as in hd
mov eax,[esi] ; eax = sector to write
 
cmp eax,[PARTITION_START]
jb danger
cmp eax,[PARTITION_END]
ja danger
 
call wait_for_hd_idle
cmp [hd_error],0
jne hd_write_error
 
cli
xor eax,eax
mov edx,[hdbase]
inc edx
out dx,al
inc edx
inc eax
out dx,al
inc edx
mov eax,[esi] ; eax = sector to write
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,byte [hdid]
add al,128+64+32
out dx,al
inc edx
mov al,30h
out dx,al
sti
 
call wait_for_sector_buffer
 
cmp [hd_error],0
jne hd_write_error
 
push ecx esi
 
cli
mov esi,edi
shl esi,9
add esi,0x600000+65536 ; esi = from memory position
mov ecx,256
mov edx,[hdbase]
cld
rep outsw
sti
 
pop esi ecx
 
danger:
does_not_need_writing:
 
add esi,8
inc edi
dec ecx
jnz write_cache_more
return_02:
pop edi esi edx ecx eax
ret
 
 
find_empty_slot:
;-----------------------------------------------------------
; find empty or read slot, flush cache if next 10% is used by write
; output : edi = cache slot
;-----------------------------------------------------------
push ecx esi
 
search_again:
 
mov ecx,cache_max*10/100
mov edi,[cache_search_start]
 
search_for_empty:
 
inc edi
cmp edi,cache_max
jbe inside_cache
mov edi,1
 
inside_cache:
 
cmp dword [edi*8+0x600000+4],2 ; get cache slot info
jb found_slot ; it's empty or read
dec ecx
jnz search_for_empty
 
call write_cache ; no empty slots found, write all
cmp [hd_error],0
jne found_slot_access_denied
 
jmp search_again ; and start again
 
found_slot:
 
mov [cache_search_start],edi
found_slot_access_denied:
pop esi ecx
ret
 
 
save_hd_wait_timeout:
 
push eax
mov eax,[timer_ticks];[0xfdf0]
add eax,300 ; 3 sec timeout
mov [hd_wait_timeout],eax
pop eax
ret
 
 
check_hd_wait_timeout:
 
push eax
mov eax,[hd_wait_timeout]
cmp [timer_ticks], eax ;[0xfdf0],eax
jg hd_timeout_error
pop eax
mov [hd_error],0
ret
 
iglobal
hd_timeout_str db 'K : FS - HD timeout',13,10,0
hd_read_str db 'K : FS - HD read error',13,10,0
hd_write_str db 'K : FS - HD write error',13,10,0
hd_lba_str db 'K : FS - HD LBA error',13,10,0
endg
 
hd_timeout_error:
 
call clear_hd_cache
call clear_application_table_status
mov esi,hd_timeout_str
call sys_msg_board_str
; jmp $
mov [hd_error],1
pop eax
ret
 
hd_read_error:
 
call clear_hd_cache
call clear_application_table_status
mov esi,hd_read_str
call sys_msg_board_str
pop edx eax
jmp return_01
; jmp $
 
hd_write_error:
 
call clear_hd_cache
call clear_application_table_status
mov esi,hd_write_str
call sys_msg_board_str
jmp return_02
; jmp $
 
hd_lba_error:
call clear_hd_cache
call clear_application_table_status
mov esi,hd_lba_str
call sys_msg_board_str
jmp LBA_read_ret
 
 
wait_for_hd_idle:
 
push eax edx
 
call save_hd_wait_timeout
 
mov edx,[hdbase]
add edx,0x7
 
wfhil1:
 
call check_hd_wait_timeout
cmp [hd_error],0
jne @f
 
in al,dx
test al,128
jnz wfhil1
@@:
 
pop edx eax
ret
 
 
 
wait_for_sector_buffer:
 
push eax edx
 
mov edx,[hdbase]
add edx,0x7
 
call save_hd_wait_timeout
 
hdwait_sbuf: ; wait for sector buffer to be ready
 
call check_hd_wait_timeout
cmp [hd_error],0
jne @f
 
in al,dx
test al,8
jz hdwait_sbuf
 
mov [hd_error],0
 
cmp [hd_setup],1 ; do not mark error for setup request
je buf_wait_ok
 
test al,1 ; previous command ended up with an error
jz buf_wait_ok
@@:
mov [hd_error],1
 
buf_wait_ok:
 
pop edx eax
ret
 
 
 
read_hd_file:
;-----------------------------------------------------------------
;
2411,7 → 1486,7
push fat16_root_first
push fat16_root_next
mov eax, [ROOT_CLUSTER]
cmp [fat_type], 32
cmp [fs_type], 32
jz .fat32
.loop:
call fat_find_lfn
2462,8 → 1537,12
;
;--------------------------------------------------------------
fs_HdRead:
cmp [fat_type], 0
jnz @f
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
cmp [fs_type], 1
jz ntfs_HdRead
or ebx, -1
mov eax, ERROR_UNKNOWN_FS
ret
2617,6 → 1696,17
;
;--------------------------------------------------------------
fs_HdReadFolder:
cmp [fs_type], 1
jz ntfs_HdReadFolder
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
push ERROR_UNSUPPORTED_FS
pop eax
or ebx, -1
ret
@@:
mov eax, [ROOT_CLUSTER]
push edi
cmp byte [esi], 0
2657,7 → 1747,7
mov [cluster_tmp], eax
test eax, eax
jnz @f
cmp [fat_type], 32
cmp [fs_type], 32
jz .notfound
mov eax, [ROOT_START]
push [ROOT_SECTORS]
2777,8 → 1867,14
ret ; CF=0
fat16_root_next_sector:
; read next sector
push [longname_sec2]
pop [longname_sec1]
push ecx
mov ecx, [eax+4]
push ecx
add ecx, [ROOT_START]
mov [longname_sec2], ecx
pop ecx
inc ecx
mov [eax+4], ecx
cmp ecx, [ROOT_SECTORS]
2828,6 → 1924,12
add edi, 0x20
ret ; CF=0
fat_notroot_next_sector:
push [longname_sec2]
pop [longname_sec1]
push eax
call fat_get_sector
mov [longname_sec2], eax
pop eax
push ecx
mov ecx, [eax+4]
inc ecx
2974,9 → 2076,20
xor ebx, ebx
ret
 
fs_HdCreateFolder:
mov al, 1
jmp fs_HdRewrite.common
 
fs_HdRewrite:
cmp [fat_type], 0
jz fshrfs
xor eax, eax
.common:
cmp [fs_type], 1
jz ntfs_HdRewrite
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jnz fshrfs
@@:
cmp byte [esi], 0
jz fshrad
pushad
2995,7 → 2108,7
test ebp, ebp
jnz .noroot
mov ebp, [ROOT_CLUSTER]
cmp [fat_type], 32
cmp [fs_type], 32
jz .pushnotroot
push fat16_root_extend_dir
push fat16_root_end_write
3008,6 → 2121,9
push fat16_root_next
jmp .common1
.noroot:
mov eax, ERROR_ACCESS_DENIED
cmp byte [ebp+1], 0
jz .ret1
; check existence
mov byte [ebp], 0
call hd_find_lfn
3041,9 → 2157,25
.common1:
call fat_find_lfn
jc .notfound
; found; must not be directory
; found
test byte [edi+11], 10h
jz .exists_file
; found directory; if we are creating directory, return OK,
; if we are creating file, say "access denied"
add esp, 32
popad
test al, al
mov eax, ERROR_ACCESS_DENIED
jz @f
mov al, 0
@@:
xor ebx, ebx
ret
.exists_file:
; found file; if we are creating directory, return "access denied",
; if we are creating file, delete existing file and continue
cmp byte [esp+32+28], 0
jz @f
add esp, 32
popad
mov eax, ERROR_ACCESS_DENIED
3279,11 → 2411,23
mov word [edi+20], cx ; high word of cluster
mov word [edi+26], cx ; low word of cluster - to be filled
mov dword [edi+28], ecx ; file size - to be filled
cmp byte [esp+32+28], cl
jz .doit
; create directory
mov byte [edi+11], 10h ; attributes: folder
mov edx, edi
lea eax, [esp+8]
call dword [eax+16] ; flush directory
push ecx
mov ecx, [SECTORS_PER_CLUSTER]
shl ecx, 9
jmp .doit2
.doit:
lea eax, [esp+8]
call dword [eax+16] ; flush directory
push ecx
mov ecx, [esp+4+32+24]
.doit2:
push ecx
push edi
mov esi, edx
3312,6 → 2456,8
add eax, [DATA_START]
; write data
.write_sector:
cmp byte [esp+16+32+28], 0
jnz .writedir
mov ecx, 512
cmp dword [esp+8], ecx
jb .writeshort
3325,6 → 2471,7
mov edi, buffer
mov ebx, edi
rep movsb
.writedircont:
mov ecx, buffer+0x200
sub ecx, edi
push eax
3391,10 → 2538,44
call update_disk
popad
ret
.writedir:
push 512
mov edi, buffer
mov ebx, edi
mov ecx, [SECTORS_PER_CLUSTER]
shl ecx, 9
cmp ecx, [esp+12]
jnz .writedircont
dec dword [esp+16]
push esi
mov ecx, 32/4
rep movsd
pop esi
mov dword [edi-32], '. '
mov dword [edi-32+4], ' '
mov dword [edi-32+8], ' '
mov byte [edi-32+11], 10h
push esi
mov ecx, 32/4
rep movsd
pop esi
mov dword [edi-32], '.. '
mov dword [edi-32+4], ' '
mov dword [edi-32+8], ' '
mov byte [edi-32+11], 10h
mov ecx, [esp+20+8]
cmp ecx, [ROOT_CLUSTER]
jnz @f
xor ecx, ecx
@@:
mov word [edi-32+26], cx
shr ecx, 16
mov [edi-32+20], cx
jmp .writedircont
 
;----------------------------------------------------------------
;
; fs_HdWrite - LFN variant for writing to floppy
; fs_HdWrite - LFN variant for writing to hard disk
;
; esi points to filename
; ebx pointer to 64-bit number = first wanted byte, 0+
3418,8 → 2599,12
jmp fs_HdWrite.ret0
 
fs_HdWrite:
cmp [fat_type], 0
jnz @f
cmp [fs_type], 1
jz ntfs_HdWrite
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
push ERROR_UNKNOWN_FS
jmp .ret0
@@:
3529,6 → 2714,13
sub ecx, ebx
jz .ret
.write_loop:
; skip unmodified sectors
cmp dword [esp], 0x200
jb .modify
sub ebx, 0x200
jae .skip
add ebx, 0x200
.modify:
; get length of data in current sector
push ecx
sub ebx, 0x200
3585,9 → 2777,8
add edi, esi
rep stosb
@@:
pop edi ecx eax
pop edi ecx
; copy new data
push eax
mov eax, edx
neg ebx
jecxz @f
3607,6 → 2798,7
sub [esp], ecx
pop ecx
jz .ret
.skip:
; next sector
inc ebp
cmp ebp, [SECTORS_PER_CLUSTER]
3751,8 → 2943,12
;
;--------------------------------------------------------------
fs_HdSetFileEnd:
cmp [fat_type], 0
jnz @f
cmp [fs_type], 1
jz ntfs_HdSetFileEnd
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
push ERROR_UNKNOWN_FS
.ret:
pop eax
3979,8 → 3175,12
ret
 
fs_HdGetFileInfo:
cmp [fat_type], 0
jnz @f
cmp [fs_type], 1
jz ntfs_HdGetFileInfo
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
mov eax, ERROR_UNKNOWN_FS
ret
@@:
4003,8 → 3203,12
jmp fs_GetFileInfo_finish
 
fs_HdSetFileInfo:
cmp [fat_type], 0
jnz @f
cmp [fs_type], 1
jz ntfs_HdSetFileInfo
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
mov eax, ERROR_UNKNOWN_FS
ret
@@:
4039,6 → 3243,8
xor eax, eax
ret
 
if 0 ; starting from revision 237 execute is implemented in taskman.inc
; through fs_XxxGetFileInfo and fs_XxxRead
;----------------------------------------------------------------
;
; fs_HdExecute - LFN variant for executing from harddisk
4076,7 → 3282,7
.flags:
cmp [fat_type], 0
jnz @f
mov eax, ERROR_UNKNOWN_FS
mov eax, -ERROR_UNKNOWN_FS
ret
@@:
cmp byte [esi], 0
4158,5 → 3364,160
popad
mov eax, 11
ret
end if
 
;----------------------------------------------------------------
;
; fs_HdDelete - delete file or empty folder from hard disk
;
; esi points to filename
;
; ret eax = 0 ok or other = errormsg
;
;--------------------------------------------------------------
fs_HdDelete:
cmp [fs_type], 1
jz ntfs_HdDelete
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
push ERROR_UNKNOWN_FS
.pop_ret:
pop eax
ret
@@:
cmp byte [esi], 0
jnz @f
; cannot delete root!
.access_denied:
push ERROR_ACCESS_DENIED
jmp .pop_ret
@@:
and [longname_sec1], 0
and [longname_sec2], 0
push edi
call hd_find_lfn
jnc .found
pop edi
push ERROR_FILE_NOT_FOUND
jmp .pop_ret
.found:
cmp dword [edi], '. '
jz .access_denied2
cmp dword [edi], '.. '
jz .access_denied2
test byte [edi+11], 10h
jz .dodel
; we can delete only empty folders!
pushad
mov ebp, [edi+20-2]
mov bp, [edi+26]
xor ecx, ecx
lea eax, [ebp-2]
imul eax, [SECTORS_PER_CLUSTER]
add eax, [DATA_START]
mov ebx, buffer
call hd_read
cmp [hd_error], 0
jnz .err1
add ebx, 2*0x20
.checkempty:
cmp byte [ebx], 0
jz .empty
cmp byte [ebx], 0xE5
jnz .notempty
add ebx, 0x20
cmp ebx, buffer+0x200
jb .checkempty
inc ecx
cmp ecx, [SECTORS_PER_CLUSTER]
jb @f
mov eax, ebp
call get_FAT
cmp [hd_error], 0
jnz .err1
mov ebp, eax
xor ecx, ecx
@@:
lea eax, [ebp-2]
imul eax, [SECTORS_PER_CLUSTER]
add eax, [DATA_START]
add eax, ecx
mov ebx, buffer
call hd_read
cmp [hd_error], 0
jz .checkempty
.err1:
popad
.err2:
pop edi
push 11
pop eax
ret
.notempty:
popad
.access_denied2:
pop edi
push ERROR_ACCESS_DENIED
pop eax
ret
.empty:
popad
push ebx
mov ebx, buffer
call hd_read
pop ebx
cmp [hd_error], 0
jnz .err2
.dodel:
push eax
mov eax, [edi+20-2]
mov ax, [edi+26]
xchg eax, [esp]
; delete folder entry
mov byte [edi], 0xE5
; delete LFN (if present)
.lfndel:
cmp edi, buffer
ja @f
cmp [longname_sec2], 0
jz .lfndone
push [longname_sec2]
push [longname_sec1]
pop [longname_sec2]
and [longname_sec1], 0
push ebx
mov ebx, buffer
call hd_write
mov eax, [esp+4]
call hd_read
pop ebx
pop eax
mov edi, buffer+0x200
@@:
sub edi, 0x20
cmp byte [edi], 0xE5
jz .lfndone
cmp byte [edi+11], 0xF
jnz .lfndone
mov byte [edi], 0xE5
jmp .lfndel
.lfndone:
push ebx
mov ebx, buffer
call hd_write
pop ebx
; delete FAT chain
pop eax
call clear_cluster_chain
call update_disk
pop edi
xor eax, eax
cmp [hd_error], 0
jz @f
mov al, 11
@@:
ret
 
; \end{diamond}
/kernel/branches/gfx_kernel/fs/fs.inc
4,7 → 4,6
;; (C) 2004 Ville Turjanmaa, License: GPL ;;
;; 29.04.2006 Elimination of hangup after the ;;
;; expiration hd_wait_timeout (for LBA) - Mario79 ;;
;; xx.04.2006 LFN support - diamond ;;
;; 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 ;;
37,12 → 36,8
;
; eax = 0 ; read file /RamDisk/First 6
; eax = 1 ; write file /RamDisk/First 33 /HardDisk/First 56
; eax = 2 ; delete file /RamDisk/First 32
; eax = 4 ; makedir
; eax = 5 ; rename file/directory
; eax = 8 ; lba read
; eax = 15 ; get_disk_info
; eax = 16 ; start application
;
; OUT:
;
89,16 → 84,8
 
cmp dword [eax+0],15 ; GET_DISK_INFO
je fs_info
cmp dword [eax+0],16 ; RUN - dont care about read&write blocks
je fs_read
cmp dword [eax+0],5 ; RENAME - dont care about read&write blocks
je fs_read
cmp dword [eax+0],4 ; MAKEDIR - dont care about read&write blocks
je fs_read
cmp dword [eax+0],2 ; DELETE - dont care about read&write blocks
je fs_read
 
cmp dword [0x3000],1 ; no memory checks for kernel requests
cmp dword [CURRENT_TASK],1 ; no memory checks for kernel requests
jz no_checks_for_kernel
mov edx,eax
cmp dword [eax+0],1
149,11 → 136,7
; (execute operation returns eax=-10)
cmp dword [eax], 0
jz .read_root
mov ecx, 10
cmp dword [eax], 16
jnz @f
neg ecx
@@: mov [esp+36], ecx
mov dword [esp+36], 10
ret
.read_root:
; \end{diamond}[18.03.2006]
290,34 → 273,6
jmp file_system_return
 
fs_noramdisk_write:
 
cmp dword [esp+20],16 ; START APPLICATION
jne fs_noramdisk_start_application
 
mov eax,[esp+4] ; fname
add eax,2*12+1
 
xor ebx,ebx ; parameters to pass
cmp dword [esp+12],ebx;0
je no_fl_start_param
mov ebx, [esp+12]
add ebx, std_application_base_address
no_fl_start_param:
mov edx,[esp+16] ; flags
 
call start_application_fl
 
jmp file_system_startapp_return
 
fs_noramdisk_start_application: ;there's new code - Mihasik
cmp dword [esp+20],2 ;DELETE
jne fs_noramdisk_delete
mov eax,[esp+4] ; fname
add eax,2*12+1
call filedelete
jmp file_system_return
 
fs_noramdisk_delete:
fs_noramdisk:
;********************************************************************
385,40 → 340,6
 
fs_noflpdisk_write:
 
cmp dword [esp+20],2 ; DELETE
jne fs_noflpdisk_delete
 
mov eax,[esp+4] ; fname
add eax,2*12+1
call floppy_filedelete
mov [flp_status],0
jmp file_system_return
 
fs_noflpdisk_delete:
cmp dword [esp+20],16 ; START APPLICATION
jne fs_noflpdisk_start_application
 
mov eax,[esp+4] ; fname
add eax,2*12+1
 
xor ebx,ebx ; parameters to pass
cmp dword [esp+12],ebx;0
je no_flp_start_param
mov ebx,[0x3010]
mov ebx,[ebx+0x10]
add ebx,[esp+12]
 
no_flp_start_param:
mov edx,[esp+16] ; flags
 
call start_application_floppy
 
file_system_startapp_return:
mov ebx, [esp+24+24] ; do not modify ebx in application
jmp file_system_return
 
fs_noflpdisk_start_application:
 
fs_noflpdisk:
;*****************************************************************
456,6 → 377,7
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
511,15 → 433,13
 
fs_yesharddisk_all:
mov eax,1
cmp dword [esp+20], 16
jnz @f
neg eax
@@: mov ebx, [esp+24+24]
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
@@:
544,6 → 464,8
mov edi,[esp+0]
mov byte [edi],'/'
 
call free_hd_channel
and [hd1_status], 0
jmp file_system_return
 
fs_noharddisk_read:
568,130 → 490,22
 
; eax=0 ok - eax=1 not enough free space
 
call free_hd_channel
and [hd1_status], 0
jmp file_system_return
 
 
fs_noharddisk_write:
 
cmp dword [esp+20],2 ; DELETE
jne fs_noharddisk_delete
 
mov eax,[esp+0] ; /dirname or /filename
mov byte [eax],0 ; path to asciiz
inc eax ; filename start
mov edx,[esp+4]
add edx,12*2 ; path start
call free_hd_channel
and [hd1_status], 0
 
call removedir
 
mov edi,[esp+0]
mov byte [edi],'/'
 
jmp file_system_return
 
fs_noharddisk_delete:
 
cmp dword [esp+20],4 ; MAKEDIR
jne fs_noharddisk_makedir
 
mov eax,[esp+0] ; /dirname
mov byte [eax],0 ; path to asciiz
inc eax ; filename start
mov edx,[esp+4]
add edx,12*2 ; path start
 
call makedir
 
mov edi,[esp+0]
mov byte [edi],'/'
 
jmp file_system_return
 
fs_noharddisk_makedir:
 
cmp dword [esp+20],5 ; RENAME
jne fs_noharddisk_rename
 
mov edi,[esp+0] ; start of source file name
add edi,12+1 ; continue after name
call expand_pathz ; convert destination name
 
mov eax,[edi+1]
cmp eax,'HD '
je fs_rename_test1
cmp eax,'HARD'
jne fs_rename_error
 
fs_rename_test1:
mov eax,[edi+1+12]
cmp eax,'1 '
je fs_rename_start
cmp eax,'FIRS'
jne fs_rename_error
 
fs_rename_start:
mov byte [ebx],0 ; path to asciiz
inc ebx ; filename start
add edi,12*2 ; path start
cmp byte [ebx],0
je fs_rename_error
cmp byte [ebx],32
je fs_rename_error
 
mov eax,[esp+0] ; /filename
mov byte [eax],0 ; path to asciiz
inc eax ; filename start
mov edx,[esp+4]
add edx,12*2 ; path start
 
call rename
 
mov edi,[esp+0]
mov byte [edi],'/'
 
jmp file_system_return
 
fs_rename_error:
mov eax,4 ; partition not defined at hd
jmp file_system_return
 
fs_noharddisk_rename:
 
cmp dword [esp+20],16 ; START APPLICATION
jne fs_noharddisk_start_application
 
mov eax,[esp+4] ; fname
add eax,12*2
 
mov ebx,[esp+0] ; length
sub ebx,eax
add ebx,12
 
mov ecx,[esp+4] ; work area
add ecx,512
 
xor ebp,ebp ; parameters to pass
cmp dword [esp+12],ebp;0
je no_hd_start_param
mov ebp, [esp+12]
add ebp, std_application_base_address
no_hd_start_param:
mov edx,[esp+16] ; flags
 
call start_application_hd
 
jmp file_system_startapp_return
 
fs_noharddisk_start_application:
 
fs_noharddisk:
; \begin{diamond}[18.03.2006]
mov eax, 5 ; file not found
; à ìîæåò áûòü, âîçâðàùàòü äðóãîé êîä îøèáêè?
cmp dword [esp+20], 16
jnz @f
neg eax
@@: mov ebx, [esp+24+24] ; do not change ebx in application
mov ebx, [esp+24+24] ; do not change ebx in application
; \end{diamond}[18.03.2006]
 
file_system_return:
713,11 → 527,7
jz .read
add esp, 20
pop ecx
mov eax, 10
cmp ecx, 16
jnz @f
neg eax
@@: mov [esp+36], eax
mov dword [esp+36], 10
ret
.read:
; \end{diamond}[18.03.2006]
769,7 → 579,7
mov esi,eax
 
shl esi,9
add esi,0x100000
add esi,RAMDISK
mov ecx,512/4
; cld
rep movsd
/kernel/branches/gfx_kernel/fs/fs_lfn.inc
82,9 → 82,8
; 5 : get file/directory attributes structure
; 6 : set file/directory attributes structure
; 7 : start application
; 8 : delete file - not implemented yet
; 9 : create directory - not implemented yet
; 10: rename file/directory - not implemented yet
; 8 : delete file
; 9 : create directory
 
add eax, std_application_base_address
; parse file name
99,6 → 98,18
mov ebp, esi
lodsb
@@:
cmp dword [ebx], 7
jne @F
mov edx, [ebx+4]
mov ebx, [ebx+8]
test ebx, ebx
jz .l1
add ebx, new_app_base
.l1:
call fs_execute ; ebp, ebx, edx
mov [esp+36], eax
ret
@@:
cmp al, '/'
jz @f
.notfound:
351,7 → 362,9
dd fs_RamdiskSetFileEnd
dd fs_RamdiskGetFileInfo
dd fs_RamdiskSetFileInfo
dd fs_RamdiskExecute
dd 0 ;fs_RamdiskExecute
dd fs_RamdiskDelete
dd fs_RamdiskCreateFolder
fs_NumRamdiskServices = ($ - fs_RamdiskServices)/4
 
fs_OnFloppy:
380,7 → 393,9
dd fs_FloppySetFileEnd
dd fs_FloppyGetFileInfo
dd fs_FloppySetFileInfo
dd fs_FloppyExecute
dd 0 ;fs_FloppyExecute
dd fs_FloppyDelete
dd fs_FloppyCreateFolder
fs_NumFloppyServices = ($ - fs_FloppyServices)/4
 
fs_OnHd0:
451,7 → 466,9
dd fs_HdSetFileEnd
dd fs_HdGetFileInfo
dd fs_HdSetFileInfo
dd fs_HdExecute
dd 0 ;fs_HdExecute
dd fs_HdDelete
dd fs_HdCreateFolder
fs_NumHdServices = ($ - fs_HdServices)/4
 
;*******************************************************
535,30 → 552,30
ret
 
fs_HasFloppy:
cmp byte [0x40000], 0
cmp byte [DRIVE_DATA], 0
setnz al
ret
 
fs_HasHd0:
mov al, [0x40001]
mov al, [DRIVE_DATA+1]
and al, 11000000b
cmp al, 01000000b
setz al
ret
fs_HasHd1:
mov al, [0x40001]
mov al, [DRIVE_DATA+1]
and al, 00110000b
cmp al, 00010000b
setz al
ret
fs_HasHd2:
mov al, [0x40001]
mov al, [DRIVE_DATA+1]
and al, 00001100b
cmp al, 00000100b
setz al
ret
fs_HasHd3:
mov al, [0x40001]
mov al, [DRIVE_DATA+1]
and al, 00000011b
cmp al, 00000001b
setz al
566,25 → 583,25
 
;*******************************************************
fs_HasCd0:
mov al, [0x40001]
mov al, [DRIVE_DATA+1]
and al, 11000000b
cmp al, 10000000b
setz al
ret
fs_HasCd1:
mov al, [0x40001]
mov al, [DRIVE_DATA+1]
and al, 00110000b
cmp al, 00100000b
setz al
ret
fs_HasCd2:
mov al, [0x40001]
mov al, [DRIVE_DATA+1]
and al, 00001100b
cmp al, 00001000b
setz al
ret
fs_HasCd3:
mov al, [0x40001]
mov al, [DRIVE_DATA+1]
and al, 00000011b
cmp al, 00000010b
setz al
607,8 → 624,8
ret
 
fs_NextFloppy:
; we have /fd/1 iff (([0x40000] and 0xF0) != 0) and /fd/2 iff (([0x40000] and 0x0F) != 0)
test byte [0x40000], 0xF0
; we have /fd/1 iff (([DRIVE_DATA] and 0xF0) != 0) and /fd/2 iff (([DRIVE_DATA] and 0x0F) != 0)
test byte [DRIVE_DATA], 0xF0
jz .no1
test eax, eax
jnz .no1
615,7 → 632,7
inc eax
ret ; CF cleared
.no1:
test byte [0x40000], 0x0F
test byte [DRIVE_DATA], 0x0F
jz .no2
cmp al, 2
jae .no2
640,7 → 657,7
push 3
fs_NextHd:
pop ecx
movzx ecx, byte [0x40002+ecx]
movzx ecx, byte [DRIVE_DATA+2+ecx]
cmp eax, ecx
jae fs_NextFloppy.no2
inc eax
/kernel/branches/gfx_kernel/fs/iso9660.inc
23,9 → 23,9
reserve_ok2:
 
push eax
mov eax,[0x3000]
mov eax,[CURRENT_TASK]
shl eax,5
mov eax,[eax+0x3000+TASKDATA.pid]
mov eax,[eax+CURRENT_TASK+TASKDATA.pid]
mov [cd_status],eax
pop eax
sti
65,7 → 65,9
mov [IDE_Channel_2],0
ret
uglobal
cd_status dd 0
endg
 
;----------------------------------------------------------------
;
253,15 → 255,18
call .get_names_from_buffer
sub eax,2048
; äèðåêòîðèÿ çàêîí÷èëàñü?
cmp eax,0
ja .read_to_buffer
mov edi,[cd_counter_block]
mov [edx+8],edi
mov edi,[ebx]
sub [edx+4],edi
xor eax, eax
dec ecx
js @f
mov al, ERROR_END_OF_FILE
@@:
pop ecx edi
mov ebx, [edx+4]
mov eax,ERROR_SUCCESS
ret
.get_names_from_buffer:
372,7 → 377,7
cd_get_parameters_of_file_1:
; ïîëó÷àåì àòðèáóòû ôàéëà
xor eax,eax
; ôàéë íå àðõèâèðîâàëñÿ
; ôàéë íå àðõèâèðîâàëñ
inc al
shl eax,1
; ýòî êàòàëîã?
658,11 → 663,9
cmp byte [esi-1], 0
jz .done
mov eax,[cd_current_pointer_of_input]
add eax,2
mov eax,[eax]
mov [CDSectorAddress],eax ; íà÷àëî äèðåêòîðèè
add eax,8
mov eax,[eax] ; ðàçìåð äèðåêòîðèè
push dword [eax+2]
pop dword [CDSectorAddress] ; íà÷àëî äèðåêòîðèè
mov eax,[eax+2+8] ; ðàçìåð äèðåêòîðèè
jmp .mainloop
; óêàçàòåëü ôàéëà íàéäåí
.done:
/kernel/branches/gfx_kernel/fs/ntfs.inc
0,0 → 1,1790
ntfs_test_bootsec:
; in: ebx->buffer, edx=size of partition
; out: CF set <=> invalid
; 1. Name=='NTFS '
cmp dword [ebx+3], 'NTFS'
jnz .no
cmp dword [ebx+7], ' '
jnz .no
; 2. Number of bytes per sector is the same as for physical device
; (that is, 0x200 for hard disk)
cmp word [ebx+11], 0x200
jnz .no
; 3. Number of sectors per cluster must be power of 2
movzx eax, byte [ebx+13]
dec eax
js .no
test al, [ebx+13]
jnz .no
; 4. FAT parameters must be zero
cmp word [ebx+14], 0
jnz .no
cmp dword [ebx+16], 0
jnz .no
cmp byte [ebx+20], 0
jnz .no
cmp word [ebx+22], 0
jnz .no
cmp dword [ebx+32], 0
jnz .no
; 5. Number of sectors <= partition size
cmp dword [ebx+0x2C], 0
ja .no
cmp [ebx+0x28], edx
ja .no
; 6. $MFT and $MFTMirr clusters must be within partition
cmp dword [ebx+0x34], 0
ja .no
push edx
movzx eax, byte [ebx+13]
mul dword [ebx+0x30]
test edx, edx
pop edx
jnz .no
cmp eax, edx
ja .no
cmp dword [ebx+0x3C], 0
ja .no
push edx
movzx eax, byte [ebx+13]
mul dword [ebx+0x38]
test edx, edx
pop edx
jnz .no
cmp eax, edx
ja .no
; 7. Clusters per FRS must be either negative and in [-31,-9] or positive and power of 2
movsx eax, byte [ebx+0x40]
cmp al, -31
jl .no
cmp al, -9
jle @f
dec eax
js .no
test [ebx+0x40], al
jnz .no
@@:
; 8. Same for clusters per IndexAllocationBuffer
movsx eax, byte [ebx+0x44]
cmp al, -31
jl .no
cmp al, -9
jle @f
dec eax
js .no
test [ebx+0x44], al
jnz .no
@@:
; OK, this is correct NTFS bootsector
clc
ret
.no:
; No, this bootsector isn't NTFS
stc
ret
 
ntfs_setup: ; CODE XREF: part_set.inc
; By given bootsector, initialize some NTFS variables
call ntfs_test_bootsec
jc problem_fat_dec_count
movzx eax, byte [ebx+13]
mov [ntfs_data.sectors_per_cluster], eax
mov eax, [ebx+0x28]
add eax, [PARTITION_START]
dec eax
mov [PARTITION_END], eax
mov [fs_type], 1
mov eax, [ebx+0x30]
mov [ntfs_data.mft_cluster], eax
mov eax, [ebx+0x38]
mov [ntfs_data.mftmirr_cluster], eax
movsx eax, byte [ebx+0x40]
test eax, eax
js .1
mul [ntfs_data.sectors_per_cluster]
shl eax, 9
jmp .2
.1:
neg eax
mov ecx, eax
mov eax, 1
shl eax, cl
.2:
mov [ntfs_data.frs_size], eax
movsx eax, byte [ebx+0x44]
test eax, eax
js .3
mul [ntfs_data.sectors_per_cluster]
shl eax, 9
jmp .4
.3:
neg eax
mov ecx, eax
mov eax, 1
shl eax, cl
.4:
mov [ntfs_data.iab_size], eax
; allocate space for buffers
add eax, [ntfs_data.frs_size]
push eax
call kernel_alloc
test eax, eax
jz problem_fat_dec_count
mov [ntfs_data.frs_buffer], eax
add eax, [ntfs_data.frs_size]
mov [ntfs_data.iab_buffer], eax
; read $MFT disposition
mov eax, [ntfs_data.mft_cluster]
mul [ntfs_data.sectors_per_cluster]
call ntfs_read_frs_sector
cmp [hd_error], 0
jnz .usemirr
cmp dword [ebx], 'FILE'
jnz .usemirr
call ntfs_restore_usa_frs
jnc .mftok
.usemirr:
and [hd_error], 0
mov eax, [ntfs_data.mftmirr_cluster]
mul [ntfs_data.sectors_per_cluster]
call ntfs_read_frs_sector
cmp [hd_error], 0
jnz @f
cmp dword [ebx], 'FILE'
jnz @f
call ntfs_restore_usa_frs
jnc .mftok
@@:
; $MFT and $MFTMirr invalid!
.fail_free_frs:
push [ntfs_data.frs_buffer]
call kernel_free
jmp problem_fat_dec_count
.fail_free_mft:
push [ntfs_data.mft_retrieval]
call kernel_free
jmp .fail_free_frs
.mftok:
; read $MFT table retrieval information
; start with one page, increase if not enough (when MFT too fragmented)
push ebx
push 0x1000
call kernel_alloc
pop ebx
test eax, eax
jz .fail_free_frs
mov [ntfs_data.mft_retrieval], eax
and [ntfs_data.mft_retrieval_size], 0
mov [ntfs_data.mft_retrieval_alloc], 0x1000/8
; $MFT base record must contain unnamed non-resident $DATA attribute
movzx eax, word [ebx+14h]
add eax, ebx
.scandata:
cmp dword [eax], -1
jz .fail_free_mft
cmp dword [eax], 0x80
jnz @f
cmp byte [eax+9], 0
jz .founddata
@@:
add eax, [eax+4]
jmp .scandata
.founddata:
cmp byte [eax+8], 0
jz .fail_free_mft
; load first portion of $DATA attribute retrieval information
mov edx, [eax+0x18]
mov [ntfs_data.mft_retrieval_end], edx
mov esi, eax
movzx eax, word [eax+0x20]
add esi, eax
sub esp, 10h
.scanmcb:
call ntfs_decode_mcb_entry
jnc .scanmcbend
call .get_mft_retrieval_ptr
mov edx, [esp] ; block length
mov [eax], edx
mov edx, [esp+8] ; block addr (relative)
mov [eax+4], edx
inc [ntfs_data.mft_retrieval_size]
jmp .scanmcb
.scanmcbend:
add esp, 10h
; there may be other portions of $DATA attribute in auxiliary records;
; if they will be needed, they will be loaded later
 
mov [ntfs_data.cur_index_size], 0x1000/0x200
push 0x1000
call kernel_alloc
test eax, eax
jz .fail_free_mft
mov [ntfs_data.cur_index_buf], eax
 
popad
call free_hd_channel
and [hd1_status], 0
ret
 
.get_mft_retrieval_ptr:
pushad
mov eax, [ntfs_data.mft_retrieval_size]
cmp eax, [ntfs_data.mft_retrieval_alloc]
jnz .ok
add eax, 0x1000/8
mov [ntfs_data.mft_retrieval_alloc], eax
shl eax, 3
push eax
call kernel_alloc
test eax, eax
jnz @f
popad
add esp, 14h
jmp .fail_free_mft
@@:
mov esi, [ntfs_data.mft_retrieval]
mov edi, eax
mov ecx, [ntfs_data.mft_retrieval_size]
add ecx, ecx
rep movsd
push [ntfs_data.mft_retrieval]
mov [ntfs_data.mft_retrieval], eax
call kernel_free
mov eax, [ntfs_data.mft_retrieval_size]
.ok:
shl eax, 3
add eax, [ntfs_data.mft_retrieval]
mov [esp+28], eax
popad
ret
 
ntfs_read_frs_sector:
push eax ecx
add eax, [PARTITION_START]
mov ecx, [ntfs_data.frs_size]
shr ecx, 9
mov ebx, [ntfs_data.frs_buffer]
push ebx
@@:
call hd_read
cmp [hd_error], 0
jnz .fail
add ebx, 0x200
inc eax
loop @b
.fail:
pop ebx
pop ecx eax
ret
 
uglobal
align 4
ntfs_cur_attr dd ?
ntfs_cur_iRecord dd ?
ntfs_cur_offs dd ? ; in sectors
ntfs_cur_size dd ? ; in sectors
ntfs_cur_buf dd ?
ntfs_cur_read dd ? ; [output]
ntfs_bCanContinue db ?
rb 3
 
ntfs_attrlist_buf rb 0x400
ntfs_attrlist_mft_buf rb 0x400
ntfs_bitmap_buf rb 0x400
 
ntfs_attr_iRecord dd ?
ntfs_attr_iBaseRecord dd ?
ntfs_attr_offs dd ?
ntfs_attr_list dd ?
ntfs_attr_size dq ?
ntfs_cur_tail dd ?
endg
 
ntfs_read_attr:
; in: global variables
; out: [ntfs_cur_read]
pushad
and [ntfs_cur_read], 0
cmp [ntfs_cur_iRecord], 0
jnz .nomft
cmp [ntfs_cur_attr], 0x80
jnz .nomft
mov eax, [ntfs_data.mft_retrieval_end]
inc eax
mul [ntfs_data.sectors_per_cluster]
cmp eax, [ntfs_cur_offs]
jbe .nomft
; precalculated part of $Mft $DATA
mov esi, [ntfs_data.mft_retrieval]
mov eax, [ntfs_cur_offs]
xor edx, edx
div [ntfs_data.sectors_per_cluster]
; eax = VCN, edx = offset in sectors from beginning of cluster
xor ecx, ecx ; ecx will contain LCN
.mftscan:
add ecx, [esi+4]
sub eax, [esi]
jb @f
add esi, 8
push eax
mov eax, [ntfs_data.mft_retrieval_end]
shl eax, 3
add eax, [ntfs_data.mft_retrieval]
cmp eax, esi
pop eax
jnz .mftscan
jmp .nomft
@@:
push ecx
add ecx, eax
add ecx, [esi]
push eax
push edx
mov eax, [ntfs_data.sectors_per_cluster]
mul ecx
; eax = sector on partition
add eax, [PARTITION_START]
pop edx
add eax, edx
mov ebx, [ntfs_cur_buf]
pop ecx
neg ecx
imul ecx, [ntfs_data.sectors_per_cluster]
sub ecx, edx
cmp ecx, [ntfs_cur_size]
jb @f
mov ecx, [ntfs_cur_size]
@@:
; ecx = number of sequential sectors to read
call hd_read
cmp [hd_error], 0
jnz .errread
add [ntfs_cur_read], 0x200
dec [ntfs_cur_size]
inc [ntfs_cur_offs]
add ebx, 0x200
mov [ntfs_cur_buf], ebx
inc eax
loop @b
pop ecx
xor eax, eax
xor edx, edx
cmp [ntfs_cur_size], eax
jz @f
add esi, 8
push eax
mov eax, [ntfs_data.mft_retrieval_end]
shl eax, 3
add eax, [ntfs_data.mft_retrieval]
cmp eax, esi
pop eax
jz .nomft
jmp .mftscan
@@:
popad
ret
.errread:
pop ecx
.errret:
stc
popad
ret
.nomft:
; 1. Read file record.
; N.B. This will do recursive call of read_attr for $MFT::$Data.
mov eax, [ntfs_cur_iRecord]
mov [ntfs_attr_iRecord], eax
and [ntfs_attr_list], 0
or dword [ntfs_attr_size], -1
or dword [ntfs_attr_size+4], -1
or [ntfs_attr_iBaseRecord], -1
call ntfs_read_file_record
test eax, eax
jz .errret
; 2. Find required attribute.
mov eax, [ntfs_data.frs_buffer]
; a) For auxiliary records, read base record
; N.B. If base record is present,
; base iRecord may be 0 (for $Mft), but SequenceNumber is nonzero
cmp dword [eax+24h], 0
jz @f
mov eax, [eax+20h]
; test eax, eax
; jz @f
.beginfindattr:
mov [ntfs_attr_iRecord], eax
call ntfs_read_file_record
test eax, eax
jz .errret
@@:
; b) Scan for required attribute and for $ATTR_LIST
mov eax, [ntfs_data.frs_buffer]
movzx ecx, word [eax+14h]
add eax, ecx
mov ecx, [ntfs_cur_attr]
and [ntfs_attr_offs], 0
.scanattr:
cmp dword [eax], -1
jz .scandone
cmp dword [eax], ecx
jz .okattr
cmp [ntfs_attr_iBaseRecord], -1
jnz .scancont
cmp dword [eax], 0x20 ; $ATTR_LIST
jnz .scancont
mov [ntfs_attr_list], eax
jmp .scancont
.okattr:
; ignore named $DATA attributes (aka NTFS streams)
cmp ecx, 0x80
jnz @f
cmp byte [eax+9], 0
jnz .scancont
@@:
mov [ntfs_attr_offs], eax
.scancont:
add eax, [eax+4]
jmp .scanattr
.continue:
pushad
and [ntfs_cur_read], 0
.scandone:
; c) Check for required offset and length
mov ecx, [ntfs_attr_offs]
jecxz .noattr
push [ntfs_cur_size]
push [ntfs_cur_read]
call .doreadattr
pop edx
pop eax
jc @f
cmp [ntfs_bCanContinue], 0
jz @f
sub edx, [ntfs_cur_read]
neg edx
shr edx, 9
sub eax, edx
mov [ntfs_cur_size], eax
jnz .not_in_cur
@@:
popad
ret
.noattr:
.not_in_cur:
cmp [ntfs_cur_attr], 0x20
jz @f
mov ecx, [ntfs_attr_list]
test ecx, ecx
jnz .lookattr
.ret_is_attr:
cmp [ntfs_attr_offs], 1 ; CF set <=> ntfs_attr_offs == 0
popad
ret
.lookattr:
; required attribute or required offset was not found in base record;
; it may be present in auxiliary records;
; scan $ATTR_LIST
mov eax, [ntfs_attr_iBaseRecord]
cmp eax, -1
jz @f
call ntfs_read_file_record
test eax, eax
jz .errret
or [ntfs_attr_iBaseRecord], -1
@@:
push [ntfs_cur_offs]
push [ntfs_cur_size]
push [ntfs_cur_read]
push [ntfs_cur_buf]
push dword [ntfs_attr_size]
push dword [ntfs_attr_size+4]
or dword [ntfs_attr_size], -1
or dword [ntfs_attr_size+4], -1
and [ntfs_cur_offs], 0
mov [ntfs_cur_size], 2
and [ntfs_cur_read], 0
mov eax, ntfs_attrlist_buf
cmp [ntfs_cur_iRecord], 0
jnz @f
mov eax, ntfs_attrlist_mft_buf
@@:
mov [ntfs_cur_buf], eax
push eax
call .doreadattr
pop esi
mov edx, 1
pop dword [ntfs_attr_size+4]
pop dword [ntfs_attr_size]
mov ebp, [ntfs_cur_read]
pop [ntfs_cur_buf]
pop [ntfs_cur_read]
pop [ntfs_cur_size]
pop [ntfs_cur_offs]
jc .errret
or edi, -1
lea ebp, [ebp+esi-1Ah]
.scanliststart:
mov eax, [ntfs_cur_attr]
.scanlist:
cmp esi, ebp
jae .scanlistdone
cmp eax, [esi]
jz @f
.scanlistcont:
movzx ecx, word [esi+4]
add esi, ecx
jmp .scanlist
@@:
; ignore named $DATA attributes (aka NTFS streams)
cmp eax, 0x80
jnz @f
cmp byte [esi+6], 0
jnz .scanlistcont
@@:
push eax
mov eax, [esi+8]
test eax, eax
jnz .testf
mov eax, dword [ntfs_attr_size]
and eax, dword [ntfs_attr_size+4]
cmp eax, -1
jnz .testfz
; if attribute is in auxiliary records, its size is defined only in first
mov eax, [esi+10h]
call ntfs_read_file_record
test eax, eax
jnz @f
.errret_pop:
pop eax
jmp .errret
@@:
mov eax, [ntfs_data.frs_buffer]
movzx ecx, word [eax+14h]
add eax, ecx
mov ecx, [ntfs_cur_attr]
@@:
cmp dword [eax], -1
jz .errret_pop
cmp dword [eax], ecx
jz @f
.l1:
add eax, [eax+4]
jmp @b
@@:
cmp eax, 0x80
jnz @f
cmp byte [eax+9], 0
jnz .l1
@@:
cmp byte [eax+8], 0
jnz .sdnores
mov eax, [eax+10h]
mov dword [ntfs_attr_size], eax
and dword [ntfs_attr_size+4], 0
jmp .testfz
.sdnores:
mov ecx, [eax+30h]
mov dword [ntfs_attr_size], ecx
mov ecx, [eax+34h]
mov dword [ntfs_attr_size+4], ecx
.testfz:
xor eax, eax
.testf:
imul eax, [ntfs_data.sectors_per_cluster]
cmp eax, [ntfs_cur_offs]
pop eax
ja @f
mov edi, [esi+10h] ; keep previous iRecord
jmp .scanlistcont
@@:
.scanlistfound:
cmp edi, -1
jnz @f
popad
ret
@@:
mov eax, [ntfs_cur_iRecord]
mov [ntfs_attr_iBaseRecord], eax
mov eax, edi
jmp .beginfindattr
.sde:
popad
stc
ret
.scanlistdone:
sub ebp, ntfs_attrlist_buf-1Ah
cmp [ntfs_cur_iRecord], 0
jnz @f
sub ebp, ntfs_attrlist_mft_buf-ntfs_attrlist_buf
@@:
cmp ebp, 0x400
jnz .scanlistfound
inc edx
push esi edi
mov esi, ntfs_attrlist_buf+0x200
mov edi, ntfs_attrlist_buf
cmp [ntfs_cur_iRecord], 0
jnz @f
mov esi, ntfs_attrlist_mft_buf+0x200
mov edi, ntfs_attrlist_mft_buf
@@:
mov ecx, 0x200/4
rep movsd
mov eax, edi
pop edi esi
sub esi, 0x200
push [ntfs_cur_offs]
push [ntfs_cur_size]
push [ntfs_cur_read]
push [ntfs_cur_buf]
push dword [ntfs_attr_size]
push dword [ntfs_attr_size+4]
or dword [ntfs_attr_size], -1
or dword [ntfs_attr_size+4], -1
mov [ntfs_cur_offs], edx
mov [ntfs_cur_size], 1
and [ntfs_cur_read], 0
mov [ntfs_cur_buf], eax
mov ecx, [ntfs_attr_list]
push esi edx
call .doreadattr
pop edx esi
mov ebp, [ntfs_cur_read]
pop dword [ntfs_attr_size+4]
pop dword [ntfs_attr_size]
pop [ntfs_cur_buf]
pop [ntfs_cur_read]
pop [ntfs_cur_size]
pop [ntfs_cur_offs]
jc .errret
add ebp, ntfs_attrlist_buf+0x200-0x1A
cmp [ntfs_cur_iRecord], 0
jnz .scanliststart
add ebp, ntfs_attrlist_mft_buf-ntfs_attrlist_buf
jmp .scanliststart
 
.doreadattr:
mov [ntfs_bCanContinue], 0
cmp byte [ecx+8], 0
jnz .nonresident
mov eax, [ecx+10h] ; length
mov esi, eax
mov edx, [ntfs_cur_offs]
shr eax, 9
cmp eax, edx
jb .okret
shl edx, 9
sub esi, edx
movzx eax, word [ecx+14h]
add edx, eax
add edx, ecx ; edx -> data
mov eax, [ntfs_cur_size]
cmp eax, (0xFFFFFFFF shr 9)+1
jbe @f
mov eax, (0xFFFFFFFF shr 9)+1
@@:
shl eax, 9
cmp eax, esi
jbe @f
mov eax, esi
@@:
; eax = length, edx -> data
mov [ntfs_cur_read], eax
mov ecx, eax
mov eax, edx
mov ebx, [ntfs_cur_buf]
call memmove
and [ntfs_cur_size], 0 ; CF=0
ret
.nonresident:
; Not all auxiliary records contain correct FileSize info
mov eax, dword [ntfs_attr_size]
mov edx, dword [ntfs_attr_size+4]
push eax
and eax, edx
cmp eax, -1
pop eax
jnz @f
mov eax, [ecx+30h] ; FileSize
mov edx, [ecx+34h]
mov dword [ntfs_attr_size], eax
mov dword [ntfs_attr_size+4], edx
@@:
add eax, 0x1FF
adc edx, 0
shrd eax, edx, 9
sub eax, [ntfs_cur_offs]
ja @f
; return with nothing read
and [ntfs_cur_size], 0
.okret:
clc
ret
@@:
; reduce read length
and [ntfs_cur_tail], 0
cmp [ntfs_cur_size], eax
jb @f
mov [ntfs_cur_size], eax
mov eax, dword [ntfs_attr_size]
and eax, 0x1FF
mov [ntfs_cur_tail], eax
@@:
cmp [ntfs_cur_size], 0
jz .okret
mov eax, [ntfs_cur_offs]
xor edx, edx
div [ntfs_data.sectors_per_cluster]
sub eax, [ecx+10h] ; first_vbo
jb .okret
; eax = cluster, edx = starting sector
sub esp, 10h
movzx esi, word [ecx+20h] ; mcb_info_ofs
add esi, ecx
xor ebp, ebp
.readloop:
call ntfs_decode_mcb_entry
jnc .break
add ebp, [esp+8]
sub eax, [esp]
jae .readloop
push ecx
push eax
add eax, [esp+8]
add eax, ebp
imul eax, [ntfs_data.sectors_per_cluster]
add eax, edx
add eax, [PARTITION_START]
pop ecx
neg ecx
imul ecx, [ntfs_data.sectors_per_cluster]
sub ecx, edx
cmp ecx, [ntfs_cur_size]
jb @f
mov ecx, [ntfs_cur_size]
@@:
mov ebx, [ntfs_cur_buf]
@@:
call hd_read
cmp [hd_error], 0
jnz .errread2
add ebx, 0x200
mov [ntfs_cur_buf], ebx
inc eax
add [ntfs_cur_read], 0x200
dec [ntfs_cur_size]
inc [ntfs_cur_offs]
loop @b
pop ecx
xor eax, eax
xor edx, edx
cmp [ntfs_cur_size], 0
jnz .readloop
add esp, 10h
mov eax, [ntfs_cur_tail]
test eax, eax
jz .okret
sub eax, 0x200
add [ntfs_cur_read], eax
jmp .okret
.errread2:
pop ecx
add esp, 10h
jmp .errret
.break:
add esp, 10h ; CF=0
mov [ntfs_bCanContinue], 1
ret
 
ntfs_read_file_record:
; in: eax=iRecord
; out: [ntfs_data.frs_buffer] contains information
; eax=0 - failed, eax=1 - success
; Read attr $DATA of $Mft, starting from eax*[ntfs_data.frs_size]
push ecx edx
mov ecx, [ntfs_data.frs_size]
mul ecx
shrd eax, edx, 9
shr edx, 9
jnz .err
push [ntfs_attr_iRecord]
push [ntfs_attr_iBaseRecord]
push [ntfs_attr_offs]
push [ntfs_attr_list]
push dword [ntfs_attr_size+4]
push dword [ntfs_attr_size]
push [ntfs_cur_iRecord]
push [ntfs_cur_attr]
push [ntfs_cur_offs]
push [ntfs_cur_size]
push [ntfs_cur_buf]
push [ntfs_cur_read]
mov [ntfs_cur_attr], 0x80 ; $DATA
and [ntfs_cur_iRecord], 0 ; $Mft
mov [ntfs_cur_offs], eax
shr ecx, 9
mov [ntfs_cur_size], ecx
mov eax, [ntfs_data.frs_buffer]
mov [ntfs_cur_buf], eax
call ntfs_read_attr
mov eax, [ntfs_cur_read]
pop [ntfs_cur_read]
pop [ntfs_cur_buf]
pop [ntfs_cur_size]
pop [ntfs_cur_offs]
pop [ntfs_cur_attr]
pop [ntfs_cur_iRecord]
pop dword [ntfs_attr_size]
pop dword [ntfs_attr_size+4]
pop [ntfs_attr_list]
pop [ntfs_attr_offs]
pop [ntfs_attr_iBaseRecord]
pop [ntfs_attr_iRecord]
pop edx ecx
jc .errret
cmp eax, [ntfs_data.frs_size]
jnz .errret
mov eax, [ntfs_data.frs_buffer]
cmp dword [eax], 'FILE'
jnz .errret
push ebx
mov ebx, eax
call ntfs_restore_usa_frs
pop ebx
setnc al
movzx eax, al
.ret:
ret
.err:
pop edx ecx
.errret:
xor eax, eax
ret
 
ntfs_restore_usa_frs:
mov eax, [ntfs_data.frs_size]
ntfs_restore_usa:
pushad
shr eax, 9
mov ecx, eax
inc eax
cmp [ebx+6], ax
jnz .err
movzx eax, word [ebx+4]
lea esi, [eax+ebx]
lodsw
mov edx, eax
lea edi, [ebx+0x1FE]
@@:
cmp [edi], dx
jnz .err
lodsw
stosw
add edi, 0x1FE
loop @b
popad
clc
ret
.err:
popad
stc
ret
 
ntfs_decode_mcb_entry:
push eax ecx edi
lea edi, [esp+16]
xor eax, eax
lodsb
test al, al
jz .end
mov ecx, eax
and ecx, 0xF
cmp ecx, 8
ja .end
push ecx
rep movsb
pop ecx
sub ecx, 8
neg ecx
cmp byte [esi-1], 80h
jae .end
push eax
xor eax, eax
rep stosb
pop ecx
shr ecx, 4
cmp ecx, 8
ja .end
push ecx
rep movsb
pop ecx
sub ecx, 8
neg ecx
cmp byte [esi-1], 80h
cmc
sbb eax, eax
rep stosb
stc
.end:
pop edi ecx eax
ret
 
ntfs_find_lfn:
; in: esi->name
; out: CF=1 - file not found
; else CF=0, [ntfs_cur_iRecord] valid, eax->record in parent directory
mov [ntfs_cur_iRecord], 5 ; start parse from root cluster
.doit2:
mov [ntfs_cur_attr], 0x90 ; $INDEX_ROOT
and [ntfs_cur_offs], 0
mov eax, [ntfs_data.cur_index_size]
mov [ntfs_cur_size], eax
mov eax, [ntfs_data.cur_index_buf]
mov [ntfs_cur_buf], eax
call ntfs_read_attr
jnc @f
.ret:
ret
@@:
cmp [ntfs_cur_read], 0x20
jc .ret
pushad
mov esi, [ntfs_data.cur_index_buf]
mov eax, [esi+14h]
add eax, 10h
cmp [ntfs_cur_read], eax
jae .readok1
add eax, 1FFh
shr eax, 9
cmp eax, [ntfs_data.cur_index_size]
ja @f
.stc_ret:
popad
stc
ret
@@:
; reallocate
push eax
push [ntfs_data.cur_index_buf]
call kernel_free
pop eax
mov [ntfs_data.cur_index_size], eax
push eax
call kernel_alloc
test eax, eax
jnz @f
and [ntfs_data.cur_index_size], 0
and [ntfs_data.cur_index_buf], 0
jmp .stc_ret
@@:
mov [ntfs_data.cur_index_buf], eax
popad
jmp .doit2
.readok1:
mov ebp, [esi+8] ; subnode_size
shr ebp, 9
cmp ebp, [ntfs_data.cur_index_size]
jbe .ok2
push esi ebp
push ebp
call kernel_alloc
pop ebp esi
test eax, eax
jz .stc_ret
mov edi, eax
mov ecx, [ntfs_data.cur_index_size]
shl ecx, 9-2
rep movsd
mov esi, eax
mov [ntfs_data.cur_index_size], ebp
push esi ebp
push [ntfs_data.cur_index_buf]
call kernel_free
pop ebp esi
mov [ntfs_data.cur_index_buf], esi
.ok2:
add esi, 10h
mov edi, [esp+4]
; edi -> name, esi -> current index data, ebp = subnode size
.scanloop:
add esi, [esi]
.scanloopint:
test byte [esi+0Ch], 2
jnz .subnode
push esi
add esi, 0x52
movzx ecx, byte [esi-2]
push edi
@@:
lodsw
call uni2ansi_char
call char_toupper
push eax
mov al, [edi]
inc edi
call char_toupper
cmp al, [esp]
pop eax
loopz @b
jz .found
pop edi
pop esi
jb .subnode
.scanloopcont:
movzx eax, word [esi+8]
add esi, eax
jmp .scanloopint
.subnode:
test byte [esi+0Ch], 1
jz .notfound
movzx eax, word [esi+8]
mov eax, [esi+eax-8]
mul [ntfs_data.sectors_per_cluster]
mov [ntfs_cur_offs], eax
mov [ntfs_cur_attr], 0xA0 ; $INDEX_ALLOCATION
mov [ntfs_cur_size], ebp
mov eax, [ntfs_data.cur_index_buf]
mov esi, eax
mov [ntfs_cur_buf], eax
call ntfs_read_attr
mov eax, ebp
shl eax, 9
cmp [ntfs_cur_read], eax
jnz .notfound
cmp dword [esi], 'INDX'
jnz .notfound
mov ebx, esi
call ntfs_restore_usa
jc .notfound
add esi, 0x18
jmp .scanloop
.notfound:
popad
stc
ret
.found:
cmp byte [edi], 0
jz .done
cmp byte [edi], '/'
jz .next
pop edi
pop esi
jmp .scanloopcont
.done:
.next:
pop esi
pop esi
mov eax, [esi]
mov [ntfs_cur_iRecord], eax
mov [esp+1Ch], esi
mov [esp+4], edi
popad
inc esi
cmp byte [esi-1], 0
jnz .doit2
ret
 
;----------------------------------------------------------------
;
; ntfs_HdRead - read NTFS hard disk
;
; esi points to filename
; ebx pointer to 64-bit number = first wanted byte, 0+
; may be ebx=0 - start from first byte
; ecx number of bytes to read, 0+
; edx mem location to return data
;
; ret ebx = bytes read or 0xffffffff file not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
ntfs_HdRead:
cmp byte [esi], 0
jnz @f
or ebx, -1
push ERROR_ACCESS_DENIED
pop eax
ret
@@:
call ntfs_find_lfn
jnc .found
or ebx, -1
push ERROR_FILE_NOT_FOUND
pop eax
ret
.found:
mov [ntfs_cur_attr], 0x80 ; $DATA
and [ntfs_cur_offs], 0
and [ntfs_cur_size], 0
call ntfs_read_attr
jnc @f
or ebx, -1
push ERROR_ACCESS_DENIED
pop eax
ret
@@:
pushad
and dword [esp+10h], 0
xor eax, eax
test ebx, ebx
jz .zero1
cmp dword [ebx+4], 0x200
jb @f
.eof0:
popad
xor ebx, ebx
.eof:
push ERROR_END_OF_FILE
pop eax
ret
@@:
mov eax, [ebx]
test eax, 0x1FF
jz .alignedstart
push edx
mov edx, [ebx+4]
shrd eax, edx, 9
pop edx
mov [ntfs_cur_offs], eax
mov [ntfs_cur_size], 1
mov [ntfs_cur_buf], ntfs_bitmap_buf
call ntfs_read_attr.continue
mov eax, [ebx]
and eax, 0x1FF
lea esi, [ntfs_bitmap_buf+eax]
sub eax, [ntfs_cur_read]
jae .eof0
neg eax
push ecx
cmp ecx, eax
jb @f
mov ecx, eax
@@:
mov [esp+10h+4], ecx
mov edi, edx
rep movsb
mov edx, edi
pop ecx
sub ecx, [esp+10h]
jnz @f
.retok:
popad
xor eax, eax
ret
@@:
cmp [ntfs_cur_read], 0x200
jz .alignedstart
.eof_ebx:
popad
jmp .eof
.alignedstart:
mov eax, [ebx]
push edx
mov edx, [ebx+4]
add eax, 511
adc edx, 0
shrd eax, edx, 9
pop edx
.zero1:
mov [ntfs_cur_offs], eax
mov [ntfs_cur_buf], edx
mov eax, ecx
shr eax, 9
mov [ntfs_cur_size], eax
add eax, [ntfs_cur_offs]
push eax
call ntfs_read_attr.continue
pop [ntfs_cur_offs]
mov eax, [ntfs_cur_read]
add [esp+10h], eax
mov eax, ecx
and eax, not 0x1FF
cmp [ntfs_cur_read], eax
jnz .eof_ebx
and ecx, 0x1FF
jz .retok
add edx, [ntfs_cur_read]
mov [ntfs_cur_size], 1
mov [ntfs_cur_buf], ntfs_bitmap_buf
call ntfs_read_attr.continue
cmp [ntfs_cur_read], ecx
jb @f
mov [ntfs_cur_read], ecx
@@:
xchg ecx, [ntfs_cur_read]
push ecx
mov edi, edx
mov esi, ntfs_bitmap_buf
add [esp+10h+4], ecx
rep movsb
pop ecx
xor eax, eax
cmp ecx, [ntfs_cur_read]
jz @f
mov al, ERROR_END_OF_FILE
@@:
mov [esp+1Ch], eax
popad
ret
 
;----------------------------------------------------------------
;
; ntfs_HdReadFolder - read NTFS hard disk folder
;
; esi points to filename
; ebx pointer to structure 32-bit number = first wanted block, 0+
; & flags (bitfields)
; flags: bit 0: 0=ANSI names, 1=UNICODE names
; ecx number of blocks to read, 0+
; edx mem location to return data
;
; ret ebx = blocks read or 0xffffffff folder not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
ntfs_HdReadFolder:
mov eax, 5 ; root cluster
cmp byte [esi], 0
jz .doit
call ntfs_find_lfn
jnc .doit2
.notfound:
or ebx, -1
push ERROR_FILE_NOT_FOUND
.pop_ret:
pop eax
ret
.doit:
mov [ntfs_cur_iRecord], eax
.doit2:
mov [ntfs_cur_attr], 0x10 ; $STANDARD_INFORMATION
and [ntfs_cur_offs], 0
mov [ntfs_cur_size], 1
mov [ntfs_cur_buf], ntfs_bitmap_buf
call ntfs_read_attr
jc .notfound
mov [ntfs_cur_attr], 0x90 ; $INDEX_ROOT
and [ntfs_cur_offs], 0
mov eax, [ntfs_data.cur_index_size]
mov [ntfs_cur_size], eax
mov eax, [ntfs_data.cur_index_buf]
mov [ntfs_cur_buf], eax
call ntfs_read_attr
jnc .ok
cmp [hd_error], 0
jz .notfound
or ebx, -1
push 11
jmp .pop_ret
.ok:
cmp [ntfs_cur_read], 0x20
jae @f
or ebx, -1
.fserr:
push ERROR_FAT_TABLE
jmp .pop_ret
@@:
pushad
mov esi, [ntfs_data.cur_index_buf]
mov eax, [esi+14h]
add eax, 10h
cmp [ntfs_cur_read], eax
jae .readok1
add eax, 1FFh
shr eax, 9
cmp eax, [ntfs_data.cur_index_size]
ja @f
popad
jmp .fserr
@@:
; reallocate
push eax
push [ntfs_data.cur_index_buf]
call kernel_free
pop eax
mov [ntfs_data.cur_index_size], eax
push eax
call kernel_alloc
test eax, eax
jnz @f
and [ntfs_data.cur_index_size], 0
and [ntfs_data.cur_index_buf], 0
.nomem:
popad
or ebx, -1
push 12
pop eax
ret
@@:
mov [ntfs_data.cur_index_buf], eax
popad
jmp .doit2
.readok1:
mov ebp, [esi+8] ; subnode_size
shr ebp, 9
cmp ebp, [ntfs_data.cur_index_size]
jbe .ok2
push esi ebp
push ebp
call kernel_alloc
pop ebp esi
test eax, eax
jz .nomem
mov edi, eax
mov ecx, [ntfs_data.cur_index_size]
shl ecx, 9-2
rep movsd
mov esi, eax
mov [ntfs_data.cur_index_size], ebp
push esi ebp
push [ntfs_data.cur_index_buf]
call kernel_free
pop ebp esi
mov [ntfs_data.cur_index_buf], esi
.ok2:
add esi, 10h
mov ebx, [esp+10h]
mov edx, [esp+14h]
push dword [ebx+4] ; read ANSI/UNICODE name
mov ebx, [ebx]
; init header
mov edi, edx
mov ecx, 32/4
xor eax, eax
rep stosd
mov byte [edx], 1 ; version
mov ecx, [esp+4+18h]
push edx
mov edx, esp
; edi -> BDFE, esi -> current index data, ebp = subnode size, ebx = first wanted block,
; ecx = number of blocks to read
; edx -> parameters block: dd <output>, dd <flags>
cmp [ntfs_cur_iRecord], 5
jz .skip_specials
; dot and dotdot entries
push esi
xor esi, esi
call .add_special_entry
inc esi
call .add_special_entry
pop esi
.skip_specials:
; at first, dump index root
add esi, [esi]
.dump_root:
test byte [esi+0Ch], 2
jnz .dump_root_done
call .add_entry
movzx eax, word [esi+8]
add esi, eax
jmp .dump_root
.dump_root_done:
; now dump all subnodes
push ecx edi
mov edi, ntfs_bitmap_buf
mov [ntfs_cur_buf], edi
mov ecx, 0x400/4
xor eax, eax
rep stosd
mov [ntfs_cur_attr], 0xB0 ; $BITMAP
and [ntfs_cur_offs], 0
mov [ntfs_cur_size], 2
call ntfs_read_attr
pop edi ecx
push 0 ; save offset in $BITMAP attribute
and [ntfs_cur_offs], 0
.dumploop:
mov [ntfs_cur_attr], 0xA0
mov [ntfs_cur_size], ebp
mov eax, [ntfs_data.cur_index_buf]
mov esi, eax
mov [ntfs_cur_buf], eax
push [ntfs_cur_offs]
mov eax, [ntfs_cur_offs]
imul eax, ebp
mov [ntfs_cur_offs], eax
call ntfs_read_attr
pop [ntfs_cur_offs]
mov eax, ebp
shl eax, 9
cmp [ntfs_cur_read], eax
jnz .done
push eax
mov eax, [ntfs_cur_offs]
and eax, 0x400*8-1
bt dword [ntfs_bitmap_buf], eax
pop eax
jnc .dump_subnode_done
cmp dword [esi], 'INDX'
jnz .dump_subnode_done
push ebx
mov ebx, esi
call ntfs_restore_usa
pop ebx
jc .dump_subnode_done
add esi, 0x18
add esi, [esi]
.dump_subnode:
test byte [esi+0Ch], 2
jnz .dump_subnode_done
call .add_entry
movzx eax, word [esi+8]
add esi, eax
jmp .dump_subnode
.dump_subnode_done:
inc [ntfs_cur_offs]
test [ntfs_cur_offs], 0x400*8-1
jnz .dumploop
mov [ntfs_cur_attr], 0xB0
push ecx edi
mov edi, ntfs_bitmap_buf
mov [ntfs_cur_buf], edi
mov ecx, 0x400/4
xor eax, eax
rep stosd
pop edi ecx
pop eax
push [ntfs_cur_offs]
inc eax
mov [ntfs_cur_offs], eax
mov [ntfs_cur_size], 2
push eax
call ntfs_read_attr
pop eax
pop [ntfs_cur_offs]
push eax
jmp .dumploop
.done:
pop eax
pop edx
mov ebx, [edx+4]
pop edx
xor eax, eax
dec ecx
js @f
mov al, ERROR_END_OF_FILE
@@:
mov [esp+1Ch], eax
mov [esp+10h], ebx
popad
ret
 
.add_special_entry:
mov eax, [edx]
inc dword [eax+8] ; new file found
dec ebx
jns .ret
dec ecx
js .ret
inc dword [eax+4] ; new file block copied
mov eax, [edx+4]
mov [edi+4], eax
; mov eax, dword [ntfs_bitmap_buf+0x20]
; or al, 0x10
mov eax, 0x10
stosd
scasd
push edx
mov eax, dword [ntfs_bitmap_buf]
mov edx, dword [ntfs_bitmap_buf+4]
call ntfs_datetime_to_bdfe
mov eax, dword [ntfs_bitmap_buf+0x18]
mov edx, dword [ntfs_bitmap_buf+0x1C]
call ntfs_datetime_to_bdfe
mov eax, dword [ntfs_bitmap_buf+8]
mov edx, dword [ntfs_bitmap_buf+0xC]
call ntfs_datetime_to_bdfe
pop edx
xor eax, eax
stosd
stosd
mov al, '.'
push edi ecx
lea ecx, [esi+1]
test byte [edi-0x24], 1
jz @f
rep stosw
pop ecx
xor eax, eax
stosw
pop edi
add edi, 520
ret
@@:
rep stosb
pop ecx
xor eax, eax
stosb
pop edi
add edi, 264
.ret:
ret
 
.add_entry:
; do not return DOS 8.3 names
cmp byte [esi+0x51], 2
jz .ret
; do not return system files
; ... note that there will be no bad effects if system files also were reported ...
cmp dword [esi], 0x10
jb .ret
mov eax, [edx]
inc dword [eax+8] ; new file found
dec ebx
jns .ret
dec ecx
js .ret
inc dword [eax+4] ; new file block copied
mov eax, [edx+4] ; flags
call ntfs_direntry_to_bdfe
push ecx esi edi
movzx ecx, byte [esi+0x50]
add esi, 0x52
test byte [edi-0x24], 1
jz .ansi
shr ecx, 1
rep movsd
adc ecx, ecx
rep movsw
and word [edi], 0
pop edi
add edi, 520
pop esi ecx
ret
.ansi:
jecxz .skip
@@:
lodsw
call uni2ansi_char
stosb
loop @b
.skip:
xor al, al
stosb
pop edi
add edi, 264
pop esi ecx
ret
 
ntfs_direntry_to_bdfe:
mov [edi+4], eax ; ANSI/UNICODE name
mov eax, [esi+48h]
test eax, 0x10000000
jz @f
and eax, not 0x10000000
or al, 0x10
@@:
stosd
scasd
push edx
mov eax, [esi+0x18]
mov edx, [esi+0x1C]
call ntfs_datetime_to_bdfe
mov eax, [esi+0x30]
mov edx, [esi+0x34]
call ntfs_datetime_to_bdfe
mov eax, [esi+0x20]
mov edx, [esi+0x24]
call ntfs_datetime_to_bdfe
pop edx
mov eax, [esi+0x40]
stosd
mov eax, [esi+0x44]
stosd
ret
 
iglobal
_24 dd 24
_60 dd 60
_10000000 dd 10000000
days400year dd 365*400+100-4+1
days100year dd 365*100+25-1
days4year dd 365*4+1
days1year dd 365
months dd 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
months2 dd 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
_400 dd 400
_100 dd 100
endg
 
ntfs_datetime_to_bdfe:
; edx:eax = number of 100-nanosecond intervals since January 1, 1601, in UTC
push eax
mov eax, edx
xor edx, edx
div [_10000000]
xchg eax, [esp]
div [_10000000]
pop edx
; edx:eax = number of seconds since January 1, 1601
push eax
mov eax, edx
xor edx, edx
div [_60]
xchg eax, [esp]
div [_60]
mov [edi], dl
pop edx
; edx:eax = number of minutes
div [_60]
mov [edi+1], dl
; eax = number of hours (note that 2^64/(10^7*60*60) < 2^32)
xor edx, edx
div [_24]
mov [edi+2], dl
mov [edi+3], byte 0
; eax = number of days since January 1, 1601
xor edx, edx
div [days400year]
imul eax, 400
add eax, 1601
mov [edi+6], ax
mov eax, edx
xor edx, edx
div [days100year]
cmp al, 4
jnz @f
dec eax
add edx, [days100year]
@@:
imul eax, 100
add [edi+6], ax
mov eax, edx
xor edx, edx
div [days4year]
shl eax, 2
add [edi+6], ax
mov eax, edx
xor edx, edx
div [days1year]
cmp al, 4
jnz @f
dec eax
add edx, [days1year]
@@:
add [edi+6], ax
push esi edx
mov esi, months
movzx eax, word [edi+6]
test al, 3
jnz .noleap
xor edx, edx
push eax
div [_400]
pop eax
test edx, edx
jz .leap
xor edx, edx
div [_100]
test edx, edx
jz .noleap
.leap:
mov esi, months2
.noleap:
pop edx
xor eax, eax
inc eax
@@:
sub edx, [esi]
jb @f
add esi, 4
inc eax
jmp @b
@@:
add edx, [esi]
pop esi
inc edx
mov [edi+4], dl
mov [edi+5], al
add edi, 8
ret
 
;----------------------------------------------------------------
;
; ntfs_HdRewrite - write to NTFS hard disk
;
; esi points to filename
; ebx ignored (reserved)
; ecx number of bytes to write, 0+
; edx mem location to data
;
; ret ebx = number of written bytes
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
ntfs_HdRewrite:
xor ebx, ebx
mov eax, ERROR_UNSUPPORTED_FS
ret
 
;----------------------------------------------------------------
;
; ntfs_HdWrite - write to NTFS hard disk
;
; esi points to filename
; ebx pointer to 64-bit number = first wanted byte, 0+
; may be ebx=0 - start from first byte
; ecx number of bytes to write, 0+
; edx mem location to data
;
; ret ebx = bytes written (maybe 0)
; eax = 0 ok write or other = errormsg
;
;--------------------------------------------------------------
ntfs_HdWrite:
xor ebx, ebx
mov eax, ERROR_UNSUPPORTED_FS
ret
 
;----------------------------------------------------------------
;
; ntfs_HdSetFileEnd - set end of file on NTFS 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
;
;--------------------------------------------------------------
ntfs_HdSetFileEnd:
ntfs_HdSetFileInfo:
;----------------------------------------------------------------
;
; ntfs_HdDelete - delete file or empty folder from NTFS hard disk
;
; esi points to filename
;
; ret eax = 0 ok or other = errormsg
;
;--------------------------------------------------------------
ntfs_HdDelete:
mov eax, ERROR_UNSUPPORTED_FS
ret
 
ntfs_HdGetFileInfo:
cmp byte [esi], 0
jnz @f
push 2
pop eax
ret
@@:
call ntfs_find_lfn
jnc .doit
push ERROR_FILE_NOT_FOUND
pop eax
cmp [hd_error], 0
jz @f
mov al, 11
@@:
ret
.doit:
push esi edi
mov esi, eax
mov edi, edx
xor eax, eax
call ntfs_direntry_to_bdfe
pop edi esi
xor eax, eax
ret
/kernel/branches/gfx_kernel/fs/part_set.inc
5,7 → 5,9
;* to MBR - Mario79 *
;*************************************************************
 
uglobal
align 4
 
;******************************************************
; Please do not change this place - variables in text
; Mario79
13,6 → 15,12
;******************************************************
PARTITION_START dd 0x3f
PARTITION_END dd 0
fs_type db 0 ; 0=none, 1=NTFS, 16=FAT16, 32=FAT32
align 4
 
fs_dependent_data_start:
; FATxx data
 
SECTORS_PER_FAT dd 0x1f3a
NUMBER_OF_FATS dd 0x2
SECTORS_PER_CLUSTER dd 0x8
30,13 → 38,40
fatEND dd 0x0FFFFFF8
fatMASK dd 0x0FFFFFFF
 
fat_type db 0 ; 0=none, 16=fat16, 32=fat32
fs_dependent_data_end:
file_system_data_size = $ - PARTITION_START
if file_system_data_size > 96
ERROR: sizeof(file system data) too big!
end if
 
virtual at fs_dependent_data_start
; NTFS data
ntfs_data:
.sectors_per_cluster dd ?
.mft_cluster dd ?
.mftmirr_cluster dd ?
.frs_size dd ? ; FRS size in bytes
.iab_size dd ? ; IndexAllocationBuffer size in bytes
.frs_buffer dd ?
.iab_buffer dd ?
.mft_retrieval dd ?
.mft_retrieval_size dd ?
.mft_retrieval_alloc dd ?
.mft_retrieval_end dd ?
.cur_index_size dd ?
.cur_index_buf dd ?
if $ > fs_dependent_data_end
ERROR: increase sizeof(fs_dependent_data)!
end if
end virtual
 
;***************************************************************************
; End place
; Mario79
;***************************************************************************
endg
iglobal
 
iglobal
partition_types: ; list of fat16/32 partitions
db 0x04 ; DOS: fat16 <32M
db 0x06 ; DOS: fat16 >32M
55,6 → 90,7
db 0xce ; DRDOS/secured: fat16, LBA-mapped
db 0xd4 ; Old Multiuser DOS secured: fat16 <32M
db 0xd6 ; Old Multiuser DOS secured: fat16 >32M
db 0x07 ; NTFS
partition_types_end:
 
 
79,10 → 115,9
; - it will skip over removed partitions
 
set_FAT32_variables:
mov [0xfe10],dword 0 ; entries in hd cache
mov [problem_partition],0
call reserve_hd1
call clear_hd_cache
call reserve_hd_channel
 
cmp dword [hdpos],0
je problem_hd
122,6 → 157,14
 
mov edx,eax ; start sector
add edx,[ebx+0x1be+8] ; add relative start
push edx
add edx, [ebx+0x1be+12] ; add length
dec edx ; PARTITION_END is inclusive
mov [PARTITION_END], edx ; note that this can be changed
; when file system data will be available
mov dl, [ebx+0x1be+4]
mov [fs_type], dl ; save for FS recognizer (separate FAT vs NTFS)
pop edx
next_primary_partition:
push eax
134,8 → 177,15
cmp ecx,[fat32part] ; is it wanted partition?
jnz next_primary_partition_1 ; no
 
mov edx,eax ; start sector
add edx,[ebx+0x1be+8+16] ; add relative start
mov edx, eax
add edx, [ebx+0x1be+8+16]
push edx
add edx, [ebx+0x1be+12+16]
dec edx
mov [PARTITION_END], edx
mov dl, [ebx+0x1be+4+16]
mov [fs_type], dl
pop edx
 
next_primary_partition_1:
push eax
148,8 → 198,15
cmp ecx,[fat32part] ; is it wanted partition?
jnz next_primary_partition_2 ; no
 
mov edx,eax ; start sector
add edx,[ebx+0x1be+8+16+16] ; add relative start
mov edx, eax
add edx, [ebx+0x1be+8+16+16]
push edx
add edx, [ebx+0x1be+12+16+16]
dec edx
mov [PARTITION_END], edx
mov dl, [ebx+0x1be+4+16+16]
mov [fs_type], dl
pop edx
 
next_primary_partition_2:
push eax
162,8 → 219,15
cmp ecx,[fat32part] ; is it wanted partition?
jnz next_partition ; no
 
mov edx,eax ; start sector
add edx,[ebx+0x1be+8+16+16+16] ; add relative start
mov edx, eax
add edx, [ebx+0x1be+8+16+16+16]
push edx
add edx, [ebx+0x1be+12+16+16+16]
dec edx
mov [PARTITION_END], edx
mov dl, [ebx+0x1be+4+16+16+16]
mov [fs_type], dl
pop edx
 
next_partition:
push eax
241,7 → 305,8
popad
 
problem_hd:
mov [fat_type],0
mov [fs_type],0
call free_hd_channel
mov [hd1_status],0 ; free
mov [problem_partition],1
ret
249,15 → 314,41
hd_and_partition_ok:
mov eax,edx
mov [PARTITION_START],eax
mov edx, [PARTITION_END]
sub edx, eax
inc edx ; edx = length of partition
 
mov [hd_setup],1
; mov [hd_setup],1
mov ebx,buffer
call hd_read ; read boot sector of partition
cmp [hd_error],0
jne problem_fat_dec_count
jz boot_read_ok
cmp [fs_type], 7
jnz problem_fat_dec_count
; NTFS duplicates bootsector:
; NT4/2k/XP+ saves bootsector copy in the end of disk
; NT 3.51 saves bootsector copy in the middle of disk
and [hd_error], 0
mov eax, [PARTITION_END]
call hd_read
cmp [hd_error], 0
jnz @f
call ntfs_test_bootsec
jnc boot_read_ok
@@:
and [hd_error], 0
mov eax, edx
shr eax, 1
add eax, [PARTITION_START]
call hd_read
cmp [hd_error], 0
jnz problem_fat_dec_count ; ­¥ áã¤ì¡ ...
boot_read_ok:
; mov [hd_setup], 0
; if we are running on NTFS, check bootsector
cmp [fs_type], 7
jz ntfs_setup
 
mov [hd_setup],0
 
cmp word [ebx+0x1fe],0xaa55 ; is it valid boot sector?
jnz problem_fat_dec_count
 
332,7 → 423,8
mov [fatBAD],0x0FFFFFF7
mov [fatEND],0x0FFFFFF8
mov [fatMASK],0x0FFFFFFF
mov [fat_type],32 ; Fat32
mov [fs_type],32 ; Fat32
call free_hd_channel
mov [hd1_status],0 ; free
ret
 
346,6 → 438,7
mov [fatBAD],0x0000FFF7
mov [fatEND],0x0000FFF8
mov [fatMASK],0x0000FFFF
mov [fat_type],16 ; Fat16
mov [fs_type],16 ; Fat16
call free_hd_channel
mov [hd1_status],0 ; free
ret