/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 |